diff --git a/.github/DISCUSSION_TEMPLATE/translations.yml b/.github/DISCUSSION_TEMPLATE/translations.yml new file mode 100644 index 000000000..16e304d99 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/translations.yml @@ -0,0 +1,45 @@ +labels: [lang-all] +body: + - type: markdown + attributes: + value: | + Thanks for your interest in helping translate the FastAPI docs! 🌍 + + Please follow these instructions carefully to propose a new language translation. 🙏 + + This structured process helps ensure translations can be properly maintained long-term. + - type: checkboxes + id: checks + attributes: + label: Initial Checks + description: Please confirm and check all the following options. + options: + - label: I checked that this language is not already being translated in FastAPI docs. + required: true + - label: I searched existing discussions to ensure no one else proposed this language. + required: true + - label: I am a native speaker of the language I want to help translate. + required: true + - type: input + id: language + attributes: + label: Target Language + description: What language do you want to translate the FastAPI docs into? + placeholder: e.g. Latin + validations: + required: true + - type: textarea + id: additional_info + attributes: + label: Additional Information + description: Any other relevant information about your translation proposal + - type: markdown + attributes: + value: | + Translations are automatized with AI and then reviewed by native speakers. 🤖 🙋 + + This allows us to keep them consistent and up-to-date. + + If there are several native speakers commenting on this discussion and + committing to help review new translations, the FastAPI team will review it + and potentially make it an official translation. 😎 diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index e84e4e4ab..a5761361d 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -21,7 +21,7 @@ jobs: outputs: docs: ${{ steps.filter.outputs.docs }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # For pull requests it's not necessary to checkout the code but for the main branch it is - uses: dorny/paths-filter@v3 id: filter @@ -40,6 +40,7 @@ jobs: - mkdocs.no-insiders.yml - .github/workflows/build-docs.yml - .github/workflows/deploy-docs.yml + - scripts/mkdocs_hooks.py langs: needs: - changes @@ -47,9 +48,9 @@ jobs: outputs: langs: ${{ steps.show-langs.outputs.langs }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv @@ -89,9 +90,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml index 34b54b452..ee8bfafb4 100644 --- a/.github/workflows/contributors.yml +++ b/.github/workflows/contributors.yml @@ -24,9 +24,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 9ca69b208..2c432da8c 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -23,9 +23,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv @@ -44,11 +44,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COMMIT_SHA: ${{ github.event.workflow_run.head_sha }} RUN_ID: ${{ github.run_id }} + STATE: "pending" - name: Clean site run: | rm -rf ./site mkdir ./site - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v5 with: path: ./site/ pattern: docs-site-* @@ -67,6 +68,14 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }} + - name: Deploy Docs Status Error + if: failure() + run: python ./scripts/deploy_docs_status.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMMIT_SHA: ${{ github.event.workflow_run.head_sha }} + RUN_ID: ${{ github.run_id }} + STATE: "error" - name: Comment Deploy run: python ./scripts/deploy_docs_status.py env: @@ -74,4 +83,4 @@ jobs: DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }} COMMIT_SHA: ${{ github.event.workflow_run.head_sha }} RUN_ID: ${{ github.run_id }} - IS_DONE: "true" + STATE: "success" diff --git a/.github/workflows/detect-conflicts.yml b/.github/workflows/detect-conflicts.yml new file mode 100644 index 000000000..aba329db8 --- /dev/null +++ b/.github/workflows/detect-conflicts.yml @@ -0,0 +1,19 @@ +name: "Conflict detector" +on: + push: + pull_request_target: + types: [synchronize] + +jobs: + main: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Check if PRs have merge conflicts + uses: eps1lon/actions-label-merge-conflict@v3 + with: + dirtyLabel: "conflicts" + repoToken: "${{ secrets.GITHUB_TOKEN }}" + commentOnDirty: "This pull request has a merge conflict that needs to be resolved." diff --git a/.github/workflows/label-approved.yml b/.github/workflows/label-approved.yml index 908a9453d..76ac77298 100644 --- a/.github/workflows/label-approved.yml +++ b/.github/workflows/label-approved.yml @@ -20,9 +20,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index e8e58015a..7aeb448e6 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v5 + - uses: actions/labeler@v6 if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }} - run: echo "Done adding labels" # Run this after labeler applied labels diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml index b8b5c42ee..2fa832fab 100644 --- a/.github/workflows/latest-changes.yml +++ b/.github/workflows/latest-changes.yml @@ -24,7 +24,7 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: # To allow latest-changes to commit to the main branch token: ${{ secrets.FASTAPI_LATEST_CHANGES }} @@ -34,7 +34,7 @@ jobs: if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }} with: limit-access-to-actor: true - - uses: tiangolo/latest-changes@0.3.2 + - uses: tiangolo/latest-changes@0.4.0 with: token: ${{ secrets.GITHUB_TOKEN }} latest_changes_file: docs/en/docs/release-notes.md diff --git a/.github/workflows/notify-translations.yml b/.github/workflows/notify-translations.yml index 621d1253a..ef3990d31 100644 --- a/.github/workflows/notify-translations.yml +++ b/.github/workflows/notify-translations.yml @@ -28,9 +28,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml index c1df3455e..e6e56bf04 100644 --- a/.github/workflows/people.yml +++ b/.github/workflows/people.yml @@ -24,9 +24,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bf88d59b1..441eb4560 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,9 +20,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10" # Issue ref: https://github.com/actions/setup-python/issues/436 @@ -35,7 +35,7 @@ jobs: TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }} run: python -m build - name: Publish - uses: pypa/gh-action-pypi-publish@v1.12.4 + uses: pypa/gh-action-pypi-publish@v1.13.0 - name: Dump GitHub context env: GITHUB_CONTEXT: ${{ toJson(github) }} diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml index d8a5dfb30..cde0ca308 100644 --- a/.github/workflows/smokeshow.yml +++ b/.github/workflows/smokeshow.yml @@ -21,8 +21,8 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: '3.9' - name: Setup uv @@ -34,7 +34,7 @@ jobs: requirements**.txt pyproject.toml - run: uv pip install -r requirements-github-actions.txt - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v5 with: name: coverage-html path: htmlcov diff --git a/.github/workflows/sponsors.yml b/.github/workflows/sponsors.yml index 6da4d90e1..1e245346d 100644 --- a/.github/workflows/sponsors.yml +++ b/.github/workflows/sponsors.yml @@ -24,9 +24,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/test-redistribute.yml b/.github/workflows/test-redistribute.yml index 693f0c603..a44f0b681 100644 --- a/.github/workflows/test-redistribute.yml +++ b/.github/workflows/test-redistribute.yml @@ -22,9 +22,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10" - name: Install build dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c3940be01..b76afe01e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,9 +23,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv @@ -61,9 +61,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Setup uv @@ -107,8 +107,8 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: python-version: '3.8' - name: Setup uv @@ -122,7 +122,7 @@ jobs: - name: Install Dependencies run: uv pip install -r requirements-tests.txt - name: Get coverage files - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: pattern: coverage-* path: coverage diff --git a/.github/workflows/topic-repos.yml b/.github/workflows/topic-repos.yml index 433aeb00b..cb98698d3 100644 --- a/.github/workflows/topic-repos.yml +++ b/.github/workflows/topic-repos.yml @@ -19,9 +19,9 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Setup uv diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml new file mode 100644 index 000000000..fa4e8f463 --- /dev/null +++ b/.github/workflows/translate.yml @@ -0,0 +1,77 @@ +name: Translate + +on: + workflow_dispatch: + inputs: + debug_enabled: + description: Run with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate) + required: false + default: "false" + command: + description: Command to run + type: choice + options: + - translate-page + - translate-lang + - update-outdated + - add-missing + - update-and-add + - remove-all-removable + language: + description: Language to translate to as a letter code (e.g. "es" for Spanish) + type: string + required: false + default: "" + en_path: + description: File path in English to translate (e.g. docs/en/docs/index.md) + type: string + required: false + default: "" + +env: + UV_SYSTEM_PYTHON: 1 + +jobs: + job: + if: github.repository_owner == 'fastapi' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + - uses: actions/checkout@v5 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.11" + - name: Setup uv + uses: astral-sh/setup-uv@v6 + with: + version: "0.4.15" + enable-cache: true + cache-dependency-glob: | + requirements**.txt + pyproject.toml + - name: Install Dependencies + run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt + # Allow debugging with tmate + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }} + with: + limit-access-to-actor: true + env: + GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + - name: FastAPI Translate + run: | + python ./scripts/translate.py ${{ github.event.inputs.command }} + python ./scripts/translate.py make-pr + env: + GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + LANGUAGE: ${{ github.event.inputs.language }} + EN_PATH: ${{ github.event.inputs.en_path }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 680cafce9..8b24c8c0c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ default_language_version: python: python3.10 repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-added-large-files - id: check-toml @@ -14,7 +14,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.2 + rev: v0.13.1 hooks: - id: ruff args: diff --git a/README.md b/README.md index 25a1d9179..a8a0e37b5 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,6 @@ The key features are: - @@ -55,7 +54,8 @@ The key features are: - + + @@ -89,7 +89,7 @@ The key features are: "_I’m over the moon excited about **FastAPI**. It’s so fun!_" -
Brian Okken - Python Bytes podcast host (ref)
+
Brian Okken - Python Bytes podcast host (ref)
--- @@ -103,7 +103,7 @@ The key features are: "_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_" -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
+
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
--- diff --git a/SECURITY.md b/SECURITY.md index db412cf2c..87e87e0ca 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,7 +16,7 @@ You can learn more about [FastAPI versions and how to pin and upgrade them](http If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue. -I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you. +I (the author, [@tiangolo](https://x.com/tiangolo)) will review it thoroughly and get back to you. ## Public Discussions diff --git a/docs/az/docs/index.md b/docs/az/docs/index.md deleted file mode 100644 index fbbbce130..000000000 --- a/docs/az/docs/index.md +++ /dev/null @@ -1,467 +0,0 @@ -

- FastAPI -

-

- FastAPI framework, yÃŧksək məshuldarlÄą, Ãļyrənməsi asan, çevik kodlama, istifadəyə hazÄąrdÄąr -

-

- - Test - - - Əhatə - - - Paket versiyasÄą - - - Dəstəklənən Python versiyalarÄą - -

- ---- - -**Sənədlər**: https://fastapi.tiangolo.com - -**Qaynaq Kodu**: https://github.com/fastapi/fastapi - ---- - -FastAPI Python ilə API yaratmaq ÃŧçÃŧn standart Python tip məsləhətlərinə əsaslanan, mÃŧasir, sÃŧrətli (yÃŧksək performanslÄą) framework-dÃŧr. - -Əsas xÃŧsusiyyətləri bunlardÄąr: - -* **SÃŧrətli**: Çox yÃŧksək performans, **NodeJS** və **Go** səviyyəsində (Starlette və Pydantic-ə təşəkkÃŧrlər). [Ən sÃŧrətli Python frameworklərindən biridir](#performans). -* **Çevik kodlama**: FunksiyanallÄąqlarÄą inkişaf etdirmək sÃŧrətini təxminən 200%-dən 300%-ə qədər artÄąrÄąn. * -* **Daha az xəta**: İnsan (developer) tərəfindən tÃļrədilən səhvlərin təxminən 40% -ni azaldÄąn. * -* **İntuitiv**: Əla redaktor dəstəyi. Hər yerdə otomatik tamamlama. XətalarÄą mÃŧəyyənləşdirməyə daha az vaxt sərf edəcəksiniz. -* **Asan**: İstifadəsi və Ãļyrənilməsi asan olmasÄą ÃŧçÃŧn nəzərdə tutulmuşdur. Sənədləri oxumaq ÃŧçÃŧn daha az vaxt ayÄąracaqsÄąnÄąz. -* **QÄąsa**: Kod təkrarlanmasÄąnÄą minimuma endirin. Hər bir parametr tərifində birdən çox xÃŧsusiyyət ilə və daha az səhvlə qarÅŸÄąlaşacaqsÄąnÄąz. -* **GÃŧclÃŧ**: Avtomatik və interaktiv sənədlərlə birlikdə istifadəyə hazÄąr kod əldə edə bilərsiniz. -* **Standartlara əsaslanan**: API-lar ÃŧçÃŧn aÃ§Äąq standartlara əsaslanÄąr (və tam uyğun gəlir): OpenAPI (əvvəlki adÄą ilə Swagger) və JSON Schema. - -* Bu fikirlər daxili development komandasÄąnÄąn hazÄąrladÄąqlarÄą məhsullarÄąn sÄąnaqlarÄąna əsaslanÄąr. - -## Sponsorlar - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%}` -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -Digər sponsorlar - -## Rəylər - -"_[...] Son gÃŧnlərdə **FastAPI**-Äą çox istifadə edirəm. [...] Əslində onu komandamÄąn bÃŧtÃŧn **Microsoftda ML sevislərində** istifadə etməyi planlayÄąram. OnlarÄąn bəziləri **windows**-un əsas məhsuluna və bəzi **Office** məhsullarÄąna inteqrasiya olunurlar._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_**FastAPI** kitabxanasÄąnÄą **Proqnozlar** əldə etmək ÃŧçÃŧn sorğulana bilən **REST** serverini yaratmaqda istifadə etdik._" - -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** **bÃļhran idarəçiliyi** orkestrləşmə framework-nÃŧn aÃ§Äąq qaynaqlÄą buraxÄąlÄąÅŸÄąnÄą elan etməkdən məmnundur: **Dispatch**! [**FastAPI** ilə quruldu]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_**FastAPI** ÃŧçÃŧn həyəcanlÄąyam. Çox əyləncəlidir!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_DÃŧzÃŧnÃŧ desəm, sizin qurduğunuz şey həqiqətən mÃļhkəm və peşəkar gÃļrÃŧnÃŧr. Bir çox cəhətdən **Hug**-un olmasÄąnÄą istədiyim kimdir - kiminsə belə bir şey qurduğunu gÃļrmək həqiqətən ruhlandÄąrÄącÄądÄąr._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_Əgər REST API-lər yaratmaq ÃŧçÃŧn **mÃŧasir framework** Ãļyrənmək istəyirsinizsə, **FastAPI**-a baxÄąn [...] SÃŧrətli, istifadəsi və Ãļyrənməsi asandÄąr. [...]_" - -"_**API** xidmətlərimizi **FastAPI**-a kÃļçÃŧrdÃŧk [...] Sizin də bəyənəcəyinizi dÃŧşÃŧnÃŧrÃŧk._" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- - -"_Python ilə istifadəyə hazÄąr API qurmaq istəyən hər kəsə **FastAPI**-Äą tÃļvsiyə edirəm. **MÃļhtəşəm şəkildə dizayn edilmiş**, **istifadəsi asan** və **yÃŧksək dərəcədə genişlənə bilən**-dir, API əsaslÄą inkişaf strategiyamÄązÄąn **əsas komponentinə** çevrilib və Virtual TAC Engineer kimi bir çox avtomatlaşdÄąrma və servisləri idarə edir._" - -
Deon Pillsbury - Cisco (ref)
- ---- - -## **Typer**, CLI-larÄąn FastAPI-Äą - - - -Əgər siz veb API əvəzinə terminalda istifadə ediləcək CLI proqramÄą qurursunuzsa, **Typer**-a baxa bilərsiniz. - -**Typer** FastAPI-Äąn kiçik qardaÅŸÄądÄąr. Və o, CLI-lərin **FastAPI**-Äą olmaq ÃŧçÃŧn nəzərdə tutulub. âŒ¨ī¸ 🚀 - -## Tələblər - -FastAPI nəhənglərin çiyinlərində dayanÄąr: - -* Web tərəfi ÃŧçÃŧn Starlette. -* Data tərəfi ÃŧçÃŧn Pydantic. - -## QuraşdÄąrma - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -Tətbiqimizi əlçatan etmək ÃŧçÃŧn bizə Uvicorn və ya Hypercorn kimi ASGI server lazÄąmdÄąr. - -
- -```console -$ pip install "uvicorn[standard]" - ----> 100% -``` - -
- -## NÃŧmunə - -### Kodu yaradaq - -* `main.py` adlÄą fayl yaradaq və ona aşağıdakÄą kodu yerləşdirək: - -```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} -``` - -
-Və ya async def... - -Əgər kodunuzda `async` və ya `await` vardÄąrsa `async def` istifadə edə bilərik: - -```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} -``` - -**Qeyd**: - -Əgər bu mÃļvzu haqqÄąnda məlumatÄąnÄąz yoxdursa `async` və `await` sənədindəki _"Tələsirsən?"_ bÃļlməsinə baxa bilərsiniz. - -
- -### Kodu işə salaq - -Serveri aşağıdakÄą əmr ilə işə salaq: - -
- -```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. -``` - -
- -
-uvicorn main:app --reload əmri haqqÄąnda... - -`uvicorn main:app` əmri aşağıdakÄąlara instinad edir: - -* `main`: `main.py` faylÄą (yəni Python "modulu"). -* `app`: `main.py` faylÄąnda `app = FastAPI()` sətrində yaratdığımÄąz `FastAPI` obyektidir. -* `--reload`: kod dəyişikliyindən sonra avtomatik olaraq serveri yenidən işə salÄąr. Bu parametrdən yalnÄąz development mərhələsində istifadə etməliyik. - -
- -### İndi yoxlayaq - -Bu linki brauzerimizdə açaq http://127.0.0.1:8000/items/5?q=somequery. - -AşağıdakÄą kimi bir JSON cavabÄą gÃļrəcəksiniz: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -Siz artÄąq bir API yaratmÄąsÄąnÄąz, hansÄą ki: - -* `/` və `/items/{item_id}` _yollarÄąnda_ HTTP sorğularÄąnÄą qəbul edir. -* Hər iki _yolda_ `GET` əməliyyatlarÄąnÄą (həmçinin HTTP _metodlarÄą_ kimi bilinir) aparÄąr. -* `/items/{item_id}` _yolu_ `item_id` adlÄą `int` qiyməti almalÄą olan _yol parametrinə_ sahibdir. -* `/items/{item_id}` _yolunun_ `q` adlÄą yol parametri var və bu parametr istəyə bağlÄą olsa da, `str` qiymətini almalÄądÄąr. - -### İnteraktiv API Sənədləri - -İndi http://127.0.0.1:8000/docs ÃŧnvanÄąna daxil olun. - -Avtomatik interaktiv API sənədlərini gÃļrəcəksiniz (Swagger UI tərəfindən təmin edilir): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternativ API sənədləri - -İndi isə http://127.0.0.1:8000/redoc ÃŧnvanÄąna daxil olun. - -ReDoc tərəfindən təqdim edilən avtomatik sənədləri gÃļrəcəksiniz: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## NÃŧmunəni Yeniləyək - -İndi gəlin `main.py` faylÄąnÄą `PUT` sorğusu ilə birlikdə gÃļvdə qəbul edəcək şəkildə dəyişdirək. - -Pydantic sayəsində standart Python tiplərindən istifadə edərək gÃļvdəni mÃŧəyyən edək. - -```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} -``` -Server avtomatik olaraq yenidən işə salÄąnmalÄą idi (çÃŧnki biz yuxarÄąda `uvicorn` əmri ilə `--reload` parametrindən istifadə etmişik). - -### İnteraktiv API sənədlərindəki dəyişikliyə baxaq - -Yenidən http://127.0.0.1:8000/docs ÃŧnvanÄąna daxil olun. - -* İnteraktiv API sənədləri yeni gÃļvdə də daxil olmaq ilə avtomatik olaraq yenilənəcək: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* "Try it out" dÃŧyməsini klikləyin, bu, parametrləri doldurmağa və API ilə birbaşa əlaqə saxlamağa imkan verir: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Sonra "Execute" dÃŧyməsini klikləyin, istifadəçi interfeysi API ilə əlaqə quracaq, parametrləri gÃļndərəcək, nəticələri əldə edəcək və onlarÄą ekranda gÃļstərəcək: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Alternativ API Sənədlərindəki Dəyişikliyə Baxaq - -İndi isə yenidən http://127.0.0.1:8000/redoc ÃŧnvanÄąna daxil olun. - -* Alternativ sənədlər həm də yeni sorğu parametri və gÃļvdəsini əks etdirəcək: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### XÃŧlasə - -Ümumiləşdirsək, parametrlər, gÃļvdə və s. Biz məlumat nÃļvlərini **bir dəfə** funksiya parametrləri kimi təyin edirik. - -Bunu standart mÃŧasir Python tipləri ilə edirsiniz. - -Yeni sintaksis, mÃŧəyyən bir kitabxananÄąn metodlarÄąnÄą və ya siniflərini və s. Ãļyrənmək məcburiyyətində deyilsiniz. - -Sadəcə standart **Python**. - -Məsələn, `int` ÃŧçÃŧn: - -```Python -item_id: int -``` - -və ya daha mÃŧrəkkəb `Item` modeli ÃŧçÃŧn: - -```Python -item: Item -``` - -...və yalnÄąz parametr tipini təyin etməklə bunlarÄą əldə edirsiniz: - -* Redaktor dəstəyi ilə: - * Avtomatik tamamlama. - * Tip yoxlanmasÄą. -* MəlumatlarÄąn Təsdiqlənməsi: - * Məlumat etibarsÄąz olduqda avtomatik olaraq aydÄąn xətalar gÃļstərir. - * Hətta çox dərin JSON obyektlərində belə doğrulama aparÄąr. -* Daxil olan məlumatlarÄą çevirmək ÃŧçÃŧn aşağıdakÄą məlumat nÃļvlərindən istifadə edilir: - * JSON. - * Yol parametrləri. - * Sorğu parametrləri. - * Çərəzlər. - * BaşlÄąqlaq. - * Formalar. - * Fayllar. -* Daxil olan məlumatlarÄą çevirmək ÃŧçÃŧn aşağıdakÄą məlumat nÃļvlərindən istifadə edilir (JSON olaraq): - * Python tiplərinin (`str`, `int`, `float`, `bool`, `list`, və s) çevrilməsi. - * `datetime` obyektləri. - * `UUID` obyektləri. - * Verilənlər bazasÄą modelləri. - * və daha çoxu... -* 2 alternativ istifadəçi interfeysi daxil olmaqla avtomatik interaktiv API sənədlərini təmin edir: - * Swagger UI. - * ReDoc. - ---- - -Gəlin əvvəlki nÃŧmunəyə qayÄądaq və **FastAPI**-nin nələr edəcəyinə nəzər salaq: - -* `GET` və `PUT` sorğularÄą ÃŧçÃŧn `item_id`-nin yolda olub-olmadığınÄą yoxlayacaq. -* `item_id`-nin `GET` və `PUT` sorğularÄą ÃŧçÃŧn nÃļvÃŧnÃŧn `int` olduğunu yoxlayacaq. - * Əgər `int` deyilsə, səbəbini gÃļstərən bir xəta mesajÄą gÃļstərəcəkdir. -* məcburi olmayan `q` parametrinin `GET` (`http://127.0.0.1:8000/items/foo?q=somequery` burdakÄą kimi) sorğusu içərisində olub olmadığınÄą yoxlayacaq. - * `q` parametrini `= None` ilə yaratdığımÄąz ÃŧçÃŧn, məcburi olmayan parametr olacaq. - * Əgər `None` olmasaydÄą, bu məcburi parametr olardÄą (`PUT` metodunun gÃļvdəsində olduğu kimi). -* `PUT` sorğusu ÃŧçÃŧn, `/items/{item_id}` gÃļvdəsini JSON olaraq oxuyacaq: - * `name` adÄąnda məcburi bir parametr olub olmadığınÄą və əgər varsa, tipinin `str` olub olmadığınÄą yoxlayacaq. - * `price` adÄąnda məcburi bir parametr olub olmadığınÄą və əgər varsa, tipinin `float` olub olmadığınÄą yoxlayacaq. - * `is_offer` adÄąnda məcburi olmayan bir parametr olub olmadığınÄą və əgər varsa, tipinin `float` olub olmadığınÄą yoxlayacaq. - * BÃŧtÃŧn bunlar ən dərin JSON obyektlərində belə işləyəcək. -* MəlumatlarÄąn JSON-a və JSON-un Python obyektinə çevrilməsi avtomatik həyata keçiriləcək. -* Hər şeyi OpenAPI ilə uyğun olacaq şəkildə avtomatik olaraq sənədləşdirəcək və onlarÄą aşağıdakÄą kimi istifadə edə biləcək: - * İnteraktiv sənədləşmə sistemləri. - * Bir çox proqramlaşdÄąrma dilləri ÃŧçÃŧn avtomatlaşdÄąrÄąlmÄąÅŸ mÃŧştəri kodu yaratma sistemləri. -* 2 interaktiv sənədləşmə veb interfeysini birbaşa təmin edəcək. - ---- - -Yeni başlamÄąÅŸÄąq, amma siz artÄąq işin məntiqini başa dÃŧşmÃŧsÃŧnÃŧz. - -İndi aşağıdakÄą sətri dəyişdirməyə çalÄąÅŸÄąn: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...bundan: - -```Python - ... "item_name": item.name ... -``` - -...buna: - -```Python - ... "item_price": item.price ... -``` - -...və redaktorun məlumat tiplərini bildiyini və avtomatik tamaladığınÄą gÃļrəcəksiniz: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -Daha çox funksiyaya malik daha dolğun nÃŧmunə ÃŧçÃŧn Öyrədici - İstifadəçi TəlimatÄą səhifəsinə baxa bilərsiniz. - -**Spoiler xəbərdarlığı**: Öyrədici - istifadəçi təlimatÄąna bunlar daxildir: - -* **Parametrlərin**, **başlÄąqlar**, çərəzlər, **forma sahələri** və **fayllar** olaraq mÃŧəyyən edilməsi. -* `maximum_length` və ya `regex` kimi **doğrulama məhdudiyyətlərinin** necə təyin ediləcəyi. -* Çox gÃŧclÃŧ və istifadəsi asan **Dependency Injection** sistemi. -* TəhlÃŧkəsizlik və autentifikasiya, **JWT tokenləri** ilə **OAuth2** dəstəyi və **HTTP Basic** autentifikasiyasÄą. -* **çox dərin JSON modellərini** mÃŧəyyən etmək ÃŧçÃŧn daha irəli səviyyə (lakin eyni dərəcədə asan) Ãŧsullar (Pydantic sayəsində). -* Strawberry və digər kitabxanalar ilə **GraphQL** inteqrasiyasÄą. -* Digər əlavə xÃŧsusiyyətlər (Starlette sayəsində): - * **WebSockets** - * HTTPX və `pytest` sayəsində çox asan testlər - * **CORS** - * **Cookie Sessions** - * ...və daha çoxu. - -## Performans - -MÃŧstəqil TechEmpower meyarlarÄą gÃļstərir ki, Uvicorn Ãŧzərində işləyən **FastAPI** proqramlarÄą ən sÃŧrətli Python kitabxanalarÄąndan biridir, yalnÄąz Starlette və Uvicorn-un ÃļzÃŧndən yavaşdÄąr, ki FastAPI bunlarÄąn Ãŧzərinə qurulmuş bir framework-dÃŧr. (*) - -ƏtraflÄą məlumat ÃŧçÃŧn bu bÃļlməyə nəzər salÄąn MÃŧqayisələr. - -## Məcburi Olmayan Tələblər - -Pydantic tərəfindən istifadə olunanlar: - -* email-validator - e-poçtun yoxlanÄąlmasÄą ÃŧçÃŧn. -* pydantic-settings - parametrlərin idarə edilməsi ÃŧçÃŧn. -* pydantic-extra-types - Pydantic ilə istifadə edilə bilən əlavə tiplər ÃŧçÃŧn. - -Starlette tərəfindən istifadə olunanlar: - -* httpx - Əgər `TestClient` strukturundan istifadə edəcəksinizsə, tələb olunur. -* jinja2 - Standart şablon konfiqurasiyasÄąndan istifadə etmək istəyirsinizsə, tələb olunur. -* python-multipart - `request.form()` ilə forma "çevirmə" dəstəyindən istifadə etmək istəyirsinizsə, tələb olunur. -* itsdangerous - `SessionMiddleware` dəstəyi ÃŧçÃŧn tələb olunur. -* pyyaml - `SchemaGenerator` dəstəyi ÃŧçÃŧn tələb olunur (Çox gÃŧman ki, FastAPI istifadə edərkən buna ehtiyacÄąnÄąz olmayacaq). -* ujson - `UJSONResponse` istifadə etmək istəyirsinizsə, tələb olunur. - -Həm FastAPI, həm də Starlette tərəfindən istifadə olunur: - -* uvicorn - YaratdığımÄąz proqramÄą servis edəcək veb server kimi fəaliyyət gÃļstərir. -* orjson - `ORJSONResponse` istifadə edəcəksinizsə tələb olunur. - -BÃŧtÃŧn bunlarÄą `pip install fastapi[all]` ilə quraşdÄąra bilərsiniz. - -## Lisenziya - -Bu layihə MIT lisenziyasÄąnÄąn şərtlərinə əsasən lisenziyalaşdÄąrÄąlÄąb. diff --git a/docs/az/docs/learn/index.md b/docs/az/docs/learn/index.md deleted file mode 100644 index cc32108bf..000000000 --- a/docs/az/docs/learn/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# Öyrən - -Burada **FastAPI** Ãļyrənmək ÃŧçÃŧn giriş bÃļlmələri və dərsliklər yer alÄąr. - -Siz bunu kitab, kurs, FastAPI Ãļyrənmək ÃŧçÃŧn rəsmi və tÃļvsiyə olunan Ãŧsul hesab edə bilərsiniz. 😎 diff --git a/docs/az/mkdocs.yml b/docs/az/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/az/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/bn/docs/about/index.md b/docs/bn/docs/about/index.md deleted file mode 100644 index b6d611ae9..000000000 --- a/docs/bn/docs/about/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ - -**FastAPI** āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ — āĻāϰ āĻĄāĻŋāϜāĻžāχāύ, āĻ…āύ⧁āĻĒā§āϰ⧇āϰāĻŖāĻž āĻ“ āφāϰāĻ“ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁āĨ¤ 🤓 diff --git a/docs/bn/docs/environment-variables.md b/docs/bn/docs/environment-variables.md deleted file mode 100644 index 9122ca5bf..000000000 --- a/docs/bn/docs/environment-variables.md +++ /dev/null @@ -1,298 +0,0 @@ -# āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ - -/// tip - -āφāĻĒāύāĻŋ āϝāĻĻāĻŋ "āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ" āϕ⧀ āĻāĻŦāĻ‚ āϏ⧇āϗ⧁āϞ⧋ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāϝāĻŧ āϏ⧇āϟāĻž āϜāĻžāύ⧇āύ, āϤāĻžāĻšāϞ⧇ āĻāχ āĻ…āĻ‚āĻļāϟāĻŋ āĻ¸ā§āĻ•āĻŋāĻĒ āĻ•āϰ⧇ āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -/// - -āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ (āϏāĻ‚āĻ•ā§āώ⧇āĻĒ⧇ "**env var**" āύāĻžāĻŽā§‡āĻ“ āĻĒāϰāĻŋāϚāĻŋāϤ) āĻšāϞ⧋ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϝāĻž āĻĒāĻžāχāĻĨāύ āϕ⧋āĻĄā§‡āϰ **āĻŦāĻžāχāϰ⧇**, **āĻ…āĻĒāĻžāϰ⧇āϟāĻŋāĻ‚ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡** āĻĨāĻžāϕ⧇ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āĻĒāĻžāχāĻĨāύ āϕ⧋āĻĄ (āĻŦāĻž āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ) āĻĻā§āĻŦāĻžāϰāĻž āϝāĻžāϕ⧇ āϰāĻŋāĻĄ āĻ•āϰāĻž āϝāĻžāϝāĻŧāĨ¤ - -āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ⧇āϰ **āϏ⧇āϟāĻŋāĻ‚āϏ** āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰāϤ⧇, āĻĒāĻžāχāĻĨāύ⧇āϰ **āχāύāĻ¸ā§āϟāϞ⧇āĻļāύ** āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϰ āĻ…āĻ‚āĻļ āĻšāĻŋāϏ⧇āĻŦ⧇, āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āĻ•āĻžāĻœā§‡ āωāĻĒāϝ⧋āĻ—ā§€ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -## Env Vars āϤ⧈āϰ⧀ āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ - -āφāĻĒāύāĻŋ **āĻļ⧇āϞ (āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ)**-āĻ, āĻĒāĻžāχāĻĨāύ⧇āϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻ›āĻžāĻĄāĻŧāĻžāχ, āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ **āϤ⧈āϰāĻŋ** āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύāσ - -//// tab | āϞāĻŋāύāĻžāĻ•ā§āϏ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ, āωāχāĻ¨ā§āĻĄā§‹āϜ Bash - -
- -```console -// āφāĻĒāύāĻŋ āϚāĻžāχāϞ⧇ MY_NAME āύāĻžāĻŽā§‡ āĻāĻ•āϟāĻŋ env var āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ -$ export MY_NAME="Wade Wilson" - -// āϤāĻžāϰāĻĒāϰ⧇ āĻāϟāĻŋāϕ⧇ āϚāĻžāχāϞ⧇ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ -$ echo "Hello $MY_NAME" - -Hello Wade Wilson -``` - -
- -//// - -//// tab | āωāχāĻ¨ā§āĻĄā§‹āϜ āĻĒāĻžāĻ“ā§ŸāĻžāϰāĻļ⧇āϞ - -
- -```console -// MY_NAME āύāĻžāĻŽā§‡ env var āϤ⧈āϰāĻŋ -$ $Env:MY_NAME = "Wade Wilson" - -// āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡ āĻāϟāĻŋāϕ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ -$ echo "Hello $Env:MY_NAME" - -Hello Wade Wilson -``` - -
- -//// - -## āĻĒāĻžāχāĻĨāύ⧇ env vars āϰāĻŋāĻĄ āĻ•āϰāĻž - -āφāĻĒāύāĻŋ āϚāĻžāχāϞ⧇ āĻĒāĻžāχāĻĨāύ⧇āϰ **āĻŦāĻžāχāϰ⧇**, āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ⧇ (āĻŦāĻž āĻ…āĻ¨ā§āϝ āϕ⧋āύ⧋ āωāĻĒāĻžāϝāĻŧ⧇) āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āĻāĻŦāĻ‚ āĻĒāϰ⧇ āϏ⧇āϗ⧁āϞ⧋ **āĻĒāĻžāχāĻĨāύ⧇ āϰāĻŋāĻĄ** (āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ āĻ•āϰāϤ⧇) āĻĒāĻžāϰ⧇āύāĨ¤ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āφāĻĒāύāĻžāϰ `main.py` āύāĻžāĻŽā§‡ āĻāĻ•āϟāĻŋ āĻĢāĻžāχāϞ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇āσ - -```Python hl_lines="3" -import os - -name = os.getenv("MY_NAME", "World") -print(f"Hello {name} from Python") -``` - -/// tip - -`os.getenv()` āĻāϰ āĻĻā§āĻŦāĻŋāĻ¤ā§€ā§Ÿ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟāϟāĻŋ āĻšāϞ⧋ āĻāϰ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āϝāĻž āϰāĻŋāϟāĻžāĻ°ā§āύ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤ - -āϝāĻĻāĻŋ āĻāϟāĻŋ āĻĻ⧇āĻ“ā§ŸāĻž āύāĻž āĻšā§Ÿ, āĻĄāĻŋāĻĢāĻ˛ā§āϟāĻ­āĻžāĻŦ⧇ `None` āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāĻŦ⧇, āĻāĻ–āĻžāύ⧇ āφāĻŽāϰāĻž āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻšāĻŋāϏ⧇āĻŦ⧇ `"World"` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĻ›āĻŋāĨ¤ - -/// - -āϤāĻžāϰāĻĒāϰ⧇ āĻĒāĻžāχāĻĨāύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋāϕ⧇ āύāĻŋāĻŽā§āύ⧋āĻ•ā§āϤāĻ­āĻžāĻŦ⧇ āĻ•āϞ āĻ•āϰāĻž āϝāĻžāĻŦ⧇āσ - -//// tab | āϞāĻŋāύāĻžāĻ•ā§āϏ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ, āωāχāĻ¨ā§āĻĄā§‹āϜ Bash - -
- -```console -// āĻāĻ–āύ⧋ āφāĻŽāϰāĻž āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϏ⧇āϟ āĻ•āϰāĻŋāύāĻŋ -$ python main.py - -// āϝ⧇āĻšā§‡āϤ⧁ env var āϏ⧇āϟ āĻ•āϰāĻž āĻšā§ŸāύāĻŋ, āϤāĻžāχ āφāĻŽāϰāĻž āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻĒāĻžāĻšā§āĻ›āĻŋ - -Hello World from Python - -// āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻŽāϰāĻž āĻĒā§āϰāĻĨāĻŽā§‡ āϝāĻĻāĻŋ āĻāĻ•āϟāĻž āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āĻ­āĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇ āύ⧇āχ -$ export MY_NAME="Wade Wilson" - -// āĻāĻŦāĻ‚ āϤāĻžāϰāĻĒāϰ āφāĻŦāĻžāϰ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāϟāĻŋāϕ⧇ āĻ•āϞ āĻ•āϰāĻŋ -$ python main.py - -// āĻāĻ–āύ āĻāϟāĻŋ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϰāĻŋāĻĄ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ - -Hello Wade Wilson from Python -``` - -
- -//// - -//// tab | āωāχāĻ¨ā§āĻĄā§‹āϜ āĻĒāĻžāĻ“ā§ŸāĻžāϰāĻļ⧇āϞ - -
- -```console -// āĻāĻ–āύ⧋ āφāĻŽāϰāĻž āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϏ⧇āϟ āĻ•āϰāĻŋāύāĻŋ -$ python main.py - -// āϝ⧇āĻšā§‡āϤ⧁ env var āϏ⧇āϟ āĻ•āϰāĻž āĻšā§ŸāύāĻŋ, āϤāĻžāχ āφāĻŽāϰāĻž āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻĒāĻžāĻšā§āĻ›āĻŋ - -Hello World from Python - -// āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻŽāϰāĻž āĻĒā§āϰāĻĨāĻŽā§‡ āϝāĻĻāĻŋ āĻāĻ•āϟāĻž āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āĻ­āĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇ āύ⧇āχ -$ $Env:MY_NAME = "Wade Wilson" - -// āĻāĻŦāĻ‚ āϤāĻžāϰāĻĒāϰ āφāĻŦāĻžāϰ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāϟāĻŋāϕ⧇ āĻ•āϞ āĻ•āϰāĻŋ -$ python main.py - -// āĻāĻ–āύ āĻāϟāĻŋ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϰāĻŋāĻĄ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ - -Hello Wade Wilson from Python -``` - -
- -//// - -āϝ⧇āĻšā§‡āϤ⧁ āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ āϕ⧋āĻĄā§‡āϰ āĻŦāĻžāχāϰ⧇ āϏ⧇āϟ āĻ•āϰāĻž āϝāĻžāϝāĻŧ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĒāϰāĻŦāĻ°ā§āϤ⧀āϤ⧇ āϕ⧋āĻĄ āĻĻā§āĻŦāĻžāϰāĻž āϰāĻŋāĻĄ āĻ•āϰāĻž āϝāĻžāϝāĻŧ, āĻāĻŦāĻ‚ āĻŦāĻžāĻ•āĻŋ āĻĢāĻžāχāϞāϗ⧁āϞ⧋āϰ āϏāĻžāĻĨ⧇ āϰāĻžāĻ–āϤ⧇ (`git` āĻ āĻ•āĻŽāĻŋāϟ) āĻšā§Ÿ āύāĻž, āϤāĻžāχ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύāϏ āĻŦāĻž **āϏ⧇āϟāĻŋāĻ‚āϏ** āĻāϰ āϜāĻ¨ā§āϝ āĻāϗ⧁āϞ⧋ āϏāĻžāϧāĻžāϰāĻŖāϤ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšā§Ÿā§‡ āĻĨāĻžāϕ⧇āĨ¤ - -āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āϟāĻŋ **āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āχāύāĻ­ā§‹āϕ⧇āĻļāύ⧇āϰ** āϜāĻ¨ā§āϝāĻ“ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āϝāĻž āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āϏ⧇āχ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡āϰ āϜāĻ¨ā§āϝāχ āĻāϭ⧇āχāϞ⧇āĻŦāϞ āĻĨāĻžāĻ•āĻŦ⧇ āĻāĻŦāĻ‚ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āϤāĻžāϰ āϚāϞāĻžāĻ•āĻžāϞ⧀āύ āϏāĻŽāϝāĻŧ āĻĒāĻ°ā§āϝāĻ¨ā§āϤāχ āϏāĻ•ā§āϰāĻŋāϝāĻŧ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤ - -āĻāϟāĻŋ āĻ•āϰāϤ⧇, āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋ āϰāĻžāύ āĻ•āϰāĻžāϰ āĻ āĻŋāĻ• āφāϗ⧇āχ, āĻāĻ•āχ āϞāĻžāχāύ⧇ āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ: - -
- -```console -// āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋ āĻ•āϞ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ āĻāĻ•āχ āϞāĻžāχāύ⧇ MY_NAME āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ -$ MY_NAME="Wade Wilson" python main.py - -// āĻāĻ–āύ āĻāϟāĻŋ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āĻ­ā§āϝāϰāĻŋā§Ÿā§‡āĻŦāϞāϟāĻŋāϕ⧇ āϰāĻŋāĻĄ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ - -Hello Wade Wilson from Python - -// āĻĒāϰāĻŦāĻ°ā§āϤ⧀āϤ⧇ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϟāĻŋāϕ⧇ āφāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžāĻšā§āϛ⧇ āύāĻž -$ python main.py - -Hello World from Python -``` - -
- -/// tip - -āĻāϟāĻŋ āύāĻŋā§Ÿā§‡ āφāϰ⧋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āĻĒ⧜āϤ⧇ āĻĒāĻžāϰ⧇āύ āĻāĻ–āĻžāύ⧇ The Twelve-Factor App: ConfigāĨ¤ - -/// - -## āϟāĻžāχāĻĒāϏ āĻāĻŦāĻ‚ āĻ­ā§āϝāĻžāϞāĻŋāĻĄā§‡āĻļāύ - -āĻāχ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞ⧋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ **āĻŸā§‡āĻ•ā§āϏāϟ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚āϏ** āĻšā§āϝāĻžāĻ¨ā§āĻĄā§‡āϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇, āϝ⧇āĻšā§‡āϤ⧁ āĻāϗ⧁āϞ⧋ āĻĒāĻžāχāĻĨāύ⧇āϰ āĻŦāĻžāχāϰ⧇ āĻ…āĻŦāĻ¸ā§āĻĨāĻŋāϤ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻāĻŦāĻ‚ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡āϰ āĻŦāĻžāĻ•āĻŋ āĻ…āĻ‚āĻļ⧇āϰ (āĻāĻŽāύāĻ•āĻŋ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻ…āĻĒāĻžāϰ⧇āϟāĻŋāĻ‚ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āϝ⧇āĻŽāύ āϞāĻŋāύāĻžāĻ•ā§āϏ, āωāχāĻ¨ā§āĻĄā§‹āϜ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ) āϏāĻžāĻĨ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻšāϤ⧇ āĻšāϝāĻŧāĨ¤ - -āĻāϰ āĻ…āĻ°ā§āĻĨ āĻšāĻšā§āϛ⧇ āĻĒāĻžāχāĻĨāύ⧇ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āĻĨ⧇āϕ⧇ āϰāĻŋāĻĄ āĻ•āϰāĻž **āϝ⧇āϕ⧋āύ⧋ āĻ­ā§āϝāĻžāϞ⧁** āĻāĻ•āϟāĻŋ `str` āĻšāĻŦ⧇, āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝ āϕ⧋āύ⧋ āϟāĻžāχāĻĒ⧇ āĻ•āύāĻ­āĻžāĻ°ā§āϏāύ āĻŦāĻž āϝ⧇āϕ⧋āύ⧋ āϭ⧇āϞāĻŋāĻĄā§‡āĻļāύ āϕ⧋āĻĄā§‡ āφāϞāĻžāĻĻāĻžāĻ­āĻžāĻŦ⧇ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ - -āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ **āĻāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏ⧇āϟāĻŋāĻ‚āϏ** āĻšā§āϝāĻžāĻ¨ā§āĻĄā§‡āϞ āĻ•āϰāĻž āύāĻŋā§Ÿā§‡ āφāϰ⧋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϜāĻžāύāĻž āϝāĻžāĻŦ⧇ [Advanced User Guide - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank}. - -## `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ - -**`PATH`** āύāĻžāĻŽā§‡ āĻāĻ•āϟāĻŋ **āĻŦāĻŋāĻļ⧇āώ** āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻ°ā§Ÿā§‡āϛ⧇, āϝ⧇āϟāĻŋ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āϰāĻžāύ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻ…āĻĒāĻžāϰ⧇āϟāĻŋāĻ‚ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽāϏ (āϞāĻŋāύāĻžāĻ•ā§āϏ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ, āωāχāĻ¨ā§āĻĄā§‹āϜ) āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšā§ŸāĨ¤ - -`PATH` āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻāϰ āĻ­ā§āϝāĻžāϞ⧁ āĻšāĻšā§āϛ⧇ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻļāĻžāϞ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āϝāĻž āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϕ⧇ āϕ⧋āϞāύ `:` āĻĻāĻŋā§Ÿā§‡ āφāϞāĻžāĻĻāĻž āĻ•āϰāĻžāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϞāĻŋāύāĻžāĻ•ā§āϏ⧇ āĻ“ āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ āĻ, āĻāĻŦāĻ‚ āϏ⧇āĻŽāĻŋāϕ⧋āϞāύ `;` āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āωāχāĻ¨ā§āĻĄā§‹āϜ āĻ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻĨāĻžāϕ⧇āĨ¤ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, `PATH` āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āύāĻŋāĻšā§‡āϰ āĻŽāϤ⧋ āĻĻ⧇āĻ–āϤ⧇ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āσ - -//// tab | āϞāĻŋāύāĻžāĻ•ā§āϏ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ - -```plaintext -/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin -``` - -āϤāĻžāϰāĻŽāĻžāύ⧇ āĻšāϞ⧋ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϗ⧁āϞ⧋āϕ⧇ āύāĻŋāĻšā§‡āϰ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϗ⧁āϞ⧋āϤ⧇ āϖ⧁āρāϜāĻŦ⧇āσ - -* `/usr/local/bin` -* `/usr/bin` -* `/bin` -* `/usr/sbin` -* `/sbin` - -//// - -//// tab | āωāχāĻ¨ā§āĻĄā§‹āϜ - -```plaintext -C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 -``` - -āϤāĻžāϰāĻŽāĻžāύ⧇ āĻšāϞ⧋ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϗ⧁āϞ⧋āϕ⧇ āύāĻŋāĻšā§‡āϰ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϗ⧁āϞ⧋āϤ⧇ āϖ⧁āρāϜāĻŦ⧇āσ - -* `C:\Program Files\Python312\Scripts` -* `C:\Program Files\Python312` -* `C:\Windows\System32` - -//// - -āϝāĻ–āύ āφāĻĒāύāĻŋ āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ⧇ āϕ⧋āύ⧋ **āĻ•āĻŽāĻžāĻ¨ā§āĻĄ** āϞāĻŋāĻ–āĻŦ⧇āύ, āĻ…āĻĒāĻžāϰ⧇āϟāĻŋāĻ‚ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ **āĻĒā§āϰāĻ¤ā§āϝ⧇āĻ•āϟāĻŋ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇** āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋ **āϖ⧁āρāϜāĻŦ⧇** āϝ⧇āϗ⧁āϞ⧋ `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻ āϞāĻŋāĻ¸ā§āϟ āĻ•āϰāĻž āφāϛ⧇āĨ¤ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āϝāĻ–āύ āφāĻĒāύāĻŋ āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ⧇ `python` āϟāĻžāχāĻĒ āĻ•āϰāĻŦ⧇āύ, āĻ…āĻĒāĻžāϰ⧇āϟāĻŋāĻ‚ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻāχ āϞāĻŋāĻ¸ā§āϟ āĻāϰ **āĻĒā§āϰāĻĨāĻŽ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇** `python` āύāĻžāĻŽā§‡āϰ āĻāĻ•āϟāĻŋ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āϖ⧁āρāϜāĻŦ⧇āĨ¤ - -āϝāĻĻāĻŋ āĻāϟāĻŋ āϖ⧁āρāĻœā§‡ āĻĒāĻžā§Ÿ, āϤāĻžāĻšāϞ⧇ āĻāϟāĻŋ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋāϕ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ⧇āĨ¤ āĻ…āĻ¨ā§āϝāĻĨāĻžā§Ÿ āĻāϟāĻŋ **āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϗ⧁āϞ⧋āϤ⧇** āĻāϟāĻŋāϕ⧇ āϖ⧁āρāϜāϤ⧇ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤ - -### āĻĒāĻžāχāĻĨāύ āχāύāĻ¸ā§āϟāϞ āĻāĻŦāĻ‚ `PATH` āφāĻĒāĻĄā§‡āϟ - -āϝāĻ–āύ āφāĻĒāύāĻŋ āĻĒāĻžāχāĻĨāύ āχāύāĻ¸ā§āϟāϞ āĻ•āϰ⧇āύ, āφāĻĒāύāĻŋ `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāϤ⧇ āϚāĻžāύ āĻ•āĻŋāύāĻž āϏ⧇āϟāĻž āϜāĻŋāĻœā§āĻžā§‡āϏ āĻ•āϰāĻž āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -//// tab | āϞāĻŋāύāĻžāĻ•ā§āϏ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ - -āϧāϰāĻž āϝāĻžāĻ• āφāĻĒāύāĻŋ āĻĒāĻžāχāĻĨāύ āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϞ⧇āύ āĻāĻŦāĻ‚ āĻāϟāĻŋ `/opt/custompython/bin` āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇ āχāύāĻ¸ā§āϟāϞ āĻšāĻšā§āϛ⧇āĨ¤ - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ "Yes" āϏāĻŋāϞ⧇āĻ•ā§āϟ āĻ•āϰ⧇ `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāϤ⧇ āϚāĻžāύ, āϤāĻžāĻšāϞ⧇ āχāύāĻ¸ā§āϟāϞāĻžāϰ `/opt/custompython/bin` āϕ⧇ `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻ āĻāĻĄ āĻ•āϰ⧇ āĻĻāĻŋāĻŦ⧇āĨ¤ - -āĻāϟāĻž āĻĻ⧇āĻ–āϤ⧇ āĻāĻŽāύāϟāĻž āĻšāϤ⧇ āĻĒāĻžāϰ⧇āσ - -```plaintext -/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin -``` - -āĻāχāĻ­āĻžāĻŦ⧇, āφāĻĒāύāĻŋ āϝāĻ–āύ āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ⧇ `python` āϟāĻžāχāĻĒ āĻ•āϰ⧇āύ, āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻĒāĻžāχāĻĨāύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋāϕ⧇ `/opt/custompython/bin` (āϏāĻ°ā§āĻŦāĻļ⧇āώ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋ) āϤ⧇ āϖ⧁āρāĻœā§‡ āĻĒāĻžāĻŦ⧇ āĻāĻŦāĻ‚ āĻāϟāĻžāϕ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ⧇āĨ¤ - -//// - -//// tab | āωāχāĻ¨ā§āĻĄā§‹āϜ - -āϧāϰāĻž āϝāĻžāĻ• āφāĻĒāύāĻŋ āĻĒāĻžāχāĻĨāύ āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϞ⧇āύ āĻāĻŦāĻ‚ āĻāϟāĻŋ `C:\opt\custompython\bin` āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇ āχāύāĻ¸ā§āϟāϞ āĻšāĻšā§āϛ⧇āĨ¤ - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ "Yes" āϏāĻŋāϞ⧇āĻ•ā§āϟ āĻ•āϰ⧇ `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāϤ⧇ āϚāĻžāύ, āϤāĻžāĻšāϞ⧇ āχāύāĻ¸ā§āϟāϞāĻžāϰ `C:\opt\custompython\bin` āϕ⧇ `PATH` āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞ āĻ āĻāĻĄ āĻ•āϰ⧇ āĻĻāĻŋāĻŦ⧇āĨ¤ - -```plaintext -C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin -``` - -āĻāχāĻ­āĻžāĻŦ⧇, āφāĻĒāύāĻŋ āϝāĻ–āύ āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ⧇ `python` āϟāĻžāχāĻĒ āĻ•āϰ⧇āύ, āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻĒāĻžāχāĻĨāύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋāϕ⧇ `C:\opt\custompython\bin` (āϏāĻ°ā§āĻŦāĻļ⧇āώ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋ) āϤ⧇ āϖ⧁āρāĻœā§‡ āĻĒāĻžāĻŦ⧇ āĻāĻŦāĻ‚ āĻāϟāĻžāϕ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ⧇āĨ¤ - -//// - -āϤāĻžāχ, āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āϟāĻžāχāĻĒ āĻ•āϰ⧇āύāσ - -
- -```console -$ python -``` - -
- -//// tab | āϞāĻŋāύāĻžāĻ•ā§āϏ, āĻŽā§āϝāĻžāĻ•āĻ“āĻāϏ - -āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ `python` āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϕ⧇ `/opt/custompython/bin` āĻ **āϖ⧁āρāĻœā§‡ āĻĒāĻžāĻŦ⧇** āĻāĻŦāĻ‚ āĻāϟāĻžāϕ⧇ āϰāĻžāύ āĻ•āϰāĻŦ⧇āĨ¤ - -āĻāϟāĻž āĻŽā§‹āϟāĻžāĻŽā§āϟāĻŋāĻ­āĻžāĻŦ⧇ āύāĻŋāĻšā§‡āϰ āĻŽāϤ⧋ āĻ•āϰ⧇ āϞ⧇āĻ–āĻžāϰ āϏāĻŽāĻžāύ āĻšāĻŦ⧇āσ - -
- -```console -$ /opt/custompython/bin/python -``` - -
- -//// - -//// tab | āωāχāĻ¨ā§āĻĄā§‹āϜ - -āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ `python` āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϕ⧇ `C:\opt\custompython\bin\python` āĻ **āϖ⧁āρāĻœā§‡ āĻĒāĻžāĻŦ⧇** āĻāĻŦāĻ‚ āĻāϟāĻžāϕ⧇ āϰāĻžāύ āĻ•āϰāĻŦ⧇āĨ¤ - -āĻāϟāĻž āĻŽā§‹āϟāĻžāĻŽā§āϟāĻŋāĻ­āĻžāĻŦ⧇ āύāĻŋāĻšā§‡āϰ āĻŽāϤ⧋ āĻ•āϰ⧇ āϞ⧇āĻ–āĻžāϰ āϏāĻŽāĻžāύ āĻšāĻŦ⧇āσ - -
- -```console -$ C:\opt\custompython\bin\python -``` - -
- -//// - -āĻāχ āϤāĻĨā§āϝāϗ⧁āϞ⧋ [āĻ­āĻžāĻ°ā§āϚ⧁⧟āĻžāϞ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟāϏ](virtual-environments.md){.internal-link target=_blank} āĻļ⧇āĻ–āĻžāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āϏāĻšāĻžā§ŸāĻ• āĻšāĻŦ⧇āĨ¤ - -## āωāĻĒāϏāĻ‚āĻšāĻžāϰ - -āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āφāĻĒāύāĻŋ **āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋā§Ÿā§‡āĻŦāϞāϏ** āĻ•āĻŋ āĻāĻŦāĻ‚ āĻāϟāĻŋāϕ⧇ āĻĒāĻžāχāĻĨāύ⧇ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšā§Ÿ āϤāĻžāϰ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻŦ⧇āϏāĻŋāĻ• āϧāĻžāϰāύāĻž āĻĒ⧇āϞ⧇āύāĨ¤ - -āϚāĻžāχāϞ⧇ āĻāχ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰ⧋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āĻĒ⧜āϤ⧇ āĻĒāĻžāϰ⧇āύ Wikipedia for Environment Variable āĻāĨ¤ - -āĻ…āύ⧇āĻ• āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, āĻĻ⧇āĻ–āĻž āĻŽāĻžāĻ¤ā§āϰāχ āĻāύāĻ­āĻžāϝāĻŧāϰāύāĻŽā§‡āĻ¨ā§āϟ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āĻšāĻŦ⧇ āϤāĻž āĻ¸ā§āĻĒāĻˇā§āϟ āĻšā§Ÿ āύāĻžāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āĻŸā§‡āϰ āϏāĻŽāϝāĻŧ āφāĻĒāύāĻŋ āύāĻžāύāĻž āϰāĻ•āĻŽ āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋāϤ⧇ āĻāϗ⧁āϞ⧋āϰ āϏāĻŽā§āĻŽā§āĻ–ā§€āύ āĻšāĻŦ⧇āύ, āϤāĻžāχ āĻāϗ⧁āϞ⧋ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻœā§‡āύ⧇ āϰāĻžāĻ–āĻž āĻ­āĻžāϞ⧋āĨ¤ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āφāĻĒāύāĻžāϰ āĻāχ āχāύāĻĢāϰāĻŽā§‡āĻļāύāϟāĻŋ āĻĒāϰāĻŦāĻ°ā§āϤ⧀, [āĻ­āĻžāĻ°ā§āϚ⧁⧟āĻžāϞ āĻāύāĻ­āĻžā§ŸāϰāύāĻŽā§‡āĻ¨ā§āϟāϏ](virtual-environments.md) āĻ…āĻ‚āĻļ⧇ āĻĻāϰāĻ•āĻžāϰ āĻšāĻŦ⧇āĨ¤ diff --git a/docs/bn/docs/index.md b/docs/bn/docs/index.md deleted file mode 100644 index 74ee230a1..000000000 --- a/docs/bn/docs/index.md +++ /dev/null @@ -1,466 +0,0 @@ -

- FastAPI -

-

- FastAPI āωāĻšā§āϚāĻ•ā§āώāĻŽāϤāĻž āϏāĻŽā§āĻĒāĻ¨ā§āύ, āϏāĻšāĻœā§‡ āĻļ⧇āĻ–āĻžāϰ āĻāĻŦāĻ‚ āĻĻā§āϰ⧁āϤ āϕ⧋āĻĄ āĻ•āϰ⧇ āĻĒā§āϰ⧋āĻĄāĻžāĻ•āĻļāύ⧇āϰ āϜāĻ¨ā§āϝ āĻĢā§āϰāĻžāĻŽāĻ“ā§ŸāĻžāĻ°ā§āĻ•āĨ¤ -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ**: https://fastapi.tiangolo.com - -**āϏ⧋āĻ°ā§āϏ āϕ⧋āĻĄ**: https://github.com/fastapi/fastapi - ---- - -FastAPI āĻāĻ•āϟāĻŋ āφāϧ⧁āύāĻŋāĻ•, āĻĻā§āϰ⧁āϤ ( āĻŦ⧇āĻļāĻŋ āĻ•ā§āώāĻŽāϤāĻž ) āϏāĻŽā§āĻĒāĻ¨ā§āύ, Python 3.6+ āĻĻāĻŋā§Ÿā§‡ API āϤ⧈āϰāĻŋāϰ āϜāĻ¨ā§āϝ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āĻĒāĻžāχāĻĨāύ āϟāĻžāχāĻĒ āχāĻ™ā§āĻ—āĻŋāϤ āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ• āĻ“āϝāĻŧ⧇āĻŦ āĻĢā§āϰ⧇āĻŽāĻ“āϝāĻŧāĻžāĻ°ā§āĻ•āĨ¤ - -āĻāϰ āĻŽā§‚āϞ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϗ⧁āϞ⧋ āĻšāϞāσ - -- **āĻ—āϤāĻŋ**: āĻāϟāĻŋ **NodeJS** āĻāĻŦāĻ‚ **Go** āĻāϰ āĻŽāϤ āĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž āϏāĻŽā§āĻĒāĻ¨ā§āύ (Starlette āĻāĻŦāĻ‚ Pydantic āĻāϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ⧇)āĨ¤ [āĻĒāĻžāχāĻĨāύ āĻāϰ āĻĻā§āϰ⧁āϤāϤāĻŽ āĻĢā§āϰ⧇āĻŽāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āϗ⧁āϞ⧋āϰ āĻŽāĻ§ā§āϝ⧇ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ](#_11)āĨ¤ -- **āĻĻā§āϰ⧁āϤ āϕ⧋āĻĄ āĻ•āϰāĻž**:āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϤ⧈āϰāĻŋāϰ āĻ—āϤāĻŋ ⧍ā§Ļā§Ļ% āĻĨ⧇āϕ⧇ ā§Šā§Ļā§Ļ% āĻŦ⧃āĻĻā§āϧāĻŋ āĻ•āϰ⧇⧎ \* -- **āĻ¸ā§āĻŦāĻ˛ā§āĻĒ bugs**: āĻŽāĻžāύ⧁āĻŦ (āĻĄā§‡āϭ⧇āϞāĻĒāĻžāϰ) āϏ⧃āĻˇā§āϟ āĻ¤ā§āϰ⧁āϟāĻŋāϰ āĻĒā§āϰāĻžāϝāĻŧ ā§Ēā§Ļ% āĻšā§āϰāĻžāϏ āĻ•āϰ⧇āĨ¤ \* -- **āĻ¸ā§āĻŦāĻœā§āĻžāĻžāϤ**: āĻĻ⧁āĻ°ā§āĻĻāĻžāĻ¨ā§āϤ āĻāĻĄāĻŋāϟāϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ Completion āύāĻžāĻŽā§‡āĻ“ āĻĒāϰāĻŋāϚāĻŋāϤāĨ¤ āĻĻā§āϰ⧁āϤ āĻĄāĻŋāĻŦāĻžāĻ— āĻ•āϰāĻž āϝāĻžā§ŸāĨ¤ - -- **āϏāĻšāϜ**: āĻāϟāĻŋ āĻāĻŽāύ āĻ­āĻžāĻŦ⧇ āϏāϜāĻžāύ⧋ āĻšā§Ÿā§‡āϛ⧇ āϝ⧇āύ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ āĻĒā§œā§‡ āϏāĻšāĻœā§‡ āĻļ⧇āĻ–āĻž āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžā§ŸāĨ¤ -- **āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤ**: āϕ⧋āĻĄ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻ•āĻŽāĻžāύ⧋āϰ āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ, bug āĻ•āĻŽāĻžā§Ÿ āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻ˜ā§‹āώāĻŖāĻž āĻĨ⧇āϕ⧇ āĻāĻ•āĻžāϧāĻŋāĻ• āĻĢāĻŋāϚāĻžāϰ āĻĒāĻžāĻ“ā§ŸāĻž āϝāĻžā§Ÿ āĨ¤ -- **āĻœā§‹āϰāĻžāϞ⧋**: āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻ­āĻžāĻŦ⧇ āϤ⧈āϰāĻŋ āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāύāĻž āύāĻĨāĻŋ (documentation) āϏāĻš āĻ‰ā§ŽāĻĒāĻžāĻĻāύ āωāĻĒāϝ⧋āĻ—āĻŋ (Production-ready) āϕ⧋āĻĄ āĻĒāĻžāĻ“ā§ŸāĻž āϝāĻžā§ŸāĨ¤ -- **āĻŽāĻžāύ-āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ•**: āĻāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ OpenAPI (āϝāĻž āĻĒ⧁āĻ°ā§āĻŦ⧇ Swagger āύāĻžāĻŽā§‡ āĻĒāϰāĻŋāϚāĻŋāϤ āĻ›āĻŋāϞ) āĻāĻŦāĻ‚ JSON Schema āĻāϰ āφāĻĻāĻ°ā§āĻļ⧇āϰ āĻŽāĻžāύ⧇āϰ āĻ“āĻĒāϰ - -\* āĻ‰ā§ŽāĻĒāĻžāĻĻāύāĻŽā§āĻ–āĻŋ āĻāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻŦāĻžāύāĻžāύ⧋āϰ āĻāĻ• āĻĻāϞ āĻĄā§‡āϭ⧇āϞāĻĒāĻžāϰ āĻāϰ āĻŽāϤāĻžāĻŽāϤ āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ• āĻĢāϞāĻžāĻĢāϞāĨ¤ - -## āĻ¸ā§āĻĒāύāϏāϰ āĻ—āĻŖ - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ¸ā§āĻĒāύāϏāϰ āĻ—āĻŖ - -## āĻŽāϤāĻžāĻŽāϤ āϏāĻŽā§‚āĻš - -"_āφāĻŽāĻŋ āφāϜāĻ•āĻžāϞ **FastAPI** āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻ›āĻŋāĨ¤ [...] āφāĻŽāϰāĻž āĻ­āĻžāĻŦāĻ›āĻŋ āĻŽāĻžāχāĻ•ā§āϰ⧋āϏāĻĢā§āĻŸā§‡ **ML āϏāĻžāĻ°ā§āĻ­āĻŋāϏ** āĻ āϏāĻ•āϞ āĻĻāϞ⧇āϰ āϜāĻ¨ā§āϝ āĻāϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦāĨ¤ āϝāĻžāϰ āĻŽāĻ§ā§āϝ⧇ āĻ•āĻŋāϛ⧁ āĻĒāĻŖā§āϝ **Windows** āĻ āϏāĻ‚āϝ⧋āϝāύ āĻšā§Ÿ āĻāĻŦāĻ‚ āĻ•āĻŋāϛ⧁ **Office** āĻāϰ āϏāĻžāĻĨ⧇ āϏāĻ‚āϝ⧋āϝāύ āĻšāĻšā§āϛ⧇āĨ¤_" - -
āĻ•āĻŦāĻŋāϰ āĻ–āĻžāύ - āĻŽāĻžāχāĻ•ā§āϰ⧋āϏāĻĢā§āĻŸā§‡ (ref)
- ---- - -"_āφāĻŽāϰāĻž **FastAPI** āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ⧇āĻ›āĻŋ āĻāĻ•āϟāĻŋ **REST** āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇, āϝāĻž **āĻ­āĻŦāĻŋāĻˇā§āϝāĻĻā§āĻŦāĻžāĻŖā§€** āĻĒāĻžāĻ“āϝāĻŧāĻžāϰ āϜāĻ¨ā§āϝ āĻ•ā§ā§Ÿā§‡āϰāĻŋ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ [āϞ⧁āĻĄāωāχāϗ⧇āϰ āϜāĻ¨ā§āϝ]_" - -
āĻĒāĻŋāϝāĻŧ⧇āϰ⧋ āĻŽā§‹āϞāĻŋāύ⧋, āχāϝāĻŧāĻžāϰ⧋āĻ¸ā§āϞāĻžāĻ­ āĻĻ⧁āĻĻāĻŋāύ, āĻāĻŦāĻ‚ āϏāĻžāχ āϏ⧁āĻŽāĻ¨ā§āĻĨ āĻŽāĻŋāϰāĻŋāϝāĻŧāĻžāϞāĻž - āωāĻŦāĻžāϰ (ref)
- ---- - -"_**Netflix** āφāĻŽāĻžāĻĻ⧇āϰ **āĻ•ā§āϰāĻžāχāϏāĻŋāϏ āĻŽā§āϝāĻžāύ⧇āϜāĻŽā§‡āĻ¨ā§āϟ** āĻ…āĻ°ā§āϕ⧇āĻ¸ā§āĻŸā§āϰ⧇āĻļāύ āĻĢā§āϰ⧇āĻŽāĻ“āϝāĻŧāĻžāĻ°ā§āĻ•: **āĻĄāĻŋāϏāĻĒā§āϝāĻžāϚ** āĻāϰ āĻ“āĻĒ⧇āύ āϏ⧋āĻ°ā§āϏ āϰāĻŋāϞāĻŋāϜ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒ⧇āϰ⧇ āφāύāĻ¨ā§āĻĻāĻŋāϤ! [āϝāĻžāĻ•āĻŋāύāĻž **FastAPI** āĻĻāĻŋāϝāĻŧ⧇ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ]_" - -
āϕ⧇āĻ­āĻŋāύ āĻ—ā§āϞāĻŋāϏāύ, āĻŽāĻžāĻ°ā§āĻ• āĻ­āĻŋāϞāĻžāύ⧋āĻ­āĻž, āĻĢāϰ⧇āĻ¸ā§āϟ āĻŽāύāϏ⧇āύ - āύ⧇āϟāĻĢā§āϞāĻŋāĻ•ā§āϏ (ref)
- ---- - -"_āφāĻŽāĻŋ **FastAPI** āύāĻŋāϝāĻŧ⧇ āϚāĻžāρāĻĻ⧇āϰ āϏāĻŽāĻžāύ āĻ‰ā§ŽāϏāĻžāĻšāĻŋāϤāĨ¤ āĻāϟāĻŋ āϖ⧁āĻŦāχ āĻŽāϜāĻžāϰ!_" - -
āĻŦā§āϰāĻžāϝāĻŧāĻžāύ āĻ“āϕ⧇āύ - āĻĒāĻžāχāĻĨāύ āĻŦāĻžāχāϟāϏ āĻĒāĻĄāĻ•āĻžāĻ¸ā§āϟ āĻšā§‹āĻ¸ā§āϟ (ref)
- ---- - -"\_āϏāĻ¤ā§āϝāĻŋāχ, āφāĻĒāύāĻŋ āϝāĻž āϤ⧈āϰāĻŋ āĻ•āϰ⧇āϛ⧇āύ āϤāĻž āϖ⧁āĻŦ āĻŽāϜāĻŦ⧁āϤ āĻāĻŦāĻ‚ āĻĒāϰāĻŋāĻĒā§‚āĻ°ā§āύ⧎ āĻ…āύ⧇āĻ• āωāĻĒāĻžāϝāĻŧ⧇, āφāĻŽāĻŋ āϝāĻž **Hug** āĻ āĻ•āϰāϤ⧇ āĻšā§‡ā§Ÿā§‡āĻ›āĻŋāϞāĻžāĻŽ - āϤāĻž āĻ•āĻžāωāϕ⧇ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĻ⧇āϖ⧇ āφāĻŽāĻŋ āϏāĻ¤ā§āϝāĻŋāχ āĻ…āύ⧁āĻĒā§āϰāĻžāύāĻŋāϤ⧎\_" - -
āϟāĻŋāĻŽā§‹āĻĨāĻŋ āĻ•ā§āϰāϏāϞ⧇ - Hug āĻ¸ā§āϰāĻˇā§āϟāĻž (ref)
- ---- - -"āφāĻĒāύāĻŋ āϝāĻĻāĻŋ REST API āϤ⧈āϰāĻŋāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ **āφāϧ⧁āύāĻŋāĻ• āĻĢā§āϰ⧇āĻŽāĻ“ā§ŸāĻžāĻ°ā§āĻ•** āĻļāĻŋāĻ–āϤ⧇ āϚāĻžāύ, āϤāĻžāĻšāϞ⧇ **FastAPI** āĻĻ⧇āϖ⧁āύ [...] āĻāϟāĻŋ āĻĻā§āϰ⧁āϤ, āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϏāĻšāϜ āĻāĻŦāĻ‚ āĻļāĻŋāĻ–āϤ⧇āĻ“ āϏāĻšāϜ [...]\_" - -"_āφāĻŽāϰāĻž āφāĻŽāĻžāĻĻ⧇āϰ **APIs** [...] āĻāϰ āϜāĻ¨ā§āϝ **FastAPI**- āϤ⧇ āĻāϏ⧇āĻ›āĻŋ [...] āφāĻŽāĻŋ āĻŽāύ⧇ āĻ•āϰāĻŋ āφāĻĒāύāĻŋāĻ“ āĻāϟāĻŋ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰāĻŦ⧇āύ [...]_" - -
āχāύ⧇āϏ āĻŽāĻ¨ā§āϟāĻžāύāĻŋ - āĻŽā§āϝāĻžāĻĨāĻŋāω āĻšā§‹āύāĻŋāĻŦāĻžāϞ - Explosion AI āĻĒā§āϰāϤāĻŋāĻˇā§āĻ āĻžāϤāĻž - spaCy āĻ¸ā§āϰāĻˇā§āϟāĻž (ref) - (ref)
- ---- - -## **Typer**, CLI āĻāϰ āϜāĻ¨ā§āϝ FastAPI - - - -āφāĻĒāύāĻŋ āϝāĻĻāĻŋ CLI āĻ…ā§āϝāĻžāĻĒ āĻŦāĻžāύāĻžāϤ⧇ āϚāĻžāύ, āϝāĻž āĻ•āĻŋāύāĻž āĻ“ā§Ÿā§‡āĻŦ API āĻāϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ āϟāĻžāĻ°ā§āĻŽāĻŋāύāĻžāϞ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāĻŦ⧇, āϤāĻžāĻšāϞ⧇ āĻĻ⧇āϖ⧁āύ**Typer**. - -**āϟāĻžāχāĻĒāĻžāϰ** āĻšāϞ FastAPI āĻāϰ āϛ⧋āϟ āĻ­āĻžāĻ‡ā§Ÿā§‡āϰ āĻŽāϤāĨ¤ āĻāĻŦāĻ‚ āĻāϟāĻŋāϰ āωāĻĻā§āĻĻ⧇āĻļā§āϝ āĻ›āĻŋāϞ **CLIs āĻāϰ FastAPI** āĻšāĻ“ā§ŸāĻžāĨ¤ âŒ¨ī¸ 🚀 - -## āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧāϤāĻž āϗ⧁āϞ⧋ - -Python 3.7+ - -FastAPI āĻ•āĻŋāϛ⧁ āĻĻāĻžāύāĻŦ⧇āĻĻ⧇āϰ āĻ•āĻžāρāϧ⧇ āĻĻāĻžāρāĻĄāĻŧāĻŋāϝāĻŧ⧇ āφāϛ⧇: - -- Starlette āĻ“āϝāĻŧ⧇āĻŦ āĻ…āĻ‚āĻļ⧇āϰ āϜāĻ¨ā§āϝ. -- Pydantic āĻĄā§‡āϟāĻž āĻ…āĻ‚āĻļāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ. - -## āχāύāĻ¸ā§āϟāϞ⧇āĻļāύ āĻĒā§āϰāĻ•ā§āϰāĻŋ⧟āĻž - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -āφāĻĒāύāĻžāϰ āĻāĻ•āϟāĻŋ ASGI āϏāĻžāĻ°ā§āĻ­āĻžāϰ⧇āϰāĻ“ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻšāĻŦ⧇, āĻĒā§āϰ⧋āĻĄāĻžāĻ•āĻļāύ⧇āϰ āϜāĻ¨ā§āϝ Uvicorn āĻ…āĻĨāĻŦāĻž Hypercorn. - -
- -```console -$ pip install "uvicorn[standard]" - ----> 100% -``` - -
- -## āωāĻĻāĻžāĻšāϰāĻŖ - -### āϤ⧈āϰāĻŋ - -- `main.py` āύāĻžāĻŽā§‡ āĻāĻ•āϟāĻŋ āĻĢāĻžāχāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ: - -```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} -``` - -
-āĻ…āĻĨāĻŦāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ async def... - -āϝāĻĻāĻŋ āφāĻĒāύāĻžāϰ āϕ⧋āĻĄ `async` / `await`, āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϤāĻžāĻšāϞ⧇ `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} -``` - -**āĻŸā§€āĻ•āĻž**: - -āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āύāĻž āϜāĻžāύ⧇āύ, _"āϤāĻžāĻĄāĻŧāĻžāĻšā§āĻĄāĻŧā§‹?"_ āĻŦāĻŋāĻ­āĻžāĻ—āϟāĻŋ āĻĻ⧇āϖ⧁āύ `async` āĻāĻŦāĻ‚ `await` āύāĻĨāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āĻĻ⧇āϖ⧁āύ . - -
- -### āĻāϟāĻŋ āϚāĻžāϞāĻžāύ - -āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύ: - -
- -```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. -``` - -
- -
-āύāĻŋāĻ°ā§āĻĻ⧇āĻļāύāĻž āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ uvicorn main:app --reload... - -`uvicorn main:app` āύāĻŋāĻ°ā§āĻĻ⧇āĻļāύāĻžāϟāĻŋ āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§‹āĻāĻžāϝāĻŧ: - -- `main`: āĻĢāĻžāχāϞ `main.py` (āĻĒāĻžāχāĻĨāύ "āĻŽāĻĄāĻŋāωāϞ")āĨ¤ -- `app`: `app = FastAPI()` āϞāĻžāχāύ āĻĻāĻŋāϝāĻŧ⧇ `main.py` āĻāϰ āĻ­āĻŋāϤāϰ⧇ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻ…āĻŦāĻœā§‡āĻ•ā§āϟāĨ¤ -- `--reload`: āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āĻĒāϰ⧇ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻĒ⧁āύāϰāĻžāϝāĻŧ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύāĨ¤ āĻāϟāĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āϟ āĻāϰ āϏāĻŽā§Ÿ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤ - -
- -### āĻāϟāĻž āĻšā§‡āĻ• āĻ•āϰ⧁āύ - -āφāĻĒāύāĻžāϰ āĻŦā§āϰāĻžāωāϜāĻžāϰ āϖ⧁āϞ⧁āύ http://127.0.0.1:8000/items/5?q=somequery āĻāĨ¤ - -āφāĻĒāύāĻŋ JSON āϰ⧇āϏāĻĒāĻ¨ā§āϏ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύ: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -āφāĻĒāύāĻŋ āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻŋ API āϤ⧈āϰāĻŋ āĻ•āϰ⧇āϛ⧇āύ āϝāĻž: - -- `/` āĻāĻŦāĻ‚ `/items/{item_id}` _paths_ āĻ HTTP āĻ…āύ⧁āϰ⧋āϧ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ⧇āĨ¤ -- āωāĻ­āϝāĻŧ *path*āχ `GET` āĻ…āĻĒāĻžāϰ⧇āĻļāύ āύ⧇āϝāĻŧ ( āϝāĻž HTTP _methods_ āύāĻžāĻŽā§‡āĻ“ āĻĒāϰāĻŋāϚāĻŋāϤ)āĨ¤ -- _path_ `/items/{item_id}`-āĻ āĻāĻ•āϟāĻŋ _path āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ_ `item_id` āφāϛ⧇ āϝāĻž āĻ•āĻŋāύāĻž `int` āĻšāϤ⧇ āĻšāĻŦ⧇āĨ¤ -- _path_ `/items/{item_id}`-āĻāϰ āĻāĻ•āϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ• `str` _query āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ_ `q` āφāϛ⧇āĨ¤ - -### āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ - -āĻāĻ–āύ āϝāĻžāύ http://127.0.0.1:8000/docs. - -āφāĻĒāύāĻŋ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻ­āĻžāĻŦ⧇ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύ (Swagger UI āĻĒā§āϰāĻĻāĻ¤ā§āϤ): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ - -āĻāĻŦāĻ‚ āĻāĻ–āύ http://127.0.0.1:8000/redoc āĻ āϝāĻžāύ. - -āφāĻĒāύāĻŋ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻ­āĻžāĻŦ⧇ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύ (ReDoc āĻĒā§āϰāĻĻāĻ¤ā§āϤ): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ āφāĻĒāĻ—ā§āϰ⧇āĻĄ - -āĻāĻ–āύ `main.py` āĻĢāĻžāχāϞāϟāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧁āύ āϝ⧇āύ āĻāϟāĻŋ `PUT` āϰāĻŋāĻ•ā§ā§Ÿā§‡āĻ¸ā§āϟ āĻĨ⧇āϕ⧇ āĻŦāĻĄāĻŋ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -Python āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ, 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} -``` - -āϏāĻžāĻ°ā§āĻ­āĻžāϰāϟāĻŋ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āĻĒ⧁āύāϰāĻžāϝāĻŧ āϞ⧋āĻĄ āĻšāĻ“āϝāĻŧāĻž āωāϚāĻŋāϤ (āĻ•āĻžāϰāĻŖ āφāĻĒāύāĻŋ āωāĻĒāϰ⧇āϰ `uvicorn` āĻ•āĻŽāĻžāĻ¨ā§āĻĄā§‡ `--reload` āϝ⧋āĻ— āĻ•āϰ⧇āϛ⧇āύ)āĨ¤ - -### āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ āωāĻ¨ā§āύ⧀āϤāĻ•āϰāĻŖ - -āĻāĻ–āύ http://127.0.0.1:8000/docs āĻāĻĄāĻĄā§āϰ⧇āϏ⧇ āϝāĻžāύ. - -- āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋāϟāĻŋ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āωāĻ¨ā§āύ⧀āϤ āĻšāϝ⧇ āϝāĻžāĻŦ⧇, āύāϤ⧁āύ āĻŦāĻĄāĻŋ āϏāĻš: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -- "Try it out" āĻŦāĻžāϟāύ⧇ āϚāĻžāĻĒ⧁āύ, āĻāϟāĻŋ āφāĻĒāύāĻžāϕ⧇ āĻĒ⧇āϰāĻžāĻŽāĻŋāϟāĻžāϰāϗ⧁āϞ⧋ āĻĒā§‚āϰāĻŖ āĻ•āϰāϤ⧇ āĻāĻŦāĻ‚ API āĻāϰ āϏāĻžāĻĨ⧇ āϏāϰāĻžāϏāϰāĻŋ āĻ•ā§āϰāĻŋ⧟āĻž-āĻ•āϞāĻžāĻĒ āĻ•āϰāϤ⧇ āĻĻāĻŋāĻŦ⧇: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -- āϤāĻžāϰāĻĒāϰ⧇ "Execute" āĻŦāĻžāϟāύ⧇ āϚāĻžāĻĒ⧁āύ, āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āφāĻĒāύāĻžāϰ API āĻāϰ āϏāĻžāĻĨ⧇ āϝ⧋āĻ—āĻžāϝ⧋āĻ— āĻ•āϰāĻŦ⧇, āĻĒ⧇āϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻĒāĻžāĻ āĻžāĻŦ⧇, āĻĢāϞāĻžāĻĢāϞāϗ⧁āϞāĻŋ āĻĒāĻžāĻŦ⧇ āĻāĻŦāĻ‚ āϏ⧇āϗ⧁āϞāĻŋ āĻĒāĻ°ā§āϰāĻĻāĻžā§Ÿ āĻĻ⧇āĻ–āĻžāĻŦ⧇: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ āφāĻĒāĻ—ā§āϰ⧇āĻĄ - -āĻāĻŦāĻ‚ āĻāĻ–āύ http://127.0.0.1:8000/redoc āĻ āϝāĻžāύāĨ¤ - -- āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋāϤ⧇āĻ“ āύāϤ⧁āύ āĻ•ā§ā§Ÿā§‡āϰāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻāĻŦāĻ‚ āĻŦāĻĄāĻŋ āĻĒā§āϰāϤāĻŋāĻĢāϞāĻŋāϤ āĻšāĻŦ⧇: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤāĻ•āϰāĻŖ - -āϏāĻ‚āĻ•ā§āώ⧇āĻĒ⧇, āφāĻĒāύāĻŋ **āĻļ⧁āϧ⧁ āĻāĻ•āĻŦāĻžāϰ** āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ⧇āϰ āϧāϰāύ, āĻŦāĻĄāĻŋ āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧇āύāĨ¤ - -āφāĻĒāύāĻŋ āϏ⧇āϟāĻŋ āφāϧ⧁āύāĻŋāĻ• āĻĒāĻžāχāĻĨāύ⧇āϰ āϏāĻžāĻĨ⧇ āĻ•āϰ⧇āύāĨ¤ - -āφāĻĒāύāĻžāϕ⧇ āύāϤ⧁āύ āĻ•āϰ⧇ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϕ⧋āύ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āĻŦāĻžāĻ•ā§āϝ āĻ—āĻ āύ, āĻĢāĻžāĻ‚āĻļāύ āĻŦāĻž āĻ•ā§āϞāĻžāϏ āĻ•āĻŋāϛ⧁āχ āĻļāĻŋāĻ–āϤ⧇ āĻšāĻšā§āϛ⧇ āύāĻžāĨ¤ - -āĻļ⧁āϧ⧁āχ āφāϧ⧁āύāĻŋāĻ• **Python 3.6+** - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, `int` āĻāϰ āϜāĻ¨ā§āϝ: - -```Python -item_id: int -``` - -āĻ…āĻĨāĻŦāĻž āφāϰāĻ“ āϜāϟāĻŋāϞ `Item` āĻŽāĻĄā§‡āϞ⧇āϰ āϜāĻ¨ā§āϝ: - -```Python -item: Item -``` - -...āĻāĻŦāĻ‚ āϏ⧇āχ āĻāĻ•āχ āĻ˜ā§‹āώāĻŖāĻžāϰ āϏāĻžāĻĨ⧇ āφāĻĒāύāĻŋ āĻĒāĻžāĻŦ⧇āύ: - -- āĻāĻĄāĻŋāϟāϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ, āϝ⧇āĻŽāύ - - āϏāĻŽāĻžāĻĒā§āϤāĻŋāĨ¤ - - āϧāϰāĻŖ āϝāĻžāϚāĻžāχ -- āϤāĻĨā§āϝ āϝāĻžāϚāĻžāχāĻ•āϰāĻŖ: - - āĻĄā§‡āϟāĻž āĻ…āĻŦ⧈āϧ āĻšāϞ⧇ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻāĻŦāĻ‚ āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻ¤ā§āϰ⧁āϟāĻŋāϰ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāύāĻžāĨ¤ - - āĻāĻŽāύāĻ•āĻŋ āĻ—āĻ­ā§€āϰāĻ­āĻžāĻŦ⧇ āύ⧇āĻ¸ā§āϟ āĻ•āϰāĻž JSON āĻ…āĻŦāĻœā§‡āĻ•ā§āĻŸā§‡āϰ āϜāĻ¨ā§āϝ āĻŦ⧈āϧāϤāĻžāĨ¤ -- āĻĒā§āϰ⧇āϰāĻŋāϤ āϤāĻĨā§āϝ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ: āϝāĻž āύ⧇āϟāĻ“ā§ŸāĻžāĻ°ā§āĻ• āĻĨ⧇āϕ⧇ āĻĒāĻžāχāĻĨāύ⧇āϰ āϤāĻĨā§āϝ āĻāĻŦāĻ‚ āϧāϰāύ⧇ āφāϏ⧇, āĻāĻŦāĻ‚ āϏ⧇āĻ–āĻžāύ āĻĨ⧇āϕ⧇ āĻĒ⧜āĻž: - - - JSONāĨ¤ - - āĻĒāĻžāĻĨ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāĨ¤ - - āĻ•ā§ā§Ÿā§‡āϰāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāĨ¤ - - āϕ⧁āĻ•āĻŋāϜ - - āĻšā§‡āĻĄāĻžāϰ - - āĻĢāĻ°ā§āĻŽ - - āĻĢāĻžāχāϞ - -- āφāωāϟāĻĒ⧁āϟ āĻĄā§‡āϟāĻžāϰ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ: āĻĒāĻžāχāĻĨāύ āĻĄā§‡āϟāĻž āĻāĻŦāĻ‚ āϟāĻžāχāĻĒ āĻĨ⧇āϕ⧇ āύ⧇āϟāĻ“āϝāĻŧāĻžāĻ°ā§āĻ• āĻĄā§‡āϟāĻžāϤ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰāĻž (JSON āĻšāĻŋāϏāĻžāĻŦ⧇): - -āĻĒāĻžāχāĻĨāύ āϟāĻžāχāĻĒ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰ⧁āύ (`str`, `int`, `float`, `bool`, `list`, āχāĻ¤ā§āϝāĻžāĻĻāĻŋ)āĨ¤ - - `datetime` āĻ…āĻŦāĻœā§‡āĻ•ā§āϟāĨ¤ - - `UUID` objeāĻ…āĻŦāĻœā§‡āĻ•ā§āϟctsāĨ¤ - - āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŽāĻĄā§‡āϞāĨ¤ - - ...āĻāĻŦāĻ‚ āφāϰ⧋ āĻ…āύ⧇āĻ•āĨ¤ -- āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ API āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ, 2āϟāĻŋ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āϏāĻš: - - āϏ⧋āϝāĻŧāĻžāĻ—āĻžāϰ āχāω āφāχ (Swagger UI)āĨ¤ - - āϰāĻŋāĻĄāĻ• (ReDoc)āĨ¤ - ---- - -āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āϤ⧀ āϕ⧋āĻĄ āωāĻĻāĻžāĻšāϰāϪ⧇ āĻĢāĻŋāϰ⧇ āφāϏāĻž āϝāĻžāĻ•, **FastAPI** āϝāĻž āĻ•āϰāĻŦ⧇: - -- `GET` āĻāĻŦāĻ‚ `PUT` āĻ…āύ⧁āϰ⧋āϧ⧇āϰ āϜāĻ¨ā§āϝ āĻĒāĻĨ⧇ `item_id` āφāϛ⧇ āĻ•āĻŋāύāĻž āϤāĻž āϝāĻžāϚāĻžāχ āĻ•āϰāĻŦ⧇āĨ¤ -- `GET` āĻāĻŦāĻ‚ `PUT` āĻ…āύ⧁āϰ⧋āϧ⧇āϰ āϜāĻ¨ā§āϝ `item_id` āϟāĻžāχāĻĒ `int` āĻāϰ āĻšāϤ⧇ āĻšāĻŦ⧇ āϤāĻž āϝāĻžāϚāĻžāχ āĻ•āϰāĻŦ⧇āĨ¤ - - āϝāĻĻāĻŋ āύāĻž āĻšāϝāĻŧ āϤāĻŦ⧇ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āĻāĻ•āϟāĻŋ āωāĻĒāϝ⧁āĻ•ā§āϤ, āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύāĨ¤ -- `GET` āĻ…āύ⧁āϰ⧋āϧ⧇āϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ• āĻ•ā§āϝ⧁āϝāĻŧ⧇āϰāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āύāĻžāĻŽāĻ• `q` (āϝ⧇āĻŽāύ `http://127.0.0.1:8000/items/foo?q=somequery`) āφāϛ⧇ āĻ•āĻŋ āϤāĻž āĻšā§‡āĻ• āĻ•āϰāĻŦ⧇āĨ¤ - - āϝ⧇āĻšā§‡āϤ⧁ `q` āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϟāĻŋ `= None` āĻĻāĻŋāϝāĻŧ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇, āϤāĻžāχ āĻāϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ•āĨ¤ - - `None` āĻ›āĻžāĻĄāĻŧāĻž āĻāϟāĻŋ āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āĻšāϤ⧋ (āϝ⧇āĻŽāύ `PUT` āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻšā§Ÿā§‡āϛ⧇)āĨ¤ -- `/items/{item_id}` āĻāϰ āϜāĻ¨ā§āϝ `PUT` āĻ…āύ⧁āϰ⧋āϧ⧇āϰ āĻŦāĻĄāĻŋ JSON āĻšāĻŋāϏāĻžāĻŦ⧇ āĻĒāĻĄāĻŧ⧁āύ: - - āϞāĻ•ā§āώ āĻ•āϰ⧁āύ, `name` āĻāĻ•āϟāĻŋ āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āĻ…ā§āϝāĻžāĻŸā§āϰāĻŋāĻŦāĻŋāωāϟ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻŦāĻŋāĻŦ⧇āϚāύāĻž āĻ•āϰ⧇āϛ⧇ āĻāĻŦāĻ‚ āĻāϟāĻŋ `str` āĻšāϤ⧇ āĻšāĻŦ⧇āĨ¤ - - āϞāĻ•ā§āώ āĻ•āϰ⧁āύ āĻāĻ–āĻžāύ⧇, `price` āĻ…ā§āϝāĻžāĻŸā§āϰāĻŋāĻŦāĻŋāωāϟāϟāĻŋ āφāĻŦāĻļā§āϝāĻ• āĻāĻŦāĻ‚ āĻāϟāĻŋ `float` āĻšāϤ⧇ āĻšāĻŦ⧇āĨ¤ - - āϞāĻ•ā§āώ āĻ•āϰ⧁āύ `is_offer` āĻāĻ•āϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ• āĻ…ā§āϝāĻžāĻŸā§āϰāĻŋāĻŦāĻŋāωāϟ āĻāĻŦāĻ‚ āĻāϟāĻŋ `bool` āĻšāϤ⧇ āĻšāĻŦ⧇ āϝāĻĻāĻŋ āωāĻĒāĻ¸ā§āĻĨāĻŋāϤ āĻĨāĻžāϕ⧇āĨ¤ - - āĻāχ āϏāĻŦāϟāĻŋ āĻ—āĻ­ā§€āϰāĻ­āĻžāĻŦ⧇ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύāϰāϤ JSON āĻ…āĻŦāĻœā§‡āĻ•ā§āϟāϗ⧁āϞāĻŋāϤ⧇āĻ“ āĻ•āĻžāϜ āĻ•āϰāĻŦ⧇āĨ¤ -- āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ JSON āĻšāϤ⧇ āĻāĻŦāĻ‚ JSON āĻĨ⧇āϕ⧇ āĻ•āύāĻ­āĻžāĻ°ā§āϟ āĻ•āϰ⧁āύāĨ¤ -- OpenAPI āĻĻāĻŋāϝāĻŧ⧇ āϏāĻŦāĻ•āĻŋāϛ⧁ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āϟ āĻ•āϰ⧁āύ, āϝāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇: - - āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋāĨ¤ - - āĻ…āύ⧇āĻ• āĻ­āĻžāώāĻžāϰ āϜāĻ¨ā§āϝ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āϕ⧋āĻĄ āϤ⧈āϰāĻŋāϰ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĨ¤ -- āϏāϰāĻžāϏāϰāĻŋ 2āϟāĻŋ āĻ•ā§āϰāĻŋ⧟āĻžāĻļā§€āϞ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āύāĻĨāĻŋ āĻ“āϝāĻŧ⧇āĻŦ āĻĒ⧃āĻˇā§āĻ  āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤ - ---- - -āφāĻŽāϰāĻž āĻāϤāĻ•ā§āώāύ āĻļ⧁āϧ⧁ āĻāϰ āĻĒ⧃āĻˇā§āĻ  āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĻ›āĻŋ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻĒāύāĻŋ āχāϤāĻŽāĻ§ā§āϝ⧇āχ āĻāϟāĻŋ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇ āϤāĻžāϰ āϧāĻžāϰāĻŖāĻžāĻ“ āĻĒā§‡ā§Ÿā§‡ āĻ—āĻŋā§Ÿā§‡āϛ⧇āύāĨ¤ - -āύāĻŋāĻŽā§āύ⧋āĻ•ā§āϤ āϞāĻžāχāύ āϗ⧁āϞ⧋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧁āύ: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...āĻĒ⧁āĻ°ā§āĻŦ⧇: - -```Python - ... "item_name": item.name ... -``` - -...āĻĒāϰāĻŦāĻ°ā§āϤ⧀āϤ⧇: - -```Python - ... "item_price": item.price ... -``` - -...āĻāĻŦāĻ‚ āĻĻ⧇āϖ⧁āύ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āφāĻĒāύāĻžāϰ āĻāĻĄāĻŋāϟāϰ āωāĻĒāĻžāĻĻāĻžāύāϗ⧁āϞ⧋āϕ⧇ āϏ⧟āĻ‚āĻ•ā§āϰāĻŋ⧟āĻ­āĻžāĻŦ⧇-āϏāĻŽā§āĻĒāĻ¨ā§āύ āĻ•āϰāĻŦ⧇ āĻāĻŦāĻ‚ āϤāĻžāĻĻ⧇āϰ āϧāϰāύ āϜāĻžāύāϤ⧇ āĻĒāĻžāϰāĻŦ⧇: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -āφāϰāĻ“ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϏāĻŽā§āĻĒāĻ¨ā§āύ āωāĻĻāĻžāĻšāϰāϪ⧇āϰ āϜāĻ¨ā§āϝ, āĻĻ⧇āϖ⧁āύ āϟāĻŋāωāĻŸā§‹āϰāĻŋ⧟āĻžāϞ - āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻ—āĻžāχāĻĄ. - -**āĻ¸ā§āĻĒ⧟āϞāĻžāϰ āϏāϤāĻ°ā§āĻ•āϤāĻž**: āϟāĻŋāωāĻŸā§‹āϰāĻŋ⧟āĻžāϞ - āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻ—āĻžāχāĻĄ āύāĻŋāĻŽā§āύ⧋āĻ•ā§āϤ āĻŦāĻŋāώ⧟āϗ⧁āϞāĻŋ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āĻ•āϰ⧇: - -- **āĻšā§‡āĻĄāĻžāϰ**, **āϕ⧁āĻ•āĻŋāϜ**, **āĻĢāĻ°ā§āĻŽ āĻĢāĻŋāĻ˛ā§āĻĄ** āĻāĻŦāĻ‚ **āĻĢāĻžāχāϞāϗ⧁āϞāĻŋ** āĻāĻŽāύ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āϜāĻžā§ŸāĻ—āĻž āĻĨ⧇āϕ⧇ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻžāĨ¤ -- `maximum_length` āĻŦāĻž `regex` āĻāϰ āĻŽāϤ⧋ **āϝāĻžāϚāĻžāχāĻ•āϰāĻŖ āĻŦāĻžāϧāĻžāĻŽā§āĻ•ā§āϤāĻŋ** āϏ⧇āϟ āĻ•āϰāĻž āĻšāϝāĻŧ āĻ•āĻŋāĻ­āĻžāĻŦ⧇, āϤāĻž āύāĻŋā§Ÿā§‡ āφāϞ⧋āϚāύāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤ -- āĻāĻ•āϟāĻŋ āϖ⧁āĻŦ āĻļāĻ•ā§āϤāĻŋāĻļāĻžāϞ⧀ āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϏāĻšāϜ āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋ āχāύāĻœā§‡āĻ•āĻļāύ āĻĒāĻĻā§āϧāϤāĻŋ -- **OAuth2** āĻāĻŦāĻ‚ **JWT āĻŸā§‹āϕ⧇āύ** āĻāĻŦāĻ‚ **HTTP Basic** auth āϏāĻš āύāĻŋāϰāĻžāĻĒāĻ¤ā§āϤāĻž āĻāĻŦāĻ‚ āĻ…āύ⧁āĻŽā§‹āĻĻāύāĻĒā§āϰāĻžāĻĒā§āϤāĻŋ āϏāĻŽā§āĻĒāĻ°ā§āĻ•āĻŋāϤ āĻŦāĻŋāώ⧟āϏāĻŽā§‚āĻšā§‡āϰ āωāĻĒāϰāĨ¤ -- **āĻ—āĻ­ā§€āϰāĻ­āĻžāĻŦ⧇ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύāϰāϤ JSON āĻŽāĻĄā§‡āϞ** āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāϰāĻ“ āωāĻ¨ā§āύāϤ (āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏāĻŽāĻžāύ āϏāĻšāϜ) āĻ•ā§ŒāĻļāϞ (Pydantic āϕ⧇ āϧāĻ¨ā§āϝāĻŦāĻžāĻĻ)āĨ¤ -- āφāϰ⧋ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ (āĻ¸ā§āϟāĻžāϰāϞ⧇āϟāϕ⧇ āϧāĻ¨ā§āϝāĻŦāĻžāĻĻ) āĻšāĻŋāϏāĻžāĻŦ⧇: - - **WebSockets** - - **GraphQL** - - HTTPX āĻāĻŦāĻ‚ `pytest` āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ• āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āϏāĻšāϜ āĻĒāϰ⧀āĻ•ā§āώāĻž - - **CORS** - - **Cookie Sessions** - - ...āĻāĻŦāĻ‚ āφāϰ⧋āĨ¤ - -## āĻ•āĻ°ā§āĻŽāĻ•ā§āώāĻŽāϤāĻž - -āĻ¸ā§āĻŦāĻžāϧ⧀āύ TechEmpower Benchmarks āĻĻ⧇āĻ–āĻžāϝāĻŧ āϝ⧇ **FastAPI** āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϗ⧁āϞāĻŋ Uvicorn-āĻāϰ āĻ…āϧ⧀āύ⧇ āϚāϞāĻŽāĻžāύ āĻĻā§āϰ⧁āϤāϤāĻŽāĻĒāĻžāχāĻĨāύ āĻĢā§āϰ⧇āĻŽāĻ“āϝāĻŧāĻžāĻ°ā§āĻ•āϗ⧁āϞāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻŋ, āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ Starlette āĻāĻŦāĻ‚ Uvicorn-āĻāϰ āĻĒāϰ (FastAPI āĻĻā§āĻŦāĻžāϰāĻž āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖāĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ)āĨ¤ (\*) - -āĻāϟāĻŋ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āĻŦ⧁āĻāϤ⧇, āĻĻ⧇āϖ⧁āύ Benchmarks. - -## āϐāĻšā§āĻ›āĻŋāĻ• āύāĻŋāĻ°ā§āĻ­āϰāĻļā§€āϞāϤāĻž - -Pydantic āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšā§ƒāϤ: - -- email-validator - āχāĻŽā§‡āϞ āϝāĻžāϚāĻžāχāĻ•āϰāϪ⧇āϰ āϜāĻ¨ā§āϝāĨ¤ - -āĻ¸ā§āϟāĻžāϰāϞ⧇āϟ āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšā§ƒāϤ: - -- httpx - āφāĻĒāύāĻŋ āϝāĻĻāĻŋ `TestClient` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āϚāĻžāύ āϤāĻžāĻšāϞ⧇ āφāĻŦāĻļā§āϝāĻ•āĨ¤ -- jinja2 - āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻĒā§āϰāĻĻāĻ¤ā§āϤ āĻŸā§‡āĻŽāĻĒā§āϞ⧇āϟ āϰ⧂āĻĒāϰ⧇āĻ–āĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āϚāĻžāύ āϤāĻžāĻšāϞ⧇ āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤ -- python-multipart - āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻĢāĻ°ā§āĻŽ āϏāĻšāĻžāϝāĻŧāϤāĻž āĻ•āϰāϤ⧇ āϚāĻžāύ āϤāĻžāĻšāϞ⧇ āĻĒā§āϰāϝāĻŧā§‹āϜāύ "parsing", `request.form()` āϏāĻšāĨ¤ -- itsdangerous - `SessionMiddleware` āϏāĻšāĻžāϝāĻŧāϤāĻžāϰ āϜāĻ¨ā§āϝ āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤ -- pyyaml - āĻ¸ā§āϟāĻžāϰāϞ⧇āĻŸā§‡āϰ SchemaGenerator āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻāϰ āϜāĻ¨ā§āϝ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ (āφāĻĒāύāĻžāϰ āϏāĻŽā§āĻ­āĻžāĻŦāϤ FastAPI āĻĒā§āϰāϝāĻŧā§‹āϜāύ āύ⧇āχ)āĨ¤ -- graphene - `GraphQLApp` āϏāĻšāĻžāϝāĻŧāϤāĻžāϰ āϜāĻ¨ā§āϝ āĻĒā§āĻ°ā§Ÿā§‹āϜāύāĨ¤ - -FastAPI / Starlette āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšā§ƒāϤ: - -- uvicorn - āϏāĻžāĻ°ā§āĻ­āĻžāϰ⧇āϰ āϜāĻ¨ā§āϝ āϝāĻž āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϞ⧋āĻĄ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āĻĒāϰāĻŋāĻŦ⧇āĻļāύ āĻ•āϰ⧇āĨ¤ -- orjson - āφāĻĒāύāĻŋ `ORJSONResponse` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āϚāĻžāχāϞ⧇ āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤ -- ujson - āφāĻĒāύāĻŋ `UJSONResponse` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āϚāĻžāχāϞ⧇ āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤ - -āφāĻĒāύāĻŋ āĻāχ āϏāĻŦ āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ `pip install fastapi[all]` āĻĻāĻŋā§Ÿā§‡. - -## āϞāĻžāχāϏ⧇āĻ¨ā§āϏ - -āĻāχ āĻĒā§āϰāĻœā§‡āĻ•ā§āϟ MIT āϞāĻžāχāϏ⧇āĻ¨ā§āϏ āύ⧀āϤāĻŋāĻŽāĻžāϞāĻžāϰ āĻ…āϧ⧀āύ⧇ āĻļāĻ°ā§āϤāĻžā§ŸāĻŋāϤāĨ¤ diff --git a/docs/bn/docs/learn/index.md b/docs/bn/docs/learn/index.md deleted file mode 100644 index 4e4c62038..000000000 --- a/docs/bn/docs/learn/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# āĻļāĻŋāϖ⧁āύ - -āĻāĻ–āĻžāύ⧇ **FastAPI** āĻļāĻŋāĻ–āĻžāϰ āϜāĻ¨ā§āϝ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻŦāĻŋāĻ­āĻžāĻ—āϗ⧁āϞāĻŋ āĻāĻŦāĻ‚ āϟāĻŋāωāĻŸā§‹āϰāĻŋāϝāĻŧāĻžāϞāϗ⧁āϞāĻŋ āϰāϝāĻŧ⧇āϛ⧇āĨ¤ - -āφāĻĒāύāĻŋ āĻāϟāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ **āĻŦāχ**, āĻāĻ•āϟāĻŋ **āϕ⧋āĻ°ā§āϏ**, āĻāĻŦāĻ‚ FastAPI āĻļāĻŋāĻ–āĻžāϰ **āĻ…āĻĢāĻŋāϏāĻŋāϝāĻŧāĻžāϞ** āĻāĻŦāĻ‚ āĻĒā§āϰāĻ¸ā§āϤāĻžāĻŦāĻŋāϤ āωāĻĒāĻžāϝāĻŧ āĻŦāĻŋāĻŦ⧇āϚāύāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ 😎 diff --git a/docs/bn/docs/python-types.md b/docs/bn/docs/python-types.md deleted file mode 100644 index d98c2ec87..000000000 --- a/docs/bn/docs/python-types.md +++ /dev/null @@ -1,586 +0,0 @@ -# āĻĒāĻžāχāĻĨāύ āĻāϰ āϟāĻžāχāĻĒā§āϏ āĻĒāϰāĻŋāϚāĻŋāϤāĻŋ - -Python-āĻ āϐāĻšā§āĻ›āĻŋāĻ• "āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ" (āϝāĻž "āϟāĻžāχāĻĒ āĻ…ā§āϝāĻžāύ⧋āĻŸā§‡āĻļāύ" āύāĻžāĻŽā§‡āĻ“ āĻĒāϰāĻŋāϚāĻŋāϤ) āĻāϰ āϜāĻ¨ā§āϝ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āϰāϝāĻŧ⧇āϛ⧇āĨ¤ - -āĻāχ **"āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ"** āĻŦāĻž āĻ…ā§āϝāĻžāύ⧋āĻŸā§‡āĻļāύāϗ⧁āϞāĻŋ āĻāĻ• āϧāϰāϪ⧇āϰ āĻŦāĻŋāĻļ⧇āώ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āϝāĻž āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ⧇āϰ āϟāĻžāχāĻĒ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĻ⧇āϝāĻŧāĨ¤ - -āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āϟāĻžāχāĻĒ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϞ⧇, āĻāĻĄāĻŋāϟāϰ āĻāĻŦāĻ‚ āϟ⧁āϞāϗ⧁āϞāĻŋ āφāĻĒāύāĻžāϕ⧇ āφāϰāĻ“ āĻ­āĻžāϞ⧋ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -āĻāϟāĻŋ āĻĒāĻžāχāĻĨāύ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻāĻ•āϟāĻŋ āĻĻā§āϰ⧁āϤ **āϟāĻŋāωāĻŸā§‹āϰāĻŋāϝāĻŧāĻžāϞ / āϰāĻŋāĻĢā§āϰ⧇āĻļāĻžāϰ** āĻŽāĻžāĻ¤ā§āϰāĨ¤ āĻāϟāĻŋ **FastAPI** āĻāϰ āϏāĻžāĻĨ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ¨ā§āϝ⧂āύāϤāĻŽ āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧāϤāĻž āĻ•āĻ­āĻžāϰ āĻ•āϰ⧇... āϝāĻž āφāϏāϞ⧇ āϖ⧁āĻŦ āĻāĻ•āϟāĻž āĻŦ⧇āĻļāĻŋ āύāĻžāĨ¤ - -**FastAPI** āĻāχ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϗ⧁āϞāĻŋāϰ āωāĻĒāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻ•āϰ⧇ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ, āϝāĻž āĻāϟāĻŋāϕ⧇ āĻ…āύ⧇āĻ• āϏ⧁āĻŦāĻŋāϧāĻž āĻāĻŦāĻ‚ āϞāĻžāĻ­ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤ - -āϤāĻŦ⧇, āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻ•āĻ–āύ⧋ **FastAPI** āĻŦā§āϝāĻŦāĻšāĻžāϰ āύāĻžāĻ“ āĻ•āϰ⧇āύ, āϤāĻŦ⧁āĻ“ āĻāϗ⧁āϞāĻŋ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻāĻ•āϟ⧁ āĻļ⧇āĻ–āĻž āφāĻĒāύāĻžāϰ āωāĻĒāĻ•āĻžāϰ⧇ āφāϏāĻŦ⧇āĨ¤ - -/// note - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āĻāĻ•āϜāύ Python āĻŦāĻŋāĻļ⧇āώāĻœā§āĻž āĻšāύ, āĻāĻŦāĻ‚ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āϏāĻŦāĻ•āĻŋāϛ⧁ āϜāĻžāύ⧇āύ, āϤāĻžāĻšāϞ⧇ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻ…āĻ§ā§āϝāĻžāϝāĻŧ⧇ āϚāϞ⧇ āϝāĻžāύāĨ¤ - -/// - -## āĻĒā§āϰ⧇āϰāĻŖāĻž - -āϚāϞ⧁āύ āĻāĻ•āϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻāĻŋāϝāĻŧ⧇ āĻļ⧁āϰ⧁ āĻ•āϰāĻŋ: - -{* ../../docs_src/python_types/tutorial001.py *} - - -āĻāχ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋ āĻ•āϞ āĻ•āϰāϞ⧇ āφāωāϟāĻĒ⧁āϟ āĻšāϝāĻŧ: - -``` -John Doe -``` - -āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤ āĻ•āĻžāϜ āĻ•āϰ⧇: - -* `first_name` āĻāĻŦāĻ‚ `last_name` āύ⧇āϝāĻŧāĨ¤ -* āĻĒā§āϰāϤāĻŋāϟāĻŋāϰ āĻĒā§āϰāĻĨāĻŽ āĻ…āĻ•ā§āώāϰāϕ⧇ `title()` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻŦāĻĄāĻŧ āĻšāĻžāϤ⧇āϰ āĻ…āĻ•ā§āώāϰ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰ⧇āĨ¤ -* āϤāĻžāĻĻ⧇āϰāϕ⧇ āĻŽāĻžāĻāĻ–āĻžāύ⧇ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻĒ⧇āϏ āĻĻāĻŋāϝāĻŧ⧇ concatenate āĻ•āϰ⧇āĨ¤ - -{* ../../docs_src/python_types/tutorial001.py hl[2] *} - - -### āĻāϟāĻŋ āϏāĻŽā§āĻĒāĻžāĻĻāύāĻž āĻ•āϰ⧁āύ - -āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϖ⧁āĻŦ āϏāĻžāϧāĻžāϰāĻŖ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĨ¤ - -āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ–āύ āĻ•āĻ˛ā§āĻĒāύāĻž āĻ•āϰ⧁āύ āϝ⧇ āφāĻĒāύāĻŋ āĻāϟāĻŋ āĻļ⧁āϰ⧁ āĻĨ⧇āϕ⧇ āϞāĻŋāĻ–āĻ›āĻŋāϞ⧇āύāĨ¤ - -āĻāĻ• āĻĒāĻ°ā§āϝāĻžāϝāĻŧ⧇ āφāĻĒāύāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āϏāĻ‚āĻœā§āĻžāĻž āĻļ⧁āϰ⧁ āĻ•āϰ⧇āĻ›āĻŋāϞ⧇āύ, āφāĻĒāύāĻžāϰ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϗ⧁āϞāĻŋ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ›āĻŋāϞ... - -āĻ•āĻŋāĻ¨ā§āϤ⧁ āϤāĻžāϰāĻĒāϰ āφāĻĒāύāĻžāϕ⧇ "āϏ⧇āχ method āĻ•āϞ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āϝāĻž āĻĒā§āϰāĻĨāĻŽ āĻ…āĻ•ā§āώāϰāϕ⧇ āĻŦāĻĄāĻŧ āĻšāĻžāϤ⧇āϰ āĻ…āĻ•ā§āώāϰ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰ⧇"āĨ¤ - -āĻāϟāĻž āĻ•āĻŋ `upper` āĻ›āĻŋāϞ? āύāĻžāĻ•āĻŋ `uppercase`? `first_uppercase`? `capitalize`? - -āϤāĻžāϰāĻĒāϰ, āφāĻĒāύāĻŋ āĻĒ⧁āϰ⧋āύ⧋ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻžāϰ⧇āϰ āĻŦāĻ¨ā§āϧ⧁, āĻāĻĄāĻŋāϟāϰ āĻ…āĻŸā§‹āĻ•āĻŽāĻĒā§āϞāĻŋāĻļāύ⧇āϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ⧇ āύ⧇āĻ“āϝāĻŧāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇āύāĨ¤ - -āφāĻĒāύāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻĒā§āϰāĻĨāĻŽ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ `first_name` āϟāĻžāχāĻĒ āĻ•āϰ⧇āύ, āϤāĻžāϰāĻĒāϰ āĻāĻ•āϟāĻŋ āĻĄāϟ (`.`) āϟāĻžāχāĻĒ āĻ•āϰ⧇āύ āĻāĻŦāĻ‚ `Ctrl+Space` āϚāĻžāĻĒ⧇āύ āĻ…āĻŸā§‹āĻ•āĻŽāĻĒā§āϞāĻŋāĻļāύ āĻŸā§āϰāĻŋāĻ—āĻžāϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝāĨ¤ - -āĻ•āĻŋāĻ¨ā§āϤ⧁, āĻĻ⧁āĻ°ā§āĻ­āĻžāĻ—ā§āϝāĻŦāĻļāϤ, āφāĻĒāύāĻŋ āĻ•āĻŋāϛ⧁āχ āωāĻĒāϝ⧋āĻ—ā§€ āĻĒāĻžāύ āύāĻž: - - - -### āϟāĻžāχāĻĒ āϝ⧋āĻ— āĻ•āϰ⧁āύ - -āφāϏ⧁āύ āφāϗ⧇āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āϞāĻžāχāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻŋāĨ¤ - -āφāĻŽāϰāĻž āĻ āĻŋāĻ• āĻāχ āĻ…āĻ‚āĻļāϟāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻŦ āĻ…āĻ°ā§āĻĨāĻžā§Ž āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϗ⧁āϞāĻŋ, āĻāχāϗ⧁āϞāĻŋ: - -```Python - first_name, last_name -``` - -āĻĨ⧇āϕ⧇ āĻāχāϗ⧁āϞāĻŋ: - -```Python - first_name: str, last_name: str -``` - -āĻŦā§āϝāĻžāϏāĨ¤ - -āĻāϗ⧁āϞāĻŋāχ "āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ": - -{* ../../docs_src/python_types/tutorial002.py hl[1] *} - - -āĻāϟāĻŋ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻžāϰ āĻŽāϤ āύāϝāĻŧ āϝ⧇āĻŽāύ: - -```Python - first_name="john", last_name="doe" -``` - -āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ­āĻŋāĻ¨ā§āύ āϜāĻŋāύāĻŋāϏāĨ¤ - -āφāĻŽāϰāĻž āϏāĻŽāĻžāύ (`=`) āύāϝāĻŧ, āϕ⧋āϞāύ (`:`) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻ›āĻŋāĨ¤ - -āĻāĻŦāĻ‚ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āϝ⧋āĻ— āĻ•āϰāĻž āϏāĻžāϧāĻžāϰāĻŖāϤ āϤ⧇āĻŽāύ āĻ•āĻŋāϛ⧁ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ āύāĻž āϝāĻž āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āĻ›āĻžāĻĄāĻŧāĻžāχ āϘāϟāϤāĨ¤ - -āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ–āύ, āĻ•āĻ˛ā§āĻĒāύāĻž āĻ•āϰ⧁āύ āφāĻĒāύāĻŋ āφāĻŦāĻžāϰ āϏ⧇āχ āĻĢāĻžāĻ‚āĻļāύ āϤ⧈āϰāĻŋāϰ āĻŽāĻžāĻāĻ–āĻžāύ⧇ āφāϛ⧇āύ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āϏāĻšāĨ¤ - -āĻāĻ•āχ āĻĒāĻ°ā§āϝāĻžāϝāĻŧ⧇, āφāĻĒāύāĻŋ āĻ…āĻŸā§‹āĻ•āĻŽāĻĒā§āϞāĻŋāϟ āĻŸā§āϰāĻŋāĻ—āĻžāϰ āĻ•āϰāϤ⧇ `Ctrl+Space` āϚāĻžāĻĒ⧇āύ āĻāĻŦāĻ‚ āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāύ: - - - -āĻāϰ āϏāĻžāĻĨ⧇, āφāĻĒāύāĻŋ āĻ…āĻĒāĻļāύāϗ⧁āϞāĻŋ āĻĻ⧇āϖ⧇, āĻ¸ā§āĻ•ā§āϰāϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āϝāϤāĻ•ā§āώāĻŖ āύāĻž āφāĻĒāύāĻŋ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āĻ…āĻĒāĻļāύ āϖ⧁āρāĻœā§‡ āĻĒāĻžāύ āϝāĻž āĻ•āĻŋāϛ⧁ āĻŽāύ⧇ āĻĒāϰāĻŋāϝāĻŧ⧇ āĻĻ⧇āϝāĻŧ: - - - -## āφāϰāĻ“ āĻĒā§āϰ⧇āϰāĻŖāĻž - -āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻĻ⧇āϖ⧁āύ, āĻāϟāĻŋāϤ⧇ āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āϰāϝāĻŧ⧇āϛ⧇: - -{* ../../docs_src/python_types/tutorial003.py hl[1] *} - - -āĻāĻĄāĻŋāϟāϰ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞāĻŋāϰ āϟāĻžāχāĻĒ āϜāĻžāύāĻžāϰ āĻ•āĻžāϰāϪ⧇, āφāĻĒāύāĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ…āĻŸā§‹āĻ•āĻŽāĻĒā§āϞāĻŋāĻļāύāχ āĻĒāĻžāύ āύāĻž, āφāĻĒāύāĻŋ āĻāϰāϰ āĻšā§‡āĻ•āĻ“ āĻĒāĻžāύ: - - - -āĻāĻ–āύ āφāĻĒāύāĻŋ āϜāĻžāύ⧇āύ āϝ⧇ āφāĻĒāύāĻžāϕ⧇ āĻāϟāĻŋ āĻ āĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇, `age`-āϕ⧇ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āĻšāĻŋāϏ⧇āĻŦ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰāϤ⧇ `str(age)` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇: - -{* ../../docs_src/python_types/tutorial004.py hl[2] *} - - -## āϟāĻžāχāĻĒ āĻ˜ā§‹āώāĻŖāĻž - -āφāĻĒāύāĻŋ āĻāϤāĻ•ā§āώāύ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻžāϰ āĻŽā§‚āϞ āĻ¸ā§āĻĨāĻžāύāϟāĻŋ āĻĻ⧇āϖ⧇ āĻĢ⧇āϞ⧇āϛ⧇āύ-- āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻšāĻŋāϏ⧇āĻŦ⧇āĨ¤ - -āϏāĻžāϧāĻžāϰāĻŖāϤ āĻāϟāĻŋ **FastAPI** āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āĻ“ āĻāĻ•āχāĨ¤ - -### āϏāĻŋāĻŽā§āĻĒāϞ āϟāĻžāχāĻĒ - -āφāĻĒāύāĻŋ `str` āĻ›āĻžāĻĄāĻŧāĻžāĻ“ āϏāĻŽāĻ¸ā§āϤ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āĻĒāĻžāχāĻĨāύ āϟāĻžāχāĻĒ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āφāĻĒāύāĻŋ āĻāϗ⧁āϞ⧋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ: - -* `int` -* `float` -* `bool` -* `bytes` - -{* ../../docs_src/python_types/tutorial005.py hl[1] *} - - -### āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āϏāĻš āĻœā§‡āύ⧇āϰāĻŋāĻ• āϟāĻžāχāĻĒ - -āĻ•āĻŋāϛ⧁ āĻĄāĻžāϟāĻž āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻŽāĻžāύ āϧāĻžāϰāĻŖ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇, āϝ⧇āĻŽāύ `dict`, `list`, `set` āĻāĻŦāĻ‚ `tuple`āĨ¤ āĻāĻŦāĻ‚ āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖ āĻŽāĻžāύāϗ⧁āϞ⧋āϰāĻ“ āύāĻŋāĻœā§‡āĻĻ⧇āϰ āϟāĻžāχāĻĒ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -āĻāχ āϧāϰāύ⧇āϰ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋāϕ⧇ āĻŦāϞāĻž āĻšāϝāĻŧ "**āĻœā§‡āύ⧇āϰāĻŋāĻ•**" āϟāĻžāχāĻĒ āĻāĻŦāĻ‚ āĻāϗ⧁āϞāĻŋāϕ⧇ āϤāĻžāĻĻ⧇āϰ āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āϏāĻš āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻž āϏāĻŽā§āĻ­āĻŦāĨ¤ - -āĻāχ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āĻāĻŦāĻ‚ āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇, āφāĻĒāύāĻŋ Python āĻŽāĻĄāĻŋāωāϞ `typing` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻāϟāĻŋ āĻŦāĻŋāĻļ⧇āώāĻ­āĻžāĻŦ⧇ āĻāχ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϗ⧁āϞāĻŋ āϏāĻŽāĻ°ā§āĻĨāύ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϰāϝāĻŧ⧇āϛ⧇āĨ¤ - -#### Python āĻāϰ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ - -`typing` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏāϟāĻŋ Python 3.6 āĻĨ⧇āϕ⧇ āϏāĻ°ā§āĻŦāĻļ⧇āώ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ, āĻ…āĻ°ā§āĻĨāĻžā§Ž Python 3.9, Python 3.10 āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āϏāĻš āϏāĻ•āϞ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āϏāĻžāĻĨ⧇ **āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ**āĨ¤ - -Python āϝāϤ āĻāĻ—āĻŋāϝāĻŧ⧇ āϝāĻžāĻšā§āϛ⧇, **āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋ** āĻāχ āϟāĻžāχāĻĒ āĻ…ā§āϝāĻžāύ⧋āĻŸā§‡āĻļāύāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āϤāϤ āωāĻ¨ā§āύāϤ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āύāĻŋāϝāĻŧ⧇ āφāϏāϛ⧇ āĻāĻŦāĻ‚ āĻ…āύ⧇āĻ• āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āφāĻĒāύāĻžāϕ⧇ āϟāĻžāχāĻĒ āĻ…ā§āϝāĻžāύ⧋āĻŸā§‡āĻļāύ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ `typing` āĻŽāĻĄāĻŋāωāϞ āχāĻŽā§āĻĒā§‹āĻ°ā§āϟ āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻšāĻŦ⧇ āύāĻžāĨ¤ - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻœā§‡āĻ•ā§āĻŸā§‡āϰ āϜāĻ¨ā§āϝ Python-āĻāϰ āφāϰāĻ“ āϏāĻžāĻŽā§āĻĒā§āϰāϤāĻŋāĻ• āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āϤāĻžāĻšāϞ⧇ āφāĻĒāύāĻŋ āϏ⧇āχ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āϏāϰāϞāϤāĻž āĻĨ⧇āϕ⧇ āϏ⧁āĻŦāĻŋāϧāĻž āύāĻŋāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύāĨ¤ - -āĻĄāĻ•ā§āϏ⧇ āϰāϝāĻŧ⧇āϛ⧇ Python-āĻāϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āωāĻĻāĻžāĻšāϰāĻŖāϗ⧁āϞāĻŋ (āϝāĻ–āύ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āφāϛ⧇)āĨ¤ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, "**Python 3.6+**" āĻŽāĻžāύ⧇ āĻāϟāĻŋ Python 3.6 āĻŦāĻž āϤāĻžāϰ āωāĻĒāϰ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ (āϝāĻžāϰ āĻŽāĻ§ā§āϝ⧇ 3.7, 3.8, 3.9, 3.10, āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ)āĨ¤ āĻāĻŦāĻ‚ "**Python 3.9+**" āĻŽāĻžāύ⧇ āĻāϟāĻŋ Python 3.9 āĻŦāĻž āϤāĻžāϰ āωāĻĒāϰ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ (āϝāĻžāϰ āĻŽāĻ§ā§āϝ⧇ 3.10, āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ)āĨ¤ - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ Python-āĻāϰ **āϏāĻ°ā§āĻŦāĻļ⧇āώ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ**, āϤāĻžāĻšāϞ⧇ āϏāĻ°ā§āĻŦāĻļ⧇āώ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āϜāĻ¨ā§āϝ āωāĻĻāĻžāĻšāϰāĻŖāϗ⧁āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ, āϏ⧇āϗ⧁āϞāĻŋ āφāĻĒāύāĻžāϕ⧇ **āϏāĻ°ā§āĻŦā§‹āĻ¤ā§āϤāĻŽ āĻāĻŦāĻ‚ āϏāĻšāϜāϤāĻŽ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ** āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰāĻŦ⧇, āϝ⧇āĻŽāύ, "**Python 3.10+**"āĨ¤ - -#### āϞāĻŋāĻ¸ā§āϟ - -āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϕ⧇ `str`-āĻāϰ āĻāĻ•āϟāĻŋ `list` āĻšāĻŋāϏ⧇āĻŦ⧇ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻ•āϰāĻž āϝāĻžāĻ•āĨ¤ - -//// tab | Python 3.9+ - -āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϟāĻŋ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧁āύ, āĻāĻ•āχ āϕ⧋āϞāύ (`:`) āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĨ¤ - -āϟāĻžāχāĻĒ āĻšāĻŋāϏ⧇āĻŦ⧇, `list` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤ - -āϝ⧇āĻšā§‡āϤ⧁ āϞāĻŋāĻ¸ā§āϟ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āϟāĻžāχāĻĒ āϝāĻž āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āϧāĻžāϰāĻŖ āĻ•āϰ⧇, āφāĻĒāύāĻŋ āϤāĻžāĻĻ⧇āϰ āĻ¸ā§āϕ⧋āϝāĻŧāĻžāϰ āĻŦā§āϰāĻžāϕ⧇āĻŸā§‡āϰ āĻ­āĻŋāϤāϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ: - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -`typing` āĻĨ⧇āϕ⧇ `List` (āĻŦāĻĄāĻŧ āĻšāĻžāϤ⧇āϰ `L` āĻĻāĻŋāϝāĻŧ⧇) āχāĻŽāĻĒā§‹āĻ°ā§āϟ āĻ•āϰ⧁āύ: - -``` Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϟāĻŋ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧁āύ, āĻāĻ•āχ āϕ⧋āϞāύ (`:`) āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĨ¤ - -āϟāĻžāχāĻĒ āĻšāĻŋāϏ⧇āĻŦ⧇, `typing` āĻĨ⧇āϕ⧇ āφāĻĒāύāĻžāϰ āχāĻŽā§āĻĒā§‹āĻ°ā§āϟ āĻ•āϰāĻž `List` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤ - -āϝ⧇āĻšā§‡āϤ⧁ āϞāĻŋāĻ¸ā§āϟ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āϟāĻžāχāĻĒ āϝāĻž āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āϧāĻžāϰāĻŖ āĻ•āϰ⧇, āφāĻĒāύāĻŋ āϤāĻžāĻĻ⧇āϰ āĻ¸ā§āϕ⧋āϝāĻŧāĻžāϰ āĻŦā§āϰāĻžāϕ⧇āĻŸā§‡āϰ āĻ­āĻŋāϤāϰ⧇ āĻ•āϰ⧁āύ: - -```Python hl_lines="4" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -//// - -/// info - -āĻ¸ā§āϕ⧋āϝāĻŧāĻžāϰ āĻŦā§āϰāĻžāϕ⧇āϟ āĻāϰ āĻ­āĻŋāϤāϰ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻāχāϏāĻŦ āĻ…āĻ­āĻ¨ā§āϤāϰ⧀āύ āϟāĻžāχāĻĒāϗ⧁āϞ⧋āϕ⧇ "āχāĻ¨ā§āϟāĻžāϰāύāĻžāϞ āϟāĻžāχāĻĒ" āĻŦāϞ⧇āĨ¤ - -āĻāχ āωāĻĻāĻžāĻšāϰāϪ⧇, āĻāϟāĻŋ āĻšāĻšā§āϛ⧇ `List`(āĻ…āĻĨāĻŦāĻž āĻĒāĻžāχāĻĨāύ ā§Š.⧝ āĻŦāĻž āϤāĻžāϰ āωāĻĒāϰ⧇āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ `list`) āĻ āĻĒāĻžāϏ āĻ•āϰāĻž āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāĨ¤ - -/// - -āĻāϰ āĻ…āĻ°ā§āĻĨ āĻšāĻšā§āϛ⧇: "āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ `items` āĻāĻ•āϟāĻŋ `list`, āĻāĻŦāĻ‚ āĻāχ āϞāĻŋāĻ¸ā§āĻŸā§‡āϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ āφāχāĻŸā§‡āĻŽ āĻāĻ•āϟāĻŋ `str`āĨ¤" - -/// tip - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ Python 3.9 āĻŦāĻž āϤāĻžāϰ āωāĻĒāϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ, āφāĻĒāύāĻžāϰ `typing` āĻĨ⧇āϕ⧇ `List` āφāĻŽāĻĻāĻžāύāĻŋ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āύāĻž, āφāĻĒāύāĻŋ āϏāĻžāϧāĻžāϰāĻŖ `list` āĻ“āχ āϟāĻžāχāĻĒ⧇āϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -/// - -āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡, āφāĻĒāύāĻžāϰ āĻāĻĄāĻŋāϟāϰ āϞāĻŋāĻ¸ā§āϟ āĻĨ⧇āϕ⧇ āφāχāĻŸā§‡āĻŽ āĻĒā§āϰāϏ⧇āϏ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇: - - - -āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āĻ›āĻžāĻĄāĻŧāĻž, āĻāϟāĻŋ āĻ•āϰāĻž āĻĒā§āϰāĻžāϝāĻŧ āĻ…āϏāĻŽā§āĻ­āĻŦāĨ¤ - -āϞāĻ•ā§āĻˇā§āϝ āĻ•āϰ⧁āύ āϝ⧇ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ `item` āĻšāϞ `items` āϞāĻŋāĻ¸ā§āĻŸā§‡āϰ āĻāĻ•āϟāĻŋ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āϟāĨ¤ - -āϤāĻŦ⧁āĻ“, āĻāĻĄāĻŋāϟāϰ āϜāĻžāύ⧇ āϝ⧇ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ `str`, āĻāĻŦāĻ‚ āϤāĻžāϰ āϜāĻ¨ā§āϝ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤ - -#### āϟāĻžāĻĒāϞ āĻāĻŦāĻ‚ āϏ⧇āϟ - -āφāĻĒāύāĻŋ `tuple` āĻāĻŦāĻ‚ `set` āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻāĻ•āχ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰāĻŦ⧇āύ: - -//// tab | Python 3.9+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial007_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial007.py!} -``` - -//// - -āĻāϰ āĻŽāĻžāύ⧇ āĻšāϞ: - -* āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ `items_t` āĻšāϞ āĻāĻ•āϟāĻŋ `tuple` āϝāĻž ā§ŠāϟāĻŋ āφāχāĻŸā§‡āĻŽ āϧāĻžāϰāĻŖ āĻ•āϰ⧇, āĻāĻ•āϟāĻŋ `int`, āĻ…āĻ¨ā§āϝ āĻāĻ•āϟāĻŋ `int`, āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ `str`āĨ¤ -* āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ `items_s` āĻšāϞ āĻāĻ•āϟāĻŋ `set`, āĻāĻŦāĻ‚ āĻāϰ āĻĒā§āϰāϤāĻŋāϟāĻŋ āφāχāĻŸā§‡āĻŽ āĻšāϞ `bytes` āϟāĻžāχāĻĒ⧇āϰāĨ¤ - -#### āĻĄāĻŋāĻ•ā§āϟ - -āĻāĻ•āϟāĻŋ `dict` āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻ•āϰāϤ⧇, āφāĻĒāύāĻŋ ⧍āϟāĻŋ āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻ•āĻŽāĻž āĻĻā§āĻŦāĻžāϰāĻž āĻĒ⧃āĻĨāĻ• āĻ•āϰ⧇ āĻĻ⧇āĻŦ⧇āύāĨ¤ - -āĻĒā§āϰāĻĨāĻŽ āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϟāĻŋ āĻšāϞ `dict`-āĻāϰ āϕ⧀āϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝāĨ¤ - -āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϟāĻŋ āĻšāϞ `dict`-āĻāϰ āĻŽāĻžāύāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ: - -//// tab | Python 3.9+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial008_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008.py!} -``` - -//// - -āĻāϰ āĻŽāĻžāύ⧇ āĻšāϞ: - -* āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ `prices` āĻšāϞ āĻāĻ•āϟāĻŋ `dict`: - * āĻāχ `dict`-āĻāϰ āϕ⧀āϗ⧁āϞāĻŋ āĻšāϞ `str` āϟāĻžāχāĻĒ⧇āϰ (āϧāϰāĻž āϝāĻžāĻ•, āĻĒā§āϰāϤāĻŋāϟāĻŋ āφāχāĻŸā§‡āĻŽā§‡āϰ āύāĻžāĻŽ)āĨ¤ - * āĻāχ `dict`-āĻāϰ āĻŽāĻžāύāϗ⧁āϞāĻŋ āĻšāϞ `float` āϟāĻžāχāĻĒ⧇āϰ (āϧāϰāĻž āϝāĻžāĻ•, āĻĒā§āϰāϤāĻŋāϟāĻŋ āφāχāĻŸā§‡āĻŽā§‡āϰ āĻĻāĻžāĻŽ)āĨ¤ - -#### āχāωāύāĻŋāϝāĻŧāύ - -āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϕ⧇ āĻāĻŽāύāĻ­āĻžāĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āϝ⧇āύ āϤāĻž **āĻāĻ•āĻžāϧāĻŋāĻ• āϟāĻžāχāĻĒ⧇āϰ** āĻšāϝāĻŧ, āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āĻāĻ•āϟāĻŋ `int` āĻ…āĻĨāĻŦāĻž `str`āĨ¤ - -Python 3.6 āĻāĻŦāĻ‚ āϤāĻžāϰ āωāĻĒāϰ⧇āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋāϤ⧇ (Python 3.10 āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ) āφāĻĒāύāĻŋ `typing` āĻĨ⧇āϕ⧇ `Union` āϟāĻžāχāĻĒ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āĻāĻŦāĻ‚ āĻ¸ā§āϕ⧋āϝāĻŧāĻžāϰ āĻŦā§āĻ°ā§āϝāĻžāϕ⧇āĻŸā§‡āϰ āĻŽāĻ§ā§āϝ⧇ āĻ—ā§āϰāĻšāĻŖāϝ⧋āĻ—ā§āϝ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āϰāĻžāĻ–āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -Python 3.10-āĻ āĻāĻ•āϟāĻŋ **āύāϤ⧁āύ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ** āφāϛ⧇ āϝ⧇āĻ–āĻžāύ⧇ āφāĻĒāύāĻŋ āϏāĻŽā§āĻ­āĻžāĻŦā§āϝ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ āĻ­āĻžāĻ°ā§āϟāĻŋāĻ•āĻžāϞ āĻŦāĻžāϰ (`|`) āĻĻā§āĻŦāĻžāϰāĻž āĻĒ⧃āĻĨāĻ• āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -//// tab | Python 3.10+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial008b_py310.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} -``` - -//// - -āωāĻ­āϝāĻŧ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āχ āĻāϰ āĻŽāĻžāύ⧇ āĻšāϞ āϝ⧇ `item` āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āĻāĻ•āϟāĻŋ `int` āĻ…āĻĨāĻŦāĻž `str`āĨ¤ - -#### āϏāĻŽā§āĻ­āĻŦāϤ `None` - -āφāĻĒāύāĻŋ āĻāĻŽāύāĻ­āĻžāĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āϝ⧇ āĻāĻ•āϟāĻŋ āĻŽāĻžāύ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āĻāĻ• āϟāĻžāχāĻĒ⧇āϰ, āϝ⧇āĻŽāύ `str`, āφāĻŦāĻžāϰ āĻāϟāĻŋ `None`-āĻ“ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -Python 3.6 āĻāĻŦāĻ‚ āϤāĻžāϰ āωāĻĒāϰ⧇āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋāϤ⧇ (Python 3.10 āĻ…āύāϤāĻ°ā§āϭ⧁āĻ•ā§āϤ) āφāĻĒāύāĻŋ `typing` āĻŽāĻĄāĻŋāωāϞ āĻĨ⧇āϕ⧇ `Optional` āχāĻŽāĻĒā§‹āĻ°ā§āϟ āĻ•āϰ⧇ āĻāϟāĻŋ āĻ˜ā§‹āώāĻŖāĻž āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009.py!} -``` - -`Optional[str]` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻŽāĻžāύ⧇ āĻšāϞ āĻļ⧁āϧ⧁ `str` āύāϝāĻŧ, āĻāϟāĻŋ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ `None`-āĻ“, āϝāĻž āφāĻĒāύāĻžāϰ āĻāĻĄāĻŋāϟāϰāϕ⧇ āϏ⧇āχ āĻ¤ā§āϰ⧁āϟāĻŋāϗ⧁āϞāĻŋ āĻļāύāĻžāĻ•ā§āϤ āĻ•āϰāϤ⧇ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāĻŦ⧇ āϝ⧇āĻ–āĻžāύ⧇ āφāĻĒāύāĻŋ āϧāϰ⧇ āύāĻŋāĻšā§āϛ⧇āύ āϝ⧇ āĻāĻ•āϟāĻŋ āĻŽāĻžāύ āϏāĻŦāϏāĻŽāϝāĻŧ `str` āĻšāĻŦ⧇, āĻ…āĻĨāϚ āĻāϟāĻŋ `None`-āĻ“ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĻ“āĨ¤ - -`Optional[Something]` āĻŽā§‚āϞāϤ `Union[Something, None]`-āĻāϰ āĻāĻ•āϟāĻŋ āĻļāĻ°ā§āϟāĻ•āĻžāϟ, āĻāĻŦāĻ‚ āϤāĻžāϰāĻž āϏāĻŽāϤ⧁āĻ˛ā§āϝāĨ¤ - -āĻāϰ āĻŽāĻžāύ⧇ āĻšāϞ, Python 3.10-āĻ, āφāĻĒāύāĻŋ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋāϰ āχāωāύāĻŋāϝāĻŧāύ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ `Something | None` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ: - -//// tab | Python 3.10+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial009_py310.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} -``` - -//// - -//// tab | Python 3.8+ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} -``` - -//// - -#### `Union` āĻŦāĻž `Optional` āĻŦā§āϝāĻŦāĻšāĻžāϰ - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ Python 3.10-āĻāϰ āύ⧀āĻšā§‡āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ, āϤāĻŦ⧇ āĻāĻ–āĻžāύ⧇ āφāĻŽāĻžāϰ āϖ⧁āĻŦāχ **āĻŦā§āϝāĻ•ā§āϤāĻŋāĻ—āϤ** āĻĻ⧃āĻˇā§āϟāĻŋāĻ­āĻ™ā§āĻ—āĻŋ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āϟāĻŋāĻĒāϏ: - -* 🚨 `Optional[SomeType]` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāĻĄāĻŧāĻŋāϝāĻŧ⧇ āϚāϞ⧁āύāĨ¤ -* āĻāϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ ✨ **`Union[SomeType, None]` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ** ✨āĨ¤ - -āωāĻ­āϝāĻŧāχ āϏāĻŽāϤ⧁āĻ˛ā§āϝ āĻāĻŦāĻ‚ āĻŽā§‚āϞ⧇ āĻāĻ•āχ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻŽāĻŋ `Union`-āĻāϰ āĻĒāĻ•ā§āώ⧇ āϏ⧁āĻĒāĻžāϰāĻŋāĻļ āĻ•āϰāĻŦ āĻ•āĻžāϰāĻŖ "**āĻ…āĻĒāĻļāύāĻžāϞ**" āĻļāĻŦā§āĻĻāϟāĻŋ āĻŽāύ⧇ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āϝ⧇ āĻŽāĻžāύāϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ•,āĻ…āĻĨāϚ āĻāϟāĻŋ āφāϏāϞ⧇ āĻŽāĻžāύ⧇ "āĻāϟāĻŋ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ `None`", āĻāĻŽāύāĻ•āĻŋ āϝāĻĻāĻŋ āĻāϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ• āύāĻž āĻšāϝāĻŧ⧇āĻ“ āφāĻŦāĻļā§āϝāĻŋāĻ• āĻšāϝāĻŧāĨ¤ - -āφāĻŽāĻŋ āĻŽāύ⧇ āĻ•āϰāĻŋ `Union[SomeType, None]` āĻāϰ āĻ…āĻ°ā§āĻĨ āφāϰāĻ“ āĻ¸ā§āĻĒāĻˇā§āϟāĻ­āĻžāĻŦ⧇ āĻĒā§āϰāĻ•āĻžāĻļ āĻ•āϰ⧇āĨ¤ - -āĻāϟāĻŋ āϕ⧇āĻŦāϞ āĻļāĻŦā§āĻĻ āĻāĻŦāĻ‚ āύāĻžāĻŽā§‡āϰ āĻŦā§āϝāĻžāĻĒāĻžāϰāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏ⧇āχ āĻļāĻŦā§āĻĻāϗ⧁āϞāĻŋ āφāĻĒāύāĻŋ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āϏāĻšāĻ•āĻ°ā§āĻŽā§€āϰāĻž āϕ⧋āĻĄ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āϕ⧀āĻ­āĻžāĻŦ⧇ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰ⧇āύ āϤāĻž āĻĒā§āϰāĻ­āĻžāĻŦāĻŋāϤ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ āĻšāĻŋāϏ⧇āĻŦ⧇, āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āύāĻŋāύ: - -{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} - - -`name` āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϟāĻŋ `Optional[str]` āĻšāĻŋāϏ⧇āĻŦ⧇ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻšāϝāĻŧ⧇āϛ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāϟāĻŋ **āĻ…āĻĒāĻļāύāĻžāϞ āύāϝāĻŧ**, āφāĻĒāύāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻ›āĻžāĻĄāĻŧāĻž āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻ•āϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ āύāĻž: - -```Python -say_hi() # āĻ“āĻš āύāĻž, āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ¤ā§āϰ⧁āϟāĻŋ āύāĻŋāĻ•ā§āώ⧇āĻĒ āĻ•āϰāĻŦ⧇! 😱 -``` - -`name` āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰāϟāĻŋ **āĻāĻ–āύāĻ“ āφāĻŦāĻļā§āϝāĻŋāĻ•** (āύāύ-āĻ…āĻĒāĻļāύāĻžāϞ) āĻ•āĻžāϰāĻŖ āĻāϟāĻŋāϰ āϕ⧋āύ⧋ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻŽāĻžāύ āύ⧇āχāĨ¤ āϤāĻŦ⧁āĻ“, `name` āĻāϰ āĻŽāĻžāύ āĻšāĻŋāϏ⧇āĻŦ⧇ `None` āĻ—ā§āϰāĻšāĻŖāϝ⧋āĻ—ā§āϝ: - -```Python -say_hi(name=None) # āĻāϟāĻŋ āĻ•āĻžāϜ āĻ•āϰ⧇, None āĻŦ⧈āϧ 🎉 -``` - -āϏ⧁āĻ–āĻŦāϰ āĻšāϞ, āĻāĻ•āĻŦāĻžāϰ āφāĻĒāύāĻŋ Python 3.10 āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻļ⧁āϰ⧁ āĻ•āϰāϞ⧇, āφāĻĒāύāĻžāϕ⧇ āĻāϗ⧁āϞ⧋āϰ āĻŦā§āϝāĻžāĻĒāĻžāϰ⧇ āφāϰ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āύāĻž, āϝ⧇āĻšā§āϤ⧁ āφāĻĒāύāĻŋ | āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āχ āχāωāύāĻŋāϝāĻŧāύ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ: - -{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *} - - -āĻāĻŦāĻ‚ āϤāĻžāϰāĻĒāϰ āφāĻĒāύāĻžāϕ⧇ āύāĻžāĻŽāϗ⧁āϞāĻŋ āϝ⧇āĻŽāύ `Optional` āĻāĻŦāĻ‚ `Union` āύāĻŋāϝāĻŧ⧇ āφāϰ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āύāĻžāĨ¤ 😎 - -#### āĻœā§‡āύ⧇āϰāĻŋāĻ• āϟāĻžāχāĻĒāϏ - -āĻ¸ā§āϕ⧋āϝāĻŧāĻžāϰ āĻŦā§āĻ°ā§āϝāĻžāϕ⧇āĻŸā§‡ āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āύ⧇āĻ“āϝāĻŧāĻž āĻāχ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋāϕ⧇ **āĻœā§‡āύ⧇āϰāĻŋāĻ• āϟāĻžāχāĻĒ** āĻŦāĻž **āĻœā§‡āύ⧇āϰāĻŋāĻ•āϏ** āĻŦāϞāĻž āĻšāϝāĻŧ, āϝ⧇āĻŽāύ: - -//// tab | Python 3.10+ - -āφāĻĒāύāĻŋ āϏ⧇āχ āĻāĻ•āχ āĻŦāĻŋāĻ˛ā§āϟāχāύ āϟāĻžāχāĻĒ āĻœā§‡āύ⧇āϰāĻŋāĻ•ā§āϏ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ(āĻ­āĻŋāϤāϰ⧇ āϟāĻžāχāĻĒ āϏāĻš āĻ¸ā§āĻ•āϝāĻŧāĻžāϰ⧇ āĻŦā§āϰāĻžāϕ⧇āϟ āĻĻāĻŋāϝāĻŧ⧇): - -* `list` -* `tuple` -* `set` -* `dict` - -āĻāĻŦāĻ‚ Python 3.8 āĻāϰ āĻŽāϤ⧋āχ, `typing` āĻŽāĻĄāĻŋāωāϞ āĻĨ⧇āϕ⧇: - -* `Union` -* `Optional` (Python 3.8 āĻāϰ āĻŽāϤ⧋āχ) -* ...āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝāĨ¤ - -Python 3.10-āĻ, `Union` āĻāĻŦāĻ‚ `Optional` āĻœā§‡āύ⧇āϰāĻŋāĻ•āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āĻšāĻŋāϏ⧇āĻŦ⧇, āφāĻĒāύāĻŋ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋāϰ āχāωāύāĻŋāϝāĻŧāύ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻ­āĻžāĻ°ā§āϟāĻŋāĻ•āĻžāϞ āĻŦāĻžāϰ (`|`) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āϝāĻž āĻ“āĻĻ⧇āϰ āĻĨ⧇āϕ⧇ āĻ…āύ⧇āĻ• āĻ­āĻžāϞ⧋ āĻāĻŦāĻ‚ āϏāĻšāϜāĨ¤ - -//// - -//// tab | Python 3.9+ - -āφāĻĒāύāĻŋ āϏ⧇āχ āĻāĻ•āχ āĻŦāĻŋāĻ˛ā§āϟāχāύ āϟāĻžāχāĻĒ āĻœā§‡āύ⧇āϰāĻŋāĻ•ā§āϏ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ(āĻ­āĻŋāϤāϰ⧇ āϟāĻžāχāĻĒ āϏāĻš āĻ¸ā§āĻ•āϝāĻŧāĻžāϰ⧇ āĻŦā§āϰāĻžāϕ⧇āϟ āĻĻāĻŋāϝāĻŧ⧇): - -* `list` -* `tuple` -* `set` -* `dict` - -āĻāĻŦāĻ‚ Python 3.8 āĻāϰ āĻŽāϤ⧋āχ, `typing` āĻŽāĻĄāĻŋāωāϞ āĻĨ⧇āϕ⧇: - -* `Union` -* `Optional` -* ...āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝāĨ¤ - -//// - -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ...āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝāĨ¤ - -//// - -### āĻ•ā§āϞāĻžāϏ āĻšāĻŋāϏ⧇āĻŦ⧇ āϟāĻžāχāĻĒāϏ - -āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ⧇āϰ āϟāĻžāχāĻĒ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻāĻ•āϟāĻŋ āĻ•ā§āϞāĻžāϏ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -āϧāϰ⧁āύ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ `Person` āύāĻžāĻŽā§‡ āĻāĻ•āϟāĻŋ āĻ•ā§āϞāĻžāϏ āφāϛ⧇, āϝāĻžāϰ āĻāĻ•āϟāĻŋ āύāĻžāĻŽ āφāϛ⧇: - -{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} - - -āϤāĻžāϰāĻĒāϰ āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϕ⧇ `Person` āϟāĻžāχāĻĒ⧇āϰ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ: - -{* ../../docs_src/python_types/tutorial010.py hl[6] *} - - -āĻāĻŦāĻ‚ āϤāĻžāϰāĻĒāϰ, āφāĻŦāĻžāϰ, āφāĻĒāύāĻŋ āĻāĻĄāĻŋāϟāϰ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻĒ⧇āϝāĻŧ⧇ āϝāĻžāĻŦ⧇āύ: - - - -āϞāĻ•ā§āĻˇā§āϝ āĻ•āϰ⧁āύ āϝ⧇ āĻāϰ āĻŽāĻžāύ⧇ āĻšāϞ "`one_person` āĻšāϞ āĻ•ā§āϞāĻžāϏ `Person`-āĻāϰ āĻāĻ•āϟāĻŋ **āχāĻ¨ā§āϏāĻŸā§āϝāĻžāĻ¨ā§āϏ**āĨ¤" - -āĻāϰ āĻŽāĻžāύ⧇ āĻāϟāĻŋ āύāϝāĻŧ āϝ⧇ "`one_person` āĻšāϞ **āĻ•ā§āϞāĻžāϏ** āϝāĻžāϕ⧇ āĻŦāϞāĻž āĻšāϝāĻŧ `Person`āĨ¤" - -## Pydantic āĻŽāĻĄā§‡āϞ - -[Pydantic](https://docs.pydantic.dev/) āĻšāϞ āĻāĻ•āϟāĻŋ Python āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āϝāĻž āĻĄāĻžāϟāĻž āĻ­ā§āϝāĻžāϞāĻŋāĻĄā§‡āĻļāύ āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻ•āϰ⧇āĨ¤ - -āφāĻĒāύāĻŋ āĻĄāĻžāϟāĻžāϰ "āφāĻ•āĻžāϰ" āĻāĻŸā§āϰāĻŋāĻŦāĻŋāωāϟ āϏāĻš āĻ•ā§āϞāĻžāϏ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧇āύāĨ¤ - -āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻāĻŸā§āϰāĻŋāĻŦāĻŋāωāϟ āĻāϰ āĻāĻ•āϟāĻŋ āϟāĻžāχāĻĒ āĻĨāĻžāϕ⧇āĨ¤ - -āϤāĻžāϰāĻĒāϰ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻ•āĻŋāϛ⧁ āĻŽāĻžāύ āĻĻāĻŋāϝāĻŧ⧇ āϏ⧇āχ āĻ•ā§āϞāĻžāϏ⧇āϰ āĻāĻ•āϟāĻŋ āχāĻ¨ā§āϏāĻŸā§āϝāĻžāĻ¨ā§āϏ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āύ-- āĻāϟāĻŋ āĻŽāĻžāύāϗ⧁āϞāĻŋāϕ⧇ āĻ­ā§āϝāĻžāϞāĻŋāĻĄā§‡āϟ āĻ•āϰāĻŦ⧇, āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻ…āύ⧁āϝāĻžāϝāĻŧā§€ āϤāĻžāĻĻ⧇āϰāϕ⧇ āωāĻĒāϝ⧁āĻ•ā§āϤ āϟāĻžāχāĻĒ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰāĻŦ⧇ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϕ⧇ āϏāĻŽāĻ¸ā§āϤ āĻĄāĻžāϟāĻž āϏāĻš āĻāĻ•āϟāĻŋ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰāĻŦ⧇āĨ¤ - -āĻāĻŦāĻ‚ āφāĻĒāύāĻŋ āϏ⧇āχ āĻĢāϞāĻžāĻĢāϞ āĻ…āĻŦāĻœā§‡āĻ•ā§āĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āĻāĻĄāĻŋāϟāϰ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻĒāĻžāĻŦ⧇āύāĨ¤ - -āĻ…āĻĢāĻŋāϏāĻŋāϝāĻŧāĻžāϞ Pydantic āĻĄāĻ•ā§āϏ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ: - -//// tab | Python 3.10+ - -```Python -{!> ../../docs_src/python_types/tutorial011_py310.py!} -``` - -//// - -//// tab | Python 3.9+ - -```Python -{!> ../../docs_src/python_types/tutorial011_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python -{!> ../../docs_src/python_types/tutorial011.py!} -``` - -//// - -/// info - -[Pydantic āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āϜāĻžāύāϤ⧇, āĻāϰ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻĻ⧇āϖ⧁āύ](https://docs.pydantic.dev/)āĨ¤ - -/// - -**FastAPI** āĻŽā§‚āϞāϤ Pydantic-āĻāϰ āωāĻĒāϰ āύāĻŋāĻ°ā§āĻŽāĻŋāϤāĨ¤ - -āφāĻĒāύāĻŋ āĻāχ āϏāĻŽāĻ¸ā§āϤ āĻ•āĻŋāϛ⧁āϰ āĻ…āύ⧇āĻ• āĻŦāĻžāĻ¸ā§āϤāĻŦāϏāĻŽā§āĻŽāϤ āωāĻĻāĻžāĻšāϰāĻŖ āĻĒāĻžāĻŦ⧇āύ [āϟāĻŋāωāĻŸā§‹āϰāĻŋāϝāĻŧāĻžāϞ - āχāωāϜāĻžāϰ āĻ—āĻžāχāĻĄā§‡](https://fastapi.tiangolo.com/tutorial/)āĨ¤ - -/// tip - -āϝāĻ–āύ āφāĻĒāύāĻŋ `Optional` āĻŦāĻž `Union[Something, None]` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ āĻāĻŦāĻ‚ āϕ⧋āύ⧋ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻŽāĻžāύ āύāĻž āĻĨāĻžāϕ⧇, Pydantic-āĻāϰ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻļ⧇āώ āφāϚāϰāĻŖ āϰāϝāĻŧ⧇āϛ⧇, āφāĻĒāύāĻŋ Pydantic āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ⧇ [Required Optional fields](https://docs.pydantic.dev/latest/concepts/models/#required-optional-fields) āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āĻĒāĻĄāĻŧāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -/// - -## āĻŽā§‡āϟāĻžāĻĄāĻžāϟāĻž āĻ…ā§āϝāĻžāύ⧋āĻŸā§‡āĻļāύ āϏāĻš āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϏ - -Python-āĻ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āĻĢāĻŋāϚāĻžāϰ āφāϛ⧇ āϝāĻž `Annotated` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāχ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϗ⧁āϞāĻŋāϤ⧇ **āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŽā§‡āϟāĻžāĻĄāĻžāϟāĻž** āϰāĻžāĻ–āϤ⧇ āĻĻ⧇āϝāĻŧāĨ¤ - -//// tab | Python 3.9+ - -Python 3.9-āĻ, `Annotated` āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϤ⧇ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ, āϤāĻžāχ āφāĻĒāύāĻŋ āĻāϟāĻŋ `typing` āĻĨ⧇āϕ⧇ āχāĻŽāĻĒā§‹āĻ°ā§āϟ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -Python 3.9-āĻāϰ āύ⧀āĻšā§‡āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋāϤ⧇, āφāĻĒāύāĻŋ `Annotated`-āϕ⧇ `typing_extensions` āĻĨ⧇āϕ⧇ āχāĻŽāĻĒā§‹āĻ°ā§āϟ āĻ•āϰ⧇āύāĨ¤ - -āĻāϟāĻŋ **FastAPI** āĻāϰ āϏāĻžāĻĨ⧇ āχāϤāĻŋāĻŽāĻĻā§āϧ⧇ āχāύāĻ¸ā§āϟāϞ āĻšāϝāĻŧ⧇ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013.py!} -``` - -//// - -Python āύāĻŋāĻœā§‡ āĻāχ `Annotated` āĻĻāĻŋāϝāĻŧ⧇ āĻ•āĻŋāϛ⧁āχ āĻ•āϰ⧇ āύāĻžāĨ¤ āĻāĻŦāĻ‚ āĻāĻĄāĻŋāϟāϰ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āϟ⧁āϞāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ, āϟāĻžāχāĻĒāϟāĻŋ āĻāĻ–āύāĻ“ `str`āĨ¤ - -āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻĒāύāĻŋ āĻāχ `Annotated` āĻāϰ āĻŽāĻ§ā§āϝāĻ•āĻžāϰ āϜāĻžāϝāĻŧāĻ—āĻžāϟāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ **FastAPI**-āĻ āϕ⧀āĻ­āĻžāĻŦ⧇ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āφāϚāϰāĻŖ āĻ•āϰ⧁āĻ• āϤāĻž āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŽā§‡āϟāĻžāĻĄāĻžāϟāĻž āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ - -āĻŽāύ⧇ āϰāĻžāĻ–āĻžāϰ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻŦāĻŋāώāϝāĻŧ āĻšāϞ āϝ⧇ **āĻĒā§āϰāĻĨāĻŽ *āϟāĻžāχāĻĒ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ*** āφāĻĒāύāĻŋ `Annotated`-āĻ āĻĒāĻžāϏ āĻ•āϰ⧇āύ āϏ⧇āϟāĻŋ āĻšāϞ **āφāϏāϞ āϟāĻžāχāĻĒ**āĨ¤ āĻŦāĻžāĻ•āĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āϟ⧁āϞāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āĻŽā§‡āϟāĻžāĻĄāĻžāϟāĻžāĨ¤ - -āĻāĻ–āύ āφāĻĒāύāĻžāϰ āϕ⧇āĻŦāϞ āϜāĻžāύāĻž āĻĒā§āϰāϝāĻŧā§‹āϜāύ āϝ⧇ `Annotated` āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ, āĻāĻŦāĻ‚ āĻāϟāĻŋ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ PythonāĨ¤ 😎 - -āĻĒāϰāĻŦāĻ°ā§āϤ⧀āϤ⧇ āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āĻŦ⧇āύ āĻāϟāĻŋ āĻ•āϤāϟāĻž **āĻļāĻ•ā§āϤāĻŋāĻļāĻžāϞ⧀** āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ - -/// tip - -āĻāϟāĻŋ **āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ Python** āĻšāĻ“āϝāĻŧāĻžāϰ āĻŽāĻžāύ⧇ āĻšāϞ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻāĻĄāĻŋāϟāϰ⧇, āφāĻĒāύāĻŋ āϝ⧇ āϟ⧁āϞāϗ⧁āϞāĻŋ āϕ⧋āĻĄ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ āĻāĻŦāĻ‚ āϰāĻŋāĻĢā§āϝāĻžāĻ•ā§āϟāϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ āϤāĻžāϤ⧇ **āϏ⧇āϰāĻž āϏāĻŽā§āĻ­āĻžāĻŦā§āϝ āĻĄā§‡āϭ⧇āϞāĻĒāĻžāϰ āĻāĻ•ā§āϏāĻĒ⧇āϰāĻŋāϝāĻŧ⧇āĻ¨ā§āϏ** āĻĒāĻžāĻŦ⧇āύāĨ¤ ✨ - -āĻāĻŦāĻ‚ āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“ āφāĻĒāύāĻžāϰ āϕ⧋āĻĄ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ…āύ⧇āĻ• Python āϟ⧁āϞ āĻāĻŦāĻ‚ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āϖ⧁āĻŦ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻšāĻŦ⧇āĨ¤ 🚀 - -/// - -## **FastAPI**-āĻ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϏ - -**FastAPI** āĻāχ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϗ⧁āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻŦ⧇āĻļ āĻ•āĻŋāϛ⧁ āϜāĻŋāύāĻŋāϏ āĻ•āϰ⧇āĨ¤ - -**FastAPI**-āĻ āφāĻĒāύāĻŋ āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟāϗ⧁āϞāĻŋ āϏāĻš āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻ˜ā§‹āώāĻŖāĻž āĻ•āϰ⧇āύ āĻāĻŦāĻ‚ āφāĻĒāύāĻŋ āĻĒāĻžāύ: - -* **āĻāĻĄāĻŋāϟāϰ āϏāĻžāĻĒā§‹āĻ°ā§āϟ**āĨ¤ -* **āϟāĻžāχāĻĒāĻšā§‡āĻ•**āĨ¤ - -...āĻāĻŦāĻ‚ **FastAPI** āĻāĻ•āχ āĻ˜ā§‹āώāĻŖāĻžāϗ⧁āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇: - -* **āϰāĻŋāϕ⧁āχāϰ⧇āĻŽā§‡āĻ¨ā§āϟāϏ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻ•āϰ⧇**: āϰāĻŋāϕ⧋āϝāĻŧ⧇āĻ¸ā§āϟ āĻĒāĻžāĻĨ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ, āϕ⧁āϝāĻŧ⧇āϰāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ, āĻšā§‡āĻĄāĻžāϰ, āĻŦāĻĄāĻŋ, āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋāϏ, āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āĻĨ⧇āϕ⧇āĨ¤ -* **āĻĄā§‡āϟāĻž āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ āĻ•āϰ⧇**: āϰāĻŋāϕ⧋āϝāĻŧ⧇āĻ¸ā§āϟ āĻĨ⧇āϕ⧇ āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āϟāĻžāχāĻĒ⧇ āĻĄā§‡āϟāĻžāĨ¤ -* **āĻĄā§‡āϟāĻž āϝāĻžāϚāĻžāχ āĻ•āϰ⧇**: āĻĒā§āϰāϤāĻŋāϟāĻŋ āϰāĻŋāϕ⧋āϝāĻŧ⧇āĻ¸ā§āϟ āĻĨ⧇āϕ⧇ āφāϏāĻž āĻĄā§‡āϟāĻž: - * āϝāĻ–āύ āĻĄā§‡āϟāĻž āĻ…āĻŦ⧈āϧ āĻšāϝāĻŧ āϤāĻ–āύ **āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻ¤ā§āϰ⧁āϟāĻŋ** āĻ—ā§āϰāĻžāĻšāϕ⧇āϰ āĻ•āĻžāϛ⧇ āĻĢ⧇āϰāϤ āĻĒāĻžāĻ āĻžāύ⧋āĨ¤ -* **API āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āϤ⧈āϰāĻŋ āĻ•āϰ⧇**: OpenAPI āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇: - * āϝāĻž āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āχāĻ¨ā§āϟāĻžāĻ°â€Œā§āϝāĻžāĻ•ā§āϟāĻŋāĻ­ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āχāωāϜāĻžāϰ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āĻĻā§āĻŦāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤ - -āĻāχ āϏāĻŦ āĻ•āĻŋāϛ⧁ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻ…āĻ¸ā§āĻĒāĻˇā§āϟ āĻŽāύ⧇ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰāĻŦ⧇āύ āύāĻžāĨ¤ āφāĻĒāύāĻŋ [āϟāĻŋāωāĻŸā§‹āϰāĻŋāϝāĻŧāĻžāϞ - āχāωāϜāĻžāϰ āĻ—āĻžāχāĻĄ](https://fastapi.tiangolo.com/tutorial/) āĻ āĻāχ āϏāĻŦ āĻ•āĻŋāϛ⧁ āĻĒā§āĻ°ā§āϝāĻžāĻ•āϟāĻŋāϏ⧇ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύāĨ¤ - -āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻŦāĻŋāώāϝāĻŧ āĻšāϞ, āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ Python āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ, āϤāĻŦ⧇ āφāϰāĻ“ āĻŦ⧇āĻļāĻŋ āĻ•ā§āϞāĻžāϏ, āĻĄā§‡āϕ⧋āϰ⧇āϟāϰ āχāĻ¤ā§āϝāĻžāĻĻāĻŋ āϝ⧋āĻ— āύāĻž āĻ•āϰ⧇āχ āĻāĻ•āχ āĻ¸ā§āĻĨāĻžāύ⧇ **FastAPI** āφāĻĒāύāĻžāϰ āĻ…āύ⧇āĻ• āĻ•āĻžāϜ āĻ•āϰ⧇ āĻĻāĻŋāĻŦ⧇āĨ¤ - -/// info - -āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āϟāĻŋāωāĻŸā§‹āϰāĻŋāϝāĻŧāĻžāϞ⧇āϰ āϏāĻŽāĻ¸ā§āϤ āĻŦāĻŋāώāϝāĻŧ āĻĒāĻĄāĻŧ⧇ āĻĢ⧇āϞ⧇ āĻĨāĻžāϕ⧇āύ āĻāĻŦāĻ‚ āϟāĻžāχāĻĒ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āϜāĻžāύāϤ⧇ āϚāĻžāύ, āϤāĻŦ⧇ āĻāĻ•āϟāĻŋ āĻ­āĻžāϞ⧋ āϰāĻŋāϏ⧋āĻ°ā§āϏ āĻšāϞ [mypy āĻāϰ "cheat sheet"](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)āĨ¤ āĻāχ "cheat sheet" āĻ āφāĻĒāύāĻŋ Python āϟāĻžāχāĻĒ āĻšāĻŋāĻ¨ā§āϟ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻŦ⧇āϏāĻŋāĻ• āĻĨ⧇āϕ⧇ āωāĻ¨ā§āύāϤ āϞ⧇āϭ⧇āϞ⧇āϰ āϧāĻžāϰāĻŖāĻž āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύ, āϝāĻž āφāĻĒāύāĻžāϰ āϕ⧋āĻĄā§‡ āϟāĻžāχāĻĒ āϏ⧇āĻĢāϟāĻŋ āĻāĻŦāĻ‚ āĻ¸ā§āĻĒāĻˇā§āϟāϤāĻž āĻŦāĻžāĻĄāĻŧāĻžāϤ⧇ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāĻŦ⧇āĨ¤ - -/// diff --git a/docs/bn/mkdocs.yml b/docs/bn/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/bn/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/de/docs/_llm-test.md b/docs/de/docs/_llm-test.md new file mode 100644 index 000000000..4a5e5392c --- /dev/null +++ b/docs/de/docs/_llm-test.md @@ -0,0 +1,503 @@ +# LLM-Testdatei { #llm-test-file } + +Dieses Dokument testet, ob das LLM, das die Dokumentation Ãŧbersetzt, den `general_prompt` in `scripts/translate.py` und den sprachspezifischen Prompt in `docs/{language code}/llm-prompt.md` versteht. Der sprachspezifische Prompt wird an `general_prompt` angehängt. + +Hier hinzugefÃŧgte Tests werden von allen Erstellern sprachspezifischer Prompts gesehen. + +So verwenden: + +* Einen sprachspezifischen Prompt haben – `docs/{language code}/llm-prompt.md`. +* Eine frische Übersetzung dieses Dokuments in die gewÃŧnschte Zielsprache durchfÃŧhren (siehe z. B. das Kommando `translate-page` der `translate.py`). Dadurch wird die Übersetzung unter `docs/{language code}/docs/_llm-test.md` erstellt. +* PrÃŧfen Sie, ob in der Übersetzung alles in Ordnung ist. +* Verbessern Sie bei Bedarf Ihren sprachsspezifischen Prompt, den allgemeinen Prompt oder das englische Dokument. +* Beheben Sie anschließend manuell die verbleibenden Probleme in der Übersetzung, sodass es eine gute Übersetzung ist. +* Übersetzen Sie erneut, nachdem die gute Übersetzung vorliegt. Das ideale Ergebnis wäre, dass das LLM an der Übersetzung keine Änderungen mehr vornimmt. Das bedeutet, dass der allgemeine Prompt und Ihr sprachsspezifischer Prompt so gut sind, wie sie sein kÃļnnen (Es wird manchmal ein paar scheinbar zufällige Änderungen machen, der Grund ist, dass LLMs keine deterministischen Algorithmen sind). + +Die Tests: + +## Codeschnipsel { #code-snippets} + +//// tab | Test + +Dies ist ein Codeschnipsel: `foo`. Und dies ist ein weiteres Codeschnipsel: `bar`. Und noch eins: `baz quux`. + +//// + +//// tab | Info + +Der Inhalt von Codeschnipseln sollte unverändert bleiben. + +Siehe Abschnitt `### Content of code snippets` im allgemeinen Prompt in `scripts/translate.py`. + +//// + +## AnfÃŧhrungszeichen { #quotes } + +//// tab | Test + +Gestern schrieb mein Freund: „Wenn man unkorrekt korrekt schreibt, hat man es unkorrekt geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚unkorrekt‘ ist unkorrekterweise nicht ‚„unkorrekt“‘“. + +/// note | Hinweis + +Das LLM wird dies wahrscheinlich falsch Ãŧbersetzen. Interessant ist nur, ob es die korrigierte Übersetzung bei einer erneuten Übersetzung beibehält. + +/// + +//// + +//// tab | Info + +Der Prompt-Designer kann entscheiden, ob neutrale AnfÃŧhrungszeichen in typografische AnfÃŧhrungszeichen umgewandelt werden sollen. Es ist in Ordnung, sie unverändert zu lassen. + +Siehe zum Beispiel den Abschnitt `### Quotes` in `docs/de/llm-prompt.md`. + +//// + +## AnfÃŧhrungszeichen in Codeschnipseln { #quotes-in-code-snippets} + +//// tab | Test + +`pip install "foo[bar]"` + +Beispiele fÃŧr Stringliterale in Codeschnipseln: `"this"`, `'that'`. + +Ein schwieriges Beispiel fÃŧr Stringliterale in Codeschnipseln: `f"I like {'oranges' if orange else "apples"}"` + +Hardcore: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"` + +//// + +//// tab | Info + +... Allerdings mÃŧssen AnfÃŧhrungszeichen in Codeschnipseln unverändert bleiben. + +//// + +## CodeblÃļcke { #code-blocks } + +//// tab | Test + +Ein Bash-Codebeispiel ... + +```bash +# Eine BegrÃŧßung an das Universum ausgeben +echo "Hello universe" +``` + +... und ein Konsolen-Codebeispiel ... + +```console +$ fastapi run main.py + FastAPI Starting server + Searching for package file structure +``` + +... und noch ein Konsolen-Codebeispiel ... + +```console +// Ein Verzeichnis „Code“ erstellen +$ mkdir code +// In dieses Verzeichnis wechseln +$ cd code +``` + +... und ein Python-Codebeispiel ... + +```Python +wont_work() # Das wird nicht funktionieren 😱 +works(foo="bar") # Das funktioniert 🎉 +``` + +... und das war's. + +//// + +//// tab | Info + +Code in CodeblÃļcken sollte nicht verändert werden, mit Ausnahme von Kommentaren. + +Siehe Abschnitt `### Content of code blocks` im allgemeinen Prompt in `scripts/translate.py`. + +//// + +## Tabs und farbige Boxen { #tabs-and-colored-boxes } + +//// tab | Test + +/// info | Info +Etwas Text +/// + +/// note | Hinweis +Etwas Text +/// + +/// note | Technische Details +Etwas Text +/// + +/// check | Testen +Etwas Text +/// + +/// tip | Tipp +Etwas Text +/// + +/// warning | Achtung +Etwas Text +/// + +/// danger | Gefahr +Etwas Text +/// + +//// + +//// tab | Info + +Tabs und `Info`/`Note`/`Warning`/usw. BlÃļcke sollten die Übersetzung ihres Titels nach einem vertikalen Strich (`|`) erhalten. + +Siehe die Abschnitte `### Special blocks` und `### Tab blocks` im allgemeinen Prompt in `scripts/translate.py`. + +//// + +## Web- und interne Links { #web-and-internal-links } + +//// tab | Test + +Der Linktext sollte Ãŧbersetzt werden, die Linkadresse sollte unverändert bleiben: + +* [Link zur Überschrift oben](#code-snippets) +* [Interner Link](index.md#installation){.internal-link target=_blank} +* Externer Link +* Link zu einem Stil +* Link zu einem Skript +* Link zu einem Bild + +Der Linktext sollte Ãŧbersetzt werden, die Linkadresse sollte auf die Übersetzung zeigen: + +* FastAPI-Link + +//// + +//// tab | Info + +Links sollten Ãŧbersetzt werden, aber ihre Adresse soll unverändert bleiben. Eine Ausnahme sind absolute Links zu Seiten der FastAPI-Dokumentation. In diesem Fall sollte auf die Übersetzung verlinkt werden. + +Siehe Abschnitt `### Links` im allgemeinen Prompt in `scripts/translate.py`. + +//// + +## HTML „abbr“-Elemente { #html-abbr-elements } + +//// tab | Test + +Hier einige Dinge, die in HTML-„abbr“-Elemente gepackt sind (einige sind erfunden): + +### Das abbr gibt eine vollständige Phrase { #the-abbr-gives-a-full-phrase } + +* GTD +* lt +* XWT +* PSGI + +### Das abbr gibt eine Erklärung { #the-abbr-gives-an-explanation } + +* Cluster +* Deep Learning + +### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation } + +* MDN +* I/O. + +//// + +//// tab | Info + +„title“-Attribute von „abbr“-Elementen werden nach bestimmten Anweisungen Ãŧbersetzt. + +Übersetzungen kÃļnnen eigene „abbr“-Elemente hinzufÃŧgen, die das LLM nicht entfernen soll. Z. B. um englische WÃļrter zu erklären. + +Siehe Abschnitt `### HTML abbr elements` im allgemeinen Prompt in `scripts/translate.py`. + +//// + +## Überschriften { #headings } + +//// tab | Test + +### Eine Webapp entwickeln – ein Tutorial { #develop-a-webapp-a-tutorial } + +Hallo. + +### Typhinweise und -annotationen { #type-hints-and-annotations } + +Hallo wieder. + +### Super- und Subklassen { #super-and-subclasses } + +Hallo wieder. + +//// + +//// tab | Info + +Die einzige strenge Regel fÃŧr Überschriften ist, dass das LLM den Hash-Teil in geschweiften Klammern unverändert lässt, damit Links nicht kaputtgehen. + +Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`. + +FÃŧr einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`. + +//// + +## In der Dokumentation verwendete Begriffe { #terms-used-in-the-docs } + +//// tab | Test + +* Sie +* Ihr + +* z. B. +* usw. + +* `foo` vom Typ `int` +* `bar` vom Typ `str` +* `baz` vom Typ `list` + +* das Tutorial – Benutzerhandbuch +* das Handbuch fÃŧr fortgeschrittene Benutzer +* die SQLModel-Dokumentation +* die API-Dokumentation +* die automatische Dokumentation + +* Data Science +* Deep Learning +* Machine Learning +* Dependency Injection +* HTTP Basic-Authentifizierung +* HTTP Digest +* ISO-Format +* der JSON-Schema-Standard +* das JSON-Schema +* die Schema-Definition +* Password Flow +* Mobile + +* deprecatet +* designt +* ungÃŧltig +* on the fly +* Standard +* Default +* Groß-/Klein­schrei­bung ist relevant +* Groß-/Klein­schrei­bung ist nicht relevant + +* die Anwendung bereitstellen +* die Seite ausliefern + +* die App +* die Anwendung + +* der Request +* die Response +* die Error-Response + +* die Pfadoperation +* der Pfadoperation-Dekorator +* die Pfadoperation-Funktion + +* der Body +* der Requestbody +* der Responsebody +* der JSON-Body +* der Formularbody +* der Dateibody +* der FunktionskÃļrper + +* der Parameter +* der Body-Parameter +* der Pfad-Parameter +* der Query-Parameter +* der Cookie-Parameter +* der Header-Parameter +* der Formular-Parameter +* der Funktionsparameter + +* das Event +* das Startup-Event +* das Hochfahren des Servers +* das Shutdown-Event +* das Lifespan-Event + +* der Handler +* der Eventhandler +* der Exceptionhandler +* handhaben + +* das Modell +* das Pydantic-Modell +* das Datenmodell +* das Datenbankmodell +* das Formularmodell +* das Modellobjekt + +* die Klasse +* die Basisklasse +* die Elternklasse +* die Subklasse +* die Kindklasse +* die Geschwisterklasse +* die Klassenmethode + +* der Header +* die Header +* der Autorisierungsheader +* der `Authorization`-Header +* der Forwarded-Header + +* das Dependency-Injection-System +* die Dependency +* das Dependable +* der Dependant + +* I/O-lastig +* CPU-lastig +* Nebenläufigkeit +* Parallelität +* Multiprocessing + +* die Umgebungsvariable +* die Umgebungsvariable +* der `PATH` +* die `PATH`-Umgebungsvariable + +* die Authentifizierung +* der Authentifizierungsanbieter +* die Autorisierung +* das Anmeldeformular +* der Autorisierungsanbieter +* der Benutzer authentisiert sich +* das System authentifiziert den Benutzer + +* Das CLI +* Das Kommandozeileninterface + +* der Server +* der Client + +* der Cloudanbieter +* der Clouddienst + +* die Entwicklung +* die Entwicklungsphasen + +* das Dict +* das Dictionary +* die Enumeration +* das Enum +* das Enum-Member + +* der Encoder +* der Decoder +* kodieren +* dekodieren + +* die Exception +* werfen + +* der Ausdruck +* die Anweisung + +* das Frontend +* das Backend + +* die GitHub-Diskussion +* das GitHub-Issue + +* die Leistung +* die Leistungsoptimierung + +* der RÃŧckgabetyp +* der RÃŧckgabewert + +* die Sicherheit +* das Sicherheitsschema + +* der Task +* der Hintergrundtask +* die Taskfunktion + +* das Template +* die Template-Engine + +* die Typannotation +* der Typhinweis + +* der Serverworker +* der Uvicorn-Worker +* der Gunicorn-Worker +* der Workerprozess +* die Workerklasse +* die Workload + +* das Deployment +* bereitstellen + +* das SDK +* das Software Development Kit + +* der `APIRouter` +* die `requirements.txt` +* das Bearer-Token +* der Breaking Change +* der Bug +* der Button +* das Callable +* der Code +* der Commit +* der Contextmanager +* die Coroutine +* die Datenbank-Session +* die Festplatte +* die Domain +* die Engine +* das Fake-X +* die HTTP-GET-Methode +* das Item +* die Bibliothek +* der Lifespan +* der Lock +* die Middleware +* die Mobile-Anwendung +* das Modul +* das Mounten +* das Netzwerk +* das Origin +* Die Überschreibung +* die Payload +* der Prozessor +* die Property +* der Proxy +* der Pull Request +* die Query +* der RAM +* der entfernte Rechner +* der Statuscode +* der String +* der Tag +* das Webframework +* die Wildcard +* zurÃŧckgeben +* validieren + +//// + +//// tab | Info + +Dies ist eine nicht vollständige und nicht normative Liste von (meist) technischen Begriffen, die in der Dokumentation vorkommen. Sie kann dem Prompt-Designer helfen herauszufinden, bei welchen Begriffen das LLM UnterstÃŧtzung braucht. Zum Beispiel, wenn es eine gute Übersetzung immer wieder auf eine suboptimale Übersetzung zurÃŧcksetzt. Oder wenn es Probleme hat, einen Begriff in Ihrer Sprache zu konjugieren/deklinieren. + +Siehe z. B. den Abschnitt `### List of English terms and their preferred German translations` in `docs/de/llm-prompt.md`. + +//// diff --git a/docs/de/docs/about/index.md b/docs/de/docs/about/index.md index 4c309e02a..5e9c6b6a0 100644 --- a/docs/de/docs/about/index.md +++ b/docs/de/docs/about/index.md @@ -1,3 +1,3 @@ -# Über +# Über { #about } Über FastAPI, sein Design, seine Inspiration und mehr. 🤓 diff --git a/docs/de/docs/advanced/additional-responses.md b/docs/de/docs/advanced/additional-responses.md index bf38d9795..218dd6c4f 100644 --- a/docs/de/docs/advanced/additional-responses.md +++ b/docs/de/docs/advanced/additional-responses.md @@ -1,4 +1,4 @@ -# Zusätzliche Responses in OpenAPI +# Zusätzliche Responses in OpenAPI { #additional-responses-in-openapi } /// warning | Achtung @@ -8,17 +8,17 @@ Wenn Sie mit **FastAPI** beginnen, benÃļtigen Sie dies mÃļglicherweise nicht. /// -Sie kÃļnnen zusätzliche Responses mit zusätzlichen Statuscodes, Medientypen, Beschreibungen, usw. deklarieren. +Sie kÃļnnen zusätzliche Responses mit zusätzlichen Statuscodes, Medientypen, Beschreibungen, usw. deklarieren. Diese zusätzlichen Responses werden in das OpenAPI-Schema aufgenommen, sodass sie auch in der API-Dokumentation erscheinen. FÃŧr diese zusätzlichen Responses mÃŧssen Sie jedoch sicherstellen, dass Sie eine `Response`, wie etwa `JSONResponse`, direkt zurÃŧckgeben, mit Ihrem Statuscode und Inhalt. -## Zusätzliche Response mit `model` +## Zusätzliche Response mit `model` { #additional-response-with-model } Sie kÃļnnen Ihren *Pfadoperation-Dekoratoren* einen Parameter `responses` Ãŧbergeben. -Der nimmt ein `dict` entgegen, die SchlÃŧssel sind Statuscodes fÃŧr jede Response, wie etwa `200`, und die Werte sind andere `dict`s mit den Informationen fÃŧr jede Response. +Der nimmt ein `dict` entgegen, die SchlÃŧssel sind Statuscodes fÃŧr jede Response, wie etwa `200`, und die Werte sind andere `dict`s mit den Informationen fÃŧr jede Response. Jedes dieser Response-`dict`s kann einen SchlÃŧssel `model` haben, welcher ein Pydantic-Modell enthält, genau wie `response_model`. @@ -34,7 +34,7 @@ Beachten Sie, dass Sie die `JSONResponse` direkt zurÃŧckgeben mÃŧssen. /// -/// info +/// info | Info Der `model`-SchlÃŧssel ist nicht Teil von OpenAPI. @@ -169,7 +169,7 @@ Die Schemas werden von einer anderen Stelle innerhalb des OpenAPI-Schemas refere } ``` -## Zusätzliche Medientypen fÃŧr die Haupt-Response +## Zusätzliche Medientypen fÃŧr die Haupt-Response { #additional-media-types-for-the-main-response } Sie kÃļnnen denselben `responses`-Parameter verwenden, um verschiedene Medientypen fÃŧr dieselbe Haupt-Response hinzuzufÃŧgen. @@ -183,7 +183,7 @@ Beachten Sie, dass Sie das Bild direkt mit einer `FileResponse` zurÃŧckgeben mÃŧ /// -/// info +/// info | Info Sofern Sie in Ihrem Parameter `responses` nicht explizit einen anderen Medientyp angeben, geht FastAPI davon aus, dass die Response denselben Medientyp wie die Haupt-Response-Klasse hat (Standardmäßig `application/json`). @@ -191,7 +191,7 @@ Wenn Sie jedoch eine benutzerdefinierte Response-Klasse mit `None` als Medientyp /// -## Informationen kombinieren +## Informationen kombinieren { #combining-information } Sie kÃļnnen auch Response-Informationen von mehreren Stellen kombinieren, einschließlich der Parameter `response_model`, `status_code` und `responses`. @@ -209,7 +209,7 @@ Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokument -## Vordefinierte und benutzerdefinierte Responses kombinieren +## Vordefinierte und benutzerdefinierte Responses kombinieren { #combine-predefined-responses-and-custom-ones } MÃļglicherweise mÃļchten Sie einige vordefinierte Responses haben, die fÃŧr viele *Pfadoperationen* gelten, Sie mÃļchten diese jedoch mit benutzerdefinierten Responses kombinieren, die fÃŧr jede *Pfadoperation* erforderlich sind. @@ -239,9 +239,9 @@ Zum Beispiel: {* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *} -## Weitere Informationen zu OpenAPI-Responses +## Weitere Informationen zu OpenAPI-Responses { #more-information-about-openapi-responses } Um zu sehen, was genau Sie in die Responses aufnehmen kÃļnnen, kÃļnnen Sie die folgenden Abschnitte in der OpenAPI-Spezifikation ÃŧberprÃŧfen: -* OpenAPI Responses Object, enthält das `Response Object`. -* OpenAPI Response Object, Sie kÃļnnen alles davon direkt in jede Response innerhalb Ihres `responses`-Parameter einfÃŧgen. Einschließlich `description`, `headers`, `content` (darin deklarieren Sie verschiedene Medientypen und JSON-Schemas) und `links`. +* OpenAPI Responses Object, enthält das `Response Object`. +* OpenAPI Response Object, Sie kÃļnnen alles davon direkt in jede Response innerhalb Ihres `responses`-Parameter einfÃŧgen. Einschließlich `description`, `headers`, `content` (darin deklarieren Sie verschiedene Medientypen und JSON-Schemas) und `links`. diff --git a/docs/de/docs/advanced/additional-status-codes.md b/docs/de/docs/advanced/additional-status-codes.md index b07bb90ab..f948e1862 100644 --- a/docs/de/docs/advanced/additional-status-codes.md +++ b/docs/de/docs/advanced/additional-status-codes.md @@ -1,16 +1,16 @@ -# Zusätzliche Statuscodes +# Zusätzliche Statuscodes { #additional-status-codes } -Standardmäßig liefert **FastAPI** die RÃŧckgabewerte (Responses) als `JSONResponse` zurÃŧck und fÃŧgt den Inhalt der jeweiligen *Pfadoperation* in das `JSONResponse` Objekt ein. +Standardmäßig liefert **FastAPI** die Responses als `JSONResponse` zurÃŧck und fÃŧgt den Inhalt, den Sie aus Ihrer *Pfadoperation* zurÃŧckgeben, in diese `JSONResponse` ein. Es wird der Default-Statuscode oder derjenige verwendet, den Sie in Ihrer *Pfadoperation* festgelegt haben. -## Zusätzliche Statuscodes +## Zusätzliche Statuscodes { #additional-status-codes_1 } Wenn Sie neben dem Hauptstatuscode weitere Statuscodes zurÃŧckgeben mÃļchten, kÃļnnen Sie dies tun, indem Sie direkt eine `Response` zurÃŧckgeben, wie etwa eine `JSONResponse`, und den zusätzlichen Statuscode direkt festlegen. Angenommen, Sie mÃļchten eine *Pfadoperation* haben, die das Aktualisieren von Artikeln ermÃļglicht und bei Erfolg den HTTP-Statuscode 200 „OK“ zurÃŧckgibt. -Sie mÃļchten aber auch, dass sie neue Artikel akzeptiert. Und wenn die Elemente vorher nicht vorhanden waren, werden diese Elemente erstellt und der HTTP-Statuscode 201 „Created“ zurÃŧckgegeben. +Sie mÃļchten aber auch, dass sie neue Artikel akzeptiert. Und wenn die Artikel vorher nicht vorhanden waren, werden diese Artikel erstellt und der HTTP-Statuscode 201 „Created“ zurÃŧckgegeben. Um dies zu erreichen, importieren Sie `JSONResponse`, und geben Sie Ihren Inhalt direkt zurÃŧck, indem Sie den gewÃŧnschten `status_code` setzen: @@ -30,11 +30,11 @@ Stellen Sie sicher, dass sie die gewÃŧnschten Daten enthält und dass die Werte Sie kÃļnnen auch `from starlette.responses import JSONResponse` verwenden. -**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. Das Gleiche gilt fÃŧr `status`. +**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. Dasselbe gilt fÃŧr `status`. /// -## OpenAPI- und API-Dokumentation +## OpenAPI- und API-Dokumentation { #openapi-and-api-docs } Wenn Sie zusätzliche Statuscodes und Responses direkt zurÃŧckgeben, werden diese nicht in das OpenAPI-Schema (die API-Dokumentation) aufgenommen, da FastAPI keine MÃļglichkeit hat, im Voraus zu wissen, was Sie zurÃŧckgeben werden. diff --git a/docs/de/docs/advanced/advanced-dependencies.md b/docs/de/docs/advanced/advanced-dependencies.md index 56eb7d454..a153665cc 100644 --- a/docs/de/docs/advanced/advanced-dependencies.md +++ b/docs/de/docs/advanced/advanced-dependencies.md @@ -1,6 +1,6 @@ -# Fortgeschrittene Abhängigkeiten +# Fortgeschrittene Abhängigkeiten { #advanced-dependencies } -## Parametrisierte Abhängigkeiten +## Parametrisierte Abhängigkeiten { #parameterized-dependencies } Alle Abhängigkeiten, die wir bisher gesehen haben, waren festgelegte Funktionen oder Klassen. @@ -10,9 +10,9 @@ Stellen wir uns vor, wir mÃļchten eine Abhängigkeit haben, die prÃŧft, ob ein Q Aber wir wollen diesen vordefinierten Inhalt per Parameter festlegen kÃļnnen. -## Eine „aufrufbare“ Instanz +## Eine „aufrufbare“ Instanz { #a-callable-instance } -In Python gibt es eine MÃļglichkeit, eine Instanz einer Klasse „aufrufbar“ („callable“) zu machen. +In Python gibt es eine MÃļglichkeit, eine Instanz einer Klasse „aufrufbar“ zu machen. Nicht die Klasse selbst (die bereits aufrufbar ist), sondern eine Instanz dieser Klasse. @@ -22,15 +22,15 @@ Dazu deklarieren wir eine Methode `__call__`: In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zusätzlichen Parametern und Unterabhängigkeiten zu suchen, und das ist es auch, was später aufgerufen wird, um einen Wert an den Parameter in Ihrer *Pfadoperation-Funktion* zu Ãŧbergeben. -## Die Instanz parametrisieren +## Die Instanz parametrisieren { #parameterize-the-instance } -Und jetzt kÃļnnen wir `__init__` verwenden, um die Parameter der Instanz zu deklarieren, die wir zum `Parametrisieren` der Abhängigkeit verwenden kÃļnnen: +Und jetzt kÃļnnen wir `__init__` verwenden, um die Parameter der Instanz zu deklarieren, die wir zum „Parametrisieren“ der Abhängigkeit verwenden kÃļnnen: {* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *} In diesem Fall wird **FastAPI** `__init__` nie berÃŧhren oder sich darum kÃŧmmern, wir werden es direkt in unserem Code verwenden. -## Eine Instanz erstellen +## Eine Instanz erstellen { #create-an-instance } Wir kÃļnnten eine Instanz dieser Klasse erstellen mit: @@ -38,7 +38,7 @@ Wir kÃļnnten eine Instanz dieser Klasse erstellen mit: Und auf diese Weise kÃļnnen wir unsere Abhängigkeit „parametrisieren“, die jetzt `"bar"` enthält, als das Attribut `checker.fixed_content`. -## Die Instanz als Abhängigkeit verwenden +## Die Instanz als Abhängigkeit verwenden { #use-the-instance-as-a-dependency } Dann kÃļnnten wir diesen `checker` in einem `Depends(checker)` anstelle von `Depends(FixedContentQueryChecker)` verwenden, da die Abhängigkeit die Instanz `checker` und nicht die Klasse selbst ist. diff --git a/docs/de/docs/advanced/async-tests.md b/docs/de/docs/advanced/async-tests.md index b82aadf00..ad8245205 100644 --- a/docs/de/docs/advanced/async-tests.md +++ b/docs/de/docs/advanced/async-tests.md @@ -1,24 +1,24 @@ -# Asynchrone Tests +# Asynchrone Tests { #async-tests } -Sie haben bereits gesehen, wie Sie Ihre **FastAPI**-Anwendungen mit dem bereitgestellten `TestClient` testen. Bisher haben Sie nur gesehen, wie man synchrone Tests schreibt, ohne `async`hrone Funktionen zu verwenden. +Sie haben bereits gesehen, wie Sie Ihre **FastAPI**-Anwendungen mit dem bereitgestellten `TestClient` testen. Bisher haben Sie nur gesehen, wie man synchrone Tests schreibt, ohne `async`-Funktionen zu verwenden. -Die MÃļglichkeit, in Ihren Tests asynchrone Funktionen zu verwenden, kÃļnnte beispielsweise nÃŧtzlich sein, wenn Sie Ihre Datenbank asynchron abfragen. Stellen Sie sich vor, Sie mÃļchten das Senden von Requests an Ihre FastAPI-Anwendung testen und dann ÃŧberprÃŧfen, ob Ihr Backend die richtigen Daten erfolgreich in die Datenbank geschrieben hat, während Sie eine asynchrone Datenbankbibliothek verwenden. +Die MÃļglichkeit, in Ihren Tests asynchrone Funktionen zu verwenden, kÃļnnte beispielsweise nÃŧtzlich sein, wenn Sie Ihre Datenbank asynchron abfragen. Stellen Sie sich vor, Sie mÃļchten das Senden von Requests an Ihre FastAPI-Anwendung testen und dann ÃŧberprÃŧfen, ob Ihr Backend die richtigen Daten erfolgreich in die Datenbank geschrieben hat, während Sie eine asynchrone Datenbankbibliothek verwenden. Schauen wir uns an, wie wir das machen kÃļnnen. -## pytest.mark.anyio +## pytest.mark.anyio { #pytest-mark-anyio } Wenn wir in unseren Tests asynchrone Funktionen aufrufen mÃļchten, mÃŧssen unsere Testfunktionen asynchron sein. AnyIO stellt hierfÃŧr ein nettes Plugin zur VerfÃŧgung, mit dem wir festlegen kÃļnnen, dass einige Testfunktionen asynchron aufgerufen werden sollen. -## HTTPX +## HTTPX { #httpx } -Auch wenn Ihre **FastAPI**-Anwendung normale `def`-Funktionen anstelle von `async def` verwendet, handelt es sich darunter immer noch um eine `async`hrone Anwendung. +Auch wenn Ihre **FastAPI**-Anwendung normale `def`-Funktionen anstelle von `async def` verwendet, handelt es sich darunter immer noch um eine `async`-Anwendung. -Der `TestClient` macht unter der Haube magisches, um die asynchrone FastAPI-Anwendung in Ihren normalen `def`-Testfunktionen, mithilfe von Standard-Pytest aufzurufen. Aber diese Magie funktioniert nicht mehr, wenn wir sie in asynchronen Funktionen verwenden. Durch die asynchrone AusfÃŧhrung unserer Tests kÃļnnen wir den `TestClient` nicht mehr in unseren Testfunktionen verwenden. +Der `TestClient` betreibt unter der Haube etwas Magie, um die asynchrone FastAPI-Anwendung in Ihren normalen `def`-Testfunktionen, mithilfe von Standard-Pytest aufzurufen. Aber diese Magie funktioniert nicht mehr, wenn wir sie in asynchronen Funktionen verwenden. Durch die asynchrone AusfÃŧhrung unserer Tests kÃļnnen wir den `TestClient` nicht mehr in unseren Testfunktionen verwenden. -Der `TestClient` basiert auf HTTPX und glÃŧcklicherweise kÃļnnen wir ihn direkt verwenden, um die API zu testen. +Der `TestClient` basiert auf HTTPX und glÃŧcklicherweise kÃļnnen wir es direkt verwenden, um die API zu testen. -## Beispiel +## Beispiel { #example } Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [GrÃļßere Anwendungen](../tutorial/bigger-applications.md){.internal-link target=_blank} und [Testen](../tutorial/testing.md){.internal-link target=_blank}: @@ -38,7 +38,7 @@ Die Datei `test_main.py` hätte die Tests fÃŧr `main.py`, das kÃļnnte jetzt so a {* ../../docs_src/async_tests/test_main.py *} -## Es ausfÃŧhren +## Es ausfÃŧhren { #run-it } Sie kÃļnnen Ihre Tests wie gewohnt ausfÃŧhren mit: @@ -52,7 +52,7 @@ $ pytest -## Details +## Im Detail { #in-detail } Der Marker `@pytest.mark.anyio` teilt pytest mit, dass diese Testfunktion asynchron aufgerufen werden soll: @@ -88,9 +88,9 @@ Falls Ihre Anwendung auf Lifespan-Events angewiesen ist, der `AsyncClient` lÃļst /// -## Andere asynchrone Funktionsaufrufe +## Andere asynchrone Funktionsaufrufe { #other-asynchronous-function-calls } -Da die Testfunktion jetzt asynchron ist, kÃļnnen Sie in Ihren Tests neben dem Senden von Requests an Ihre FastAPI-Anwendung jetzt auch andere `async`hrone Funktionen aufrufen (und `await`en), genau so, wie Sie diese an anderer Stelle in Ihrem Code aufrufen wÃŧrden. +Da die Testfunktion jetzt asynchron ist, kÃļnnen Sie in Ihren Tests neben dem Senden von Requests an Ihre FastAPI-Anwendung jetzt auch andere `async`-Funktionen aufrufen (und `await`en), genau so, wie Sie diese an anderer Stelle in Ihrem Code aufrufen wÃŧrden. /// tip | Tipp diff --git a/docs/de/docs/advanced/behind-a-proxy.md b/docs/de/docs/advanced/behind-a-proxy.md index 9e2282280..036916cbe 100644 --- a/docs/de/docs/advanced/behind-a-proxy.md +++ b/docs/de/docs/advanced/behind-a-proxy.md @@ -1,17 +1,114 @@ -# Hinter einem Proxy +# Hinter einem Proxy { #behind-a-proxy } -In manchen Situationen mÃŧssen Sie mÃļglicherweise einen **Proxy**-Server wie Traefik oder Nginx verwenden, mit einer Konfiguration, die ein zusätzliches Pfadpräfix hinzufÃŧgt, das von Ihrer Anwendung nicht gesehen wird. +In vielen Situationen wÃŧrden Sie einen **Proxy** wie Traefik oder Nginx vor Ihrer FastAPI-App verwenden. -In diesen Fällen kÃļnnen Sie `root_path` verwenden, um Ihre Anwendung zu konfigurieren. +Diese Proxys kÃļnnten HTTPS-Zertifikate und andere Dinge handhaben. -Der `root_path` („Wurzelpfad“) ist ein Mechanismus, der von der ASGI-Spezifikation bereitgestellt wird (auf der FastAPI via Starlette aufbaut). +## Proxy-Forwarded-Header { #proxy-forwarded-headers } + +Ein **Proxy** vor Ihrer Anwendung wÃŧrde normalerweise einige Header on-the-fly setzen, bevor er die Requests an den **Server** sendet, um den Server wissen zu lassen, dass der Request vom Proxy **weitergeleitet** wurde, einschließlich der ursprÃŧnglichen (Ãļffentlichen) URL, inklusive der Domain, dass HTTPS verwendet wird, usw. + +Das **Server**-Programm (z. B. **Uvicorn** via **FastAPI CLI**) ist in der Lage, diese Header zu interpretieren und diese Information dann an Ihre Anwendung weiterzugeben. + +Aber aus SicherheitsgrÃŧnden, da der Server nicht weiß, dass er hinter einem vertrauenswÃŧrdigen Proxy läuft, wird er diese Header nicht interpretieren. + +/// note | Technische Details + +Die Proxy-Header sind: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +### Proxy-Forwarded-Header aktivieren { #enable-proxy-forwarded-headers } + +Sie kÃļnnen FastAPI CLI mit der *CLI-Option* `--forwarded-allow-ips` starten und die IP-Adressen Ãŧbergeben, denen vertraut werden soll, um diese Forwarded-Header zu lesen. + +Wenn Sie es auf `--forwarded-allow-ips="*"` setzen, wÃŧrde es allen eingehenden IPs vertrauen. + +Wenn Ihr **Server** hinter einem vertrauenswÃŧrdigen **Proxy** sitzt und nur der Proxy mit ihm spricht, wÃŧrde dies dazu fÃŧhren, dass er die IP dieses **Proxys** akzeptiert, was auch immer sie ist. + +
+ +```console +$ fastapi run --forwarded-allow-ips="*" + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +### Weiterleitungen mit HTTPS { #redirects-with-https } + +Angenommen, Sie definieren eine *Pfadoperation* `/items/`: + +{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *} + +Wenn der Client versucht, zu `/items` zu gehen, wÃŧrde er standardmäßig zu `/items/` umgeleitet. + +Aber bevor Sie die *CLI-Option* `--forwarded-allow-ips` setzen, kÃļnnte er zu `http://localhost:8000/items/` umleiten. + +Aber mÃļglicherweise wird Ihre Anwendung unter `https://mysuperapp.com` gehostet, und die Weiterleitung sollte zu `https://mysuperapp.com/items/` erfolgen. + +Durch Setzen von `--proxy-headers` kann FastAPI jetzt an den richtigen Ort umleiten. 😎 + +``` +https://mysuperapp.com/items/ +``` + +/// tip | Tipp + +Wenn Sie mehr Ãŧber HTTPS erfahren mÃļchten, lesen Sie den Leitfaden [Über HTTPS](../deployment/https.md){.internal-link target=_blank}. + +/// + +### Wie Proxy-Forwarded-Header funktionieren + +Hier ist eine visuelle Darstellung, wie der **Proxy** weitergeleitete Header zwischen dem Client und dem **Anwendungsserver** hinzufÃŧgt: + +```mermaid +sequenceDiagram + participant Client + participant Proxy as Proxy/Loadbalancer + participant Server as FastAPI Server + + Client->>Proxy: HTTPS-Request
Host: mysuperapp.com
Pfad: /items + + Note over Proxy: Proxy fÃŧgt Forwarded-Header hinzu + + Proxy->>Server: HTTP-Request
X-Forwarded-For: [client IP]
X-Forwarded-Proto: https
X-Forwarded-Host: mysuperapp.com
Pfad: /items + + Note over Server: Server interpretiert die Header
(wenn --forwarded-allow-ips gesetzt ist) + + Server->>Proxy: HTTP-Response
mit correkten HTTPS-URLs + + Proxy->>Client: HTTPS-Response +``` + +Der **Proxy** fängt den ursprÃŧnglichen Client-Request ab und fÃŧgt die speziellen *Forwarded*-Header (`X-Forwarded-*`) hinzu, bevor er den Request an den **Anwendungsserver** weitergibt. + +Diese Header bewahren Informationen Ãŧber den ursprÃŧnglichen Request, die sonst verloren gingen: + +* **X-Forwarded-For**: Die ursprÃŧngliche IP-Adresse des Clients +* **X-Forwarded-Proto**: Das ursprÃŧngliche Protokoll (`https`) +* **X-Forwarded-Host**: Der ursprÃŧngliche Host (`mysuperapp.com`) + +Wenn **FastAPI CLI** mit `--forwarded-allow-ips` konfiguriert ist, vertraut es diesen Headern und verwendet sie, z. B. um die korrekten URLs in Weiterleitungen zu erzeugen. + +## Proxy mit einem abgetrennten Pfadpräfix { #proxy-with-a-stripped-path-prefix } + +Sie kÃļnnten einen Proxy haben, der Ihrer Anwendung ein Pfadpräfix hinzufÃŧgt. + +In diesen Fällen kÃļnnen Sie `root_path` verwenden, um Ihre Anwendung zu konfigurieren. + +Der `root_path` ist ein Mechanismus, der von der ASGI-Spezifikation bereitgestellt wird (auf der FastAPI via Starlette aufbaut). Der `root_path` wird verwendet, um diese speziellen Fälle zu handhaben. Und er wird auch intern beim Mounten von Unteranwendungen verwendet. -## Proxy mit einem abgetrennten Pfadpräfix - Ein Proxy mit einem abgetrennten Pfadpräfix bedeutet in diesem Fall, dass Sie einen Pfad unter `/app` in Ihrem Code deklarieren kÃļnnten, dann aber, eine Ebene darÃŧber, den Proxy hinzufÃŧgen, der Ihre **FastAPI**-Anwendung unter einem Pfad wie `/api/v1` platziert. In diesem Fall wÃŧrde der ursprÃŧngliche Pfad `/app` tatsächlich unter `/api/v1/app` bereitgestellt. @@ -20,13 +117,13 @@ Auch wenn Ihr gesamter Code unter der Annahme geschrieben ist, dass es nur `/app {* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *} -Und der Proxy wÃŧrde das **Pfadpräfix** on-the-fly **"entfernen**", bevor er die Anfrage an Uvicorn Ãŧbermittelt, dafÃŧr sorgend, dass Ihre Anwendung davon Ãŧberzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren mÃŧssen, das Präfix `/api/v1` zu verwenden. +Und der Proxy wÃŧrde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den Request an den Anwendungsserver (wahrscheinlich Uvicorn via FastAPI CLI) Ãŧbermittelt, dafÃŧr sorgend, dass Ihre Anwendung davon Ãŧberzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren mÃŧssen, das Präfix `/api/v1` zu verwenden. Bis hierher wÃŧrde alles wie gewohnt funktionieren. Wenn Sie dann jedoch die Benutzeroberfläche der integrierten Dokumentation (das Frontend) Ãļffnen, wird angenommen, dass sich das OpenAPI-Schema unter `/openapi.json` anstelle von `/api/v1/openapi.json` befindet. -Das Frontend (das im Browser läuft) wÃŧrde also versuchen, `/openapi.json` zu erreichen und wäre nicht in der Lage, das OpenAPI-Schema abzurufen. +Also wÃŧrde das Frontend (das im Browser läuft) versuchen, `/openapi.json` zu erreichen und wäre nicht in der Lage, das OpenAPI-Schema abzurufen. Da wir fÃŧr unsere Anwendung einen Proxy mit dem Pfadpräfix `/api/v1` haben, muss das Frontend das OpenAPI-Schema unter `/api/v1/openapi.json` abrufen. @@ -64,16 +161,16 @@ Die Benutzeroberfläche der Dokumentation wÃŧrde benÃļtigen, dass das OpenAPI-Sc } ``` -In diesem Beispiel kÃļnnte der „Proxy“ etwa **Traefik** sein. Und der Server wäre so etwas wie **Uvicorn**, auf dem Ihre FastAPI-Anwendung ausgefÃŧhrt wird. +In diesem Beispiel kÃļnnte der „Proxy“ etwa **Traefik** sein. Und der Server wäre etwas wie FastAPI CLI mit **Uvicorn**, auf dem Ihre FastAPI-Anwendung ausgefÃŧhrt wird. -### Bereitstellung des `root_path` +### Bereitstellung des `root_path` { #providing-the-root-path } Um dies zu erreichen, kÃļnnen Sie die Kommandozeilenoption `--root-path` wie folgt verwenden:
```console -$ uvicorn main:app --root-path /api/v1 +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -90,9 +187,9 @@ Und die Kommandozeilenoption `--root-path` stellt diesen `root_path` bereit. /// -### ÜberprÃŧfen des aktuellen `root_path` +### Testen des aktuellen `root_path` { #checking-the-current-root-path } -Sie kÃļnnen den aktuellen `root_path` abrufen, der von Ihrer Anwendung fÃŧr jede Anfrage verwendet wird. Er ist Teil des `scope`-Dictionarys (das ist Teil der ASGI-Spezifikation). +Sie kÃļnnen den aktuellen `root_path` abrufen, der von Ihrer Anwendung fÃŧr jeden Request verwendet wird. Er ist Teil des `scope`-Dictionarys (das ist Teil der ASGI-Spezifikation). Hier fÃŧgen wir ihn, nur zu Demonstrationszwecken, in die Nachricht ein. @@ -103,14 +200,14 @@ Wenn Sie Uvicorn dann starten mit:
```console -$ uvicorn main:app --root-path /api/v1 +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ```
-wäre die Response etwa: +wäre die Response etwa: ```JSON { @@ -119,19 +216,19 @@ wäre die Response etwa: } ``` -### Festlegen des `root_path` in der FastAPI-Anwendung +### Festlegen des `root_path` in der FastAPI-Anwendung { #setting-the-root-path-in-the-fastapi-app } -Falls Sie keine MÃļglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu Ãŧbergeben, kÃļnnen Sie als Alternative beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen: +Falls Sie keine MÃļglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu Ãŧbergeben, kÃļnnen Sie, alternativ dazu, beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen: {* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *} Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn. -### Über `root_path` +### Über `root_path` { #about-root-path } -Beachten Sie, dass der Server (Uvicorn) diesen `root_path` fÃŧr nichts anderes außer die Weitergabe an die Anwendung verwendet. +Beachten Sie, dass der Server (Uvicorn) diesen `root_path` fÃŧr nichts anderes verwendet als fÃŧr die Weitergabe an die Anwendung. -Aber wenn Sie mit Ihrem Browser auf http://127.0.0.1:8000/app gehen, sehen Sie die normale Antwort: +Aber wenn Sie mit Ihrem Browser auf http://127.0.0.1:8000/app gehen, sehen Sie die normale Response: ```JSON { @@ -144,17 +241,17 @@ Es wird also nicht erwartet, dass unter `http://127.0.0.1:8000/api/v1/app` darau Uvicorn erwartet, dass der Proxy unter `http://127.0.0.1:8000/app` auf Uvicorn zugreift, und dann liegt es in der Verantwortung des Proxys, das zusätzliche `/api/v1`-Präfix darÃŧber hinzuzufÃŧgen. -## Über Proxys mit einem abgetrennten Pfadpräfix +## Über Proxys mit einem abgetrennten Pfadpräfix { #about-proxies-with-a-stripped-path-prefix } -Bedenken Sie, dass ein Proxy mit abgetrennten Pfadpräfix nur eine von vielen KonfigurationsmÃļglichkeiten ist. +Bedenken Sie, dass ein Proxy mit abgetrenntem Pfadpräfix nur eine von vielen KonfigurationsmÃļglichkeiten ist. Wahrscheinlich wird in vielen Fällen die Standardeinstellung sein, dass der Proxy kein abgetrenntes Pfadpräfix hat. -In einem solchen Fall (ohne ein abgetrenntes Pfadpräfix) wÃŧrde der Proxy auf etwas wie `https://myawesomeapp.com` lauschen, und wenn der Browser dann zu `https://myawesomeapp.com/api/v1/` wechselt, und Ihr Server (z. B. Uvicorn) auf `http://127.0.0.1:8000` lauscht, wÃŧrde der Proxy (ohne ein abgetrenntes Pfadpräfix) Ãŧber denselben Pfad auf Uvicorn zugreifen: `http://127.0.0.1:8000/api/v1/app`. +In einem solchen Fall (ohne ein abgetrenntes Pfadpräfix) wÃŧrde der Proxy auf etwas wie `https://myawesomeapp.com` lauschen, und wenn der Browser dann zu `https://myawesomeapp.com/api/v1/app` wechselt, und Ihr Server (z. B. Uvicorn) auf `http://127.0.0.1:8000` lauscht, wÃŧrde der Proxy (ohne ein abgetrenntes Pfadpräfix) Ãŧber denselben Pfad auf Uvicorn zugreifen: `http://127.0.0.1:8000/api/v1/app`. -## Lokal testen mit Traefik +## Lokal testen mit Traefik { #testing-locally-with-traefik } -Sie kÃļnnen das Experiment mit einem abgetrennten Pfadpräfix ganz einfach lokal ausfÃŧhren, indem Sie Traefik verwenden. +Sie kÃļnnen das Experiment mit einem abgetrennten Pfadpräfix einfach lokal ausfÃŧhren, indem Sie Traefik verwenden. Laden Sie Traefik herunter, es ist eine einzelne Binärdatei, Sie kÃļnnen die komprimierte Datei extrahieren und sie direkt vom Terminal aus ausfÃŧhren. @@ -205,7 +302,7 @@ Erstellen Sie nun die andere Datei `routes.toml`: Diese Datei konfiguriert Traefik, das Pfadpräfix `/api/v1` zu verwenden. -Und dann leitet Traefik seine Anfragen an Ihren Uvicorn weiter, der unter `http://127.0.0.1:8000` läuft. +Und dann leitet Traefik seine Requests an Ihren Uvicorn weiter, der unter `http://127.0.0.1:8000` läuft. Starten Sie nun Traefik: @@ -224,14 +321,14 @@ Und jetzt starten Sie Ihre Anwendung mit Uvicorn, indem Sie die Option `--root-p
```console -$ uvicorn main:app --root-path /api/v1 +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ```
-### Die Responses betrachten +### Die Responses testen { #check-the-responses } Wenn Sie nun zur URL mit dem Port fÃŧr Uvicorn gehen: http://127.0.0.1:8000/app, sehen Sie die normale Response: @@ -267,7 +364,7 @@ Und die von Uvicorn direkt bereitgestellte Version ohne Pfadpräfix (`http://127 Dies demonstriert, wie der Proxy (Traefik) das Pfadpräfix verwendet und wie der Server (Uvicorn) den `root_path` aus der Option `--root-path` verwendet. -### Es in der Dokumentationsoberfläche betrachten +### Es in der Dokumentationsoberfläche testen { #check-the-docs-ui } Jetzt folgt der spaßige Teil. ✨ @@ -287,7 +384,7 @@ Genau so, wie wir es wollten. âœ”ī¸ Dies liegt daran, dass FastAPI diesen `root_path` verwendet, um den Default-`server` in OpenAPI mit der von `root_path` bereitgestellten URL zu erstellen. -## Zusätzliche Server +## Zusätzliche Server { #additional-servers } /// warning | Achtung @@ -297,7 +394,7 @@ Dies ist ein fortgeschrittener Anwendungsfall. Überspringen Sie das gerne. Standardmäßig erstellt **FastAPI** einen `server` im OpenAPI-Schema mit der URL fÃŧr den `root_path`. -Sie kÃļnnen aber auch andere alternative `server` bereitstellen, beispielsweise wenn Sie mÃļchten, dass *dieselbe* Dokumentationsoberfläche mit einer Staging- und Produktionsumgebung interagiert. +Sie kÃļnnen aber auch andere alternative `servers` bereitstellen, beispielsweise wenn Sie mÃļchten, dass *dieselbe* Dokumentationsoberfläche mit einer Staging- und Produktionsumgebung interagiert. Wenn Sie eine benutzerdefinierte Liste von Servern (`servers`) Ãŧbergeben und es einen `root_path` gibt (da Ihre API hinter einem Proxy läuft), fÃŧgt **FastAPI** einen „Server“ mit diesem `root_path` am Anfang der Liste ein. @@ -346,7 +443,7 @@ Die Dokumentationsoberfläche interagiert mit dem von Ihnen ausgewählten Server /// -### Den automatischen Server von `root_path` deaktivieren +### Den automatischen Server von `root_path` deaktivieren { #disable-automatic-server-from-root-path } Wenn Sie nicht mÃļchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, kÃļnnen Sie den Parameter `root_path_in_servers=False` verwenden: @@ -354,7 +451,7 @@ Wenn Sie nicht mÃļchten, dass **FastAPI** einen automatischen Server inkludiert, Dann wird er nicht in das OpenAPI-Schema aufgenommen. -## Mounten einer Unteranwendung +## Mounten einer Unteranwendung { #mounting-a-sub-application } Wenn Sie gleichzeitig eine Unteranwendung mounten (wie beschrieben in [Unteranwendungen – Mounts](sub-applications.md){.internal-link target=_blank}) und einen Proxy mit `root_path` verwenden wollen, kÃļnnen Sie das normal tun, wie Sie es erwarten wÃŧrden. diff --git a/docs/de/docs/advanced/custom-response.md b/docs/de/docs/advanced/custom-response.md index 43cb55e04..8714086e5 100644 --- a/docs/de/docs/advanced/custom-response.md +++ b/docs/de/docs/advanced/custom-response.md @@ -1,12 +1,12 @@ -# Benutzerdefinierte Response – HTML, Stream, Datei, andere +# Benutzerdefinierte Response – HTML, Stream, Datei, andere { #custom-response-html-stream-file-others } -Standardmäßig gibt **FastAPI** die Responses mittels `JSONResponse` zurÃŧck. +Standardmäßig gibt **FastAPI** die Responses mittels `JSONResponse` zurÃŧck. -Sie kÃļnnen das Ãŧberschreiben, indem Sie direkt eine `Response` zurÃŧckgeben, wie in [Eine Response direkt zurÃŧckgeben](response-directly.md){.internal-link target=_blank} gezeigt. +Sie kÃļnnen dies Ãŧberschreiben, indem Sie direkt eine `Response` zurÃŧckgeben, wie in [Eine Response direkt zurÃŧckgeben](response-directly.md){.internal-link target=_blank} gezeigt. -Wenn Sie jedoch direkt eine `Response` zurÃŧckgeben, werden die Daten nicht automatisch konvertiert und die Dokumentation wird nicht automatisch generiert (zum Beispiel wird der spezifische „Medientyp“, der im HTTP-Header `Content-Type` angegeben ist, nicht Teil der generierten OpenAPI). +Wenn Sie jedoch direkt eine `Response` (oder eine Unterklasse wie `JSONResponse`) zurÃŧckgeben, werden die Daten nicht automatisch konvertiert (selbst wenn Sie ein `response_model` deklariert haben), und die Dokumentation wird nicht automatisch generiert (zum Beispiel wird der spezifische „Medientyp“, der im HTTP-Header `Content-Type` angegeben ist, nicht Teil der generierten OpenAPI). -Sie kÃļnnen aber auch die `Response`, die Sie verwenden mÃļchten, im *Pfadoperation-Dekorator* deklarieren. +Sie kÃļnnen jedoch auch die `Response`, die Sie verwenden mÃļchten (z. B. jede `Response`-Unterklasse), im *Pfadoperation-Dekorator* mit dem `response_class`-Parameter deklarieren. Der Inhalt, den Sie von Ihrer *Pfadoperation-Funktion* zurÃŧckgeben, wird in diese `Response` eingefÃŧgt. @@ -18,13 +18,13 @@ Wenn Sie eine Response-Klasse ohne Medientyp verwenden, erwartet FastAPI, dass I /// -## `ORJSONResponse` verwenden +## `ORJSONResponse` verwenden { #use-orjsonresponse } -Um beispielsweise noch etwas Leistung herauszuholen, kÃļnnen Sie `orjson` installieren und verwenden, und die Response als `ORJSONResponse` deklarieren. +Um beispielsweise noch etwas Leistung herauszuholen, kÃļnnen Sie `orjson` installieren und die Response als `ORJSONResponse` setzen. -Importieren Sie die `Response`-Klasse (-Unterklasse), die Sie verwenden mÃļchten, und deklarieren Sie sie im *Pfadoperation-Dekorator*. +Importieren Sie die `Response`-Klasse (Unterklasse), die Sie verwenden mÃļchten, und deklarieren Sie sie im *Pfadoperation-Dekorator*. -Bei umfangreichen Responses ist die direkte RÃŧckgabe einer `Response` viel schneller als ein Dictionary zurÃŧckzugeben. +Bei umfangreichen Responses ist die direkte RÃŧckgabe einer `Response` wesentlich schneller als ein Dictionary zurÃŧckzugeben. Das liegt daran, dass FastAPI standardmäßig jedes enthaltene Element ÃŧberprÃŧft und sicherstellt, dass es als JSON serialisierbar ist, und zwar unter Verwendung desselben [JSON-kompatiblen Encoders](../tutorial/encoder.md){.internal-link target=_blank}, der im Tutorial erläutert wurde. Dadurch kÃļnnen Sie **beliebige Objekte** zurÃŧckgeben, zum Beispiel Datenbankmodelle. @@ -32,7 +32,7 @@ Wenn Sie jedoch sicher sind, dass der von Ihnen zurÃŧckgegebene Inhalt **mit JSO {* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} -/// info +/// info | Info Der Parameter `response_class` wird auch verwendet, um den „Medientyp“ der Response zu definieren. @@ -44,11 +44,11 @@ Und er wird als solcher in OpenAPI dokumentiert. /// tip | Tipp -Die `ORJSONResponse` ist derzeit nur in FastAPI verfÃŧgbar, nicht in Starlette. +Die `ORJSONResponse` ist nur in FastAPI verfÃŧgbar, nicht in Starlette. /// -## HTML-Response +## HTML-Response { #html-response } Um eine Response mit HTML direkt von **FastAPI** zurÃŧckzugeben, verwenden Sie `HTMLResponse`. @@ -57,7 +57,7 @@ Um eine Response mit HTML direkt von **FastAPI** zurÃŧckzugeben, verwenden Sie ` {* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} -/// info +/// info | Info Der Parameter `response_class` wird auch verwendet, um den „Medientyp“ der Response zu definieren. @@ -67,7 +67,7 @@ Und er wird als solcher in OpenAPI dokumentiert. /// -### Eine `Response` zurÃŧckgeben +### Eine `Response` zurÃŧckgeben { #return-a-response } Wie in [Eine Response direkt zurÃŧckgeben](response-directly.md){.internal-link target=_blank} gezeigt, kÃļnnen Sie die Response auch direkt in Ihrer *Pfadoperation* Ãŧberschreiben, indem Sie diese zurÃŧckgeben. @@ -81,19 +81,19 @@ Eine `Response`, die direkt von Ihrer *Pfadoperation-Funktion* zurÃŧckgegeben wi /// -/// info +/// info | Info NatÃŧrlich stammen der eigentliche `Content-Type`-Header, der Statuscode, usw., aus dem `Response`-Objekt, das Sie zurÃŧckgegeben haben. /// -### In OpenAPI dokumentieren und `Response` Ãŧberschreiben +### In OpenAPI dokumentieren und `Response` Ãŧberschreiben { #document-in-openapi-and-override-response } Wenn Sie die Response innerhalb der Funktion Ãŧberschreiben und gleichzeitig den „Medientyp“ in OpenAPI dokumentieren mÃļchten, kÃļnnen Sie den `response_class`-Parameter verwenden UND ein `Response`-Objekt zurÃŧckgeben. -Die `response_class` wird dann nur zur Dokumentation der OpenAPI-Pfadoperation* verwendet, Ihre `Response` wird jedoch unverändert verwendet. +Die `response_class` wird dann nur zur Dokumentation der OpenAPI-*Pfadoperation* verwendet, Ihre `Response` wird jedoch unverändert verwendet. -#### Eine `HTMLResponse` direkt zurÃŧckgeben +#### Eine `HTMLResponse` direkt zurÃŧckgeben { #return-an-htmlresponse-directly } Es kÃļnnte zum Beispiel so etwas sein: @@ -107,7 +107,7 @@ Aber da Sie die `HTMLResponse` auch in der `response_class` Ãŧbergeben haben, we -## VerfÃŧgbare Responses +## VerfÃŧgbare Responses { #available-responses } Hier sind einige der verfÃŧgbaren Responses. @@ -121,7 +121,7 @@ Sie kÃļnnen auch `from starlette.responses import HTMLResponse` verwenden. /// -### `Response` +### `Response` { #response } Die Hauptklasse `Response`, alle anderen Responses erben von ihr. @@ -138,30 +138,42 @@ FastAPI (eigentlich Starlette) fÃŧgt automatisch einen Content-Length-Header ein {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} -### `HTMLResponse` +### `HTMLResponse` { #htmlresponse } Nimmt Text oder Bytes entgegen und gibt eine HTML-Response zurÃŧck, wie Sie oben gelesen haben. -### `PlainTextResponse` +### `PlainTextResponse` { #plaintextresponse } Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurÃŧck. {* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} -### `JSONResponse` +### `JSONResponse` { #jsonresponse } Nimmt einige Daten entgegen und gibt eine `application/json`-codierte Response zurÃŧck. Dies ist die Standard-Response, die in **FastAPI** verwendet wird, wie Sie oben gelesen haben. -### `ORJSONResponse` +### `ORJSONResponse` { #orjsonresponse } Eine schnelle alternative JSON-Response mit `orjson`, wie Sie oben gelesen haben. -### `UJSONResponse` +/// info | Info + +Dazu muss `orjson` installiert werden, z. B. mit `pip install orjson`. + +/// + +### `UJSONResponse` { #ujsonresponse } Eine alternative JSON-Response mit `ujson`. +/// info | Info + +Dazu muss `ujson` installiert werden, z. B. mit `pip install ujson`. + +/// + /// warning | Achtung `ujson` ist bei der Behandlung einiger Sonderfälle weniger sorgfältig als Pythons eingebaute Implementierung. @@ -176,7 +188,7 @@ MÃļglicherweise ist `ORJSONResponse` eine schnellere Alternative. /// -### `RedirectResponse` +### `RedirectResponse` { #redirectresponse } Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurÃŧck. Verwendet standardmäßig den Statuscode 307 – Temporäre Weiterleitung (Temporary Redirect). @@ -188,7 +200,6 @@ Sie kÃļnnen eine `RedirectResponse` direkt zurÃŧckgeben: Oder Sie kÃļnnen sie im Parameter `response_class` verwenden: - {* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *} Wenn Sie das tun, kÃļnnen Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurÃŧckgeben. @@ -201,26 +212,24 @@ Sie kÃļnnen den Parameter `status_code` auch in Kombination mit dem Parameter `r {* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} -### `StreamingResponse` +### `StreamingResponse` { #streamingresponse } Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody. {* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} -#### Verwendung von `StreamingResponse` mit dateiähnlichen Objekten +#### Verwendung von `StreamingResponse` mit dateiartigen Objekten { #using-streamingresponse-with-file-like-objects } -Wenn Sie ein dateiähnliches (file-like) Objekt haben (z. B. das von `open()` zurÃŧckgegebene Objekt), kÃļnnen Sie eine Generatorfunktion erstellen, um Ãŧber dieses dateiähnliche Objekt zu iterieren. +Wenn Sie ein dateiartiges (file-like) Objekt haben (z. B. das von `open()` zurÃŧckgegebene Objekt), kÃļnnen Sie eine Generatorfunktion erstellen, um Ãŧber dieses dateiartige Objekt zu iterieren. Auf diese Weise mÃŧssen Sie nicht alles zuerst in den Arbeitsspeicher lesen und kÃļnnen diese Generatorfunktion an `StreamingResponse` Ãŧbergeben und zurÃŧckgeben. Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen. -```{ .python .annotate hl_lines="2 10-12 14" } -{!../../docs_src/custom_response/tutorial008.py!} -``` +{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *} 1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält. -2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiähnliche Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist. +2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiartige Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist. 3. Dieses `yield from` weist die Funktion an, Ãŧber das Ding namens `file_like` zu iterieren. Und dann fÃŧr jeden iterierten Teil, diesen Teil so zurÃŧckzugeben, als wenn er aus dieser Generatorfunktion (`iterfile`) stammen wÃŧrde. Es handelt sich also hier um eine Generatorfunktion, die die „generierende“ Arbeit intern auf etwas anderes Ãŧberträgt. @@ -233,7 +242,7 @@ Beachten Sie, dass wir, da wir Standard-`open()` verwenden, welches `async` und /// -### `FileResponse` +### `FileResponse` { #fileresponse } Streamt eine Datei asynchron als Response. @@ -254,7 +263,7 @@ Sie kÃļnnen auch den Parameter `response_class` verwenden: In diesem Fall kÃļnnen Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurÃŧckgeben. -## Benutzerdefinierte Response-Klasse +## Benutzerdefinierte Response-Klasse { #custom-response-class } Sie kÃļnnen Ihre eigene benutzerdefinierte Response-Klasse erstellen, die von `Response` erbt und diese verwendet. @@ -282,7 +291,7 @@ Statt: NatÃŧrlich werden Sie wahrscheinlich viel bessere MÃļglichkeiten finden, Vorteil daraus zu ziehen, als JSON zu formatieren. 😉 -## Standard-Response-Klasse +## Standard-Response-Klasse { #default-response-class } Beim Erstellen einer **FastAPI**-Klasseninstanz oder eines `APIRouter`s kÃļnnen Sie angeben, welche Response-Klasse standardmäßig verwendet werden soll. @@ -298,6 +307,6 @@ Sie kÃļnnen dennoch weiterhin `response_class` in *Pfadoperationen* Ãŧberschreib /// -## Zusätzliche Dokumentation +## Zusätzliche Dokumentation { #additional-documentation } Sie kÃļnnen auch den Medientyp und viele andere Details in OpenAPI mit `responses` deklarieren: [Zusätzliche Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}. diff --git a/docs/de/docs/advanced/dataclasses.md b/docs/de/docs/advanced/dataclasses.md index 8e537c639..12ea8e9ec 100644 --- a/docs/de/docs/advanced/dataclasses.md +++ b/docs/de/docs/advanced/dataclasses.md @@ -1,24 +1,24 @@ -# Verwendung von Datenklassen +# Verwendung von Datenklassen { #using-dataclasses } -FastAPI basiert auf **Pydantic** und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden kÃļnnen, um Requests und Responses zu deklarieren. +FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden kÃļnnen, um Requests und Responses zu deklarieren. Aber FastAPI unterstÃŧtzt auf die gleiche Weise auch die Verwendung von `dataclasses`: {* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *} -Das ist dank **Pydantic** ebenfalls mÃļglich, da es `dataclasses` intern unterstÃŧtzt. +Das ist dank **Pydantic** ebenfalls mÃļglich, da es `dataclasses` intern unterstÃŧtzt. -Auch wenn im obige Code Pydantic nicht explizit vorkommt, verwendet FastAPI Pydantic, um diese Standard-Datenklassen in Pydantics eigene Variante von Datenklassen zu konvertieren. +Auch wenn im obigen Code Pydantic nicht explizit vorkommt, verwendet FastAPI Pydantic, um diese Standard-Datenklassen in Pydantics eigene Variante von Datenklassen zu konvertieren. Und natÃŧrlich wird das gleiche unterstÃŧtzt: -* Validierung der Daten -* Serialisierung der Daten -* Dokumentation der Daten, usw. +* Datenvalidierung +* Datenserialisierung +* Datendokumentation, usw. Das funktioniert genauso wie mit Pydantic-Modellen. Und tatsächlich wird es unter der Haube mittels Pydantic auf die gleiche Weise bewerkstelligt. -/// info +/// info | Info Bedenken Sie, dass Datenklassen nicht alles kÃļnnen, was Pydantic-Modelle kÃļnnen. @@ -28,7 +28,7 @@ Wenn Sie jedoch eine Menge Datenklassen herumliegen haben, ist dies ein guter Tr /// -## Datenklassen als `response_model` +## Datenklassen in `response_model` { #dataclasses-in-response-model } Sie kÃļnnen `dataclasses` auch im Parameter `response_model` verwenden: @@ -40,7 +40,7 @@ Auf diese Weise wird deren Schema in der Benutzeroberfläche der API-Dokumentati -## Datenklassen in verschachtelten Datenstrukturen +## Datenklassen in verschachtelten Datenstrukturen { #dataclasses-in-nested-data-structures } Sie kÃļnnen `dataclasses` auch mit anderen Typannotationen kombinieren, um verschachtelte Datenstrukturen zu erstellen. @@ -62,7 +62,7 @@ In diesem Fall kÃļnnen Sie einfach die Standard-`dataclasses` durch `pydantic.da In diesem Fall handelt es sich um eine Liste von `Item`-Datenklassen. -6. Hier geben wir ein Dictionary zurÃŧck, das `items` enthält, welches eine Liste von Datenklassen ist. +6. Hier geben wir ein Dictionary zurÃŧck, das `items` enthält, welches eine Liste von Datenklassen ist. FastAPI ist weiterhin in der Lage, die Daten nach JSON zu serialisieren. @@ -74,7 +74,7 @@ In diesem Fall kÃļnnen Sie einfach die Standard-`dataclasses` durch `pydantic.da Wie immer kÃļnnen Sie in FastAPI `def` und `async def` beliebig kombinieren. - Wenn Sie eine Auffrischung darÃŧber benÃļtigen, wann welche Anwendung sinnvoll ist, lesen Sie den Abschnitt „In Eile?“ in der Dokumentation zu [`async` und `await`](../async.md#in-eile){.internal-link target=_blank}. + Wenn Sie eine Auffrischung darÃŧber benÃļtigen, wann welche Anwendung sinnvoll ist, lesen Sie den Abschnitt „In Eile?“ in der Dokumentation zu [`async` und `await`](../async.md#in-a-hurry){.internal-link target=_blank}. 9. Diese *Pfadoperation-Funktion* gibt keine Datenklassen zurÃŧck (obwohl dies mÃļglich wäre), sondern eine Liste von Dictionarys mit internen Daten. @@ -84,12 +84,12 @@ Sie kÃļnnen `dataclasses` mit anderen Typannotationen auf vielfältige Weise kom Weitere Einzelheiten finden Sie in den Bemerkungen im Quellcode oben. -## Mehr erfahren +## Mehr erfahren { #learn-more } Sie kÃļnnen `dataclasses` auch mit anderen Pydantic-Modellen kombinieren, von ihnen erben, sie in Ihre eigenen Modelle einbinden, usw. -Weitere Informationen finden Sie in der Pydantic-Dokumentation zu Datenklassen. +Weitere Informationen finden Sie in der Pydantic-Dokumentation zu Datenklassen. -## Version +## Version { #version } Dies ist verfÃŧgbar seit FastAPI-Version `0.67.0`. 🔖 diff --git a/docs/de/docs/advanced/events.md b/docs/de/docs/advanced/events.md index 65fc9e484..2ceef1190 100644 --- a/docs/de/docs/advanced/events.md +++ b/docs/de/docs/advanced/events.md @@ -1,14 +1,14 @@ -# Lifespan-Events +# Lifespan-Events { #lifespan-events } -Sie kÃļnnen Logik (Code) definieren, die ausgefÃŧhrt werden soll, bevor die Anwendung **hochfährt**. Dies bedeutet, dass dieser Code **einmal** ausgefÃŧhrt wird, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**. +Sie kÃļnnen Logik (Code) definieren, die ausgefÃŧhrt werden soll, bevor die Anwendung **hochfährt**. Dies bedeutet, dass dieser Code **einmal** ausgefÃŧhrt wird, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**. Auf die gleiche Weise kÃļnnen Sie Logik (Code) definieren, die ausgefÃŧhrt werden soll, wenn die Anwendung **heruntergefahren** wird. In diesem Fall wird dieser Code **einmal** ausgefÃŧhrt, **nachdem** mÃļglicherweise **viele Requests** bearbeitet wurden. -Da dieser Code ausgefÃŧhrt wird, bevor die Anwendung **beginnt**, Requests entgegenzunehmen, und unmittelbar, nachdem sie die Bearbeitung von Requests **abgeschlossen hat**, deckt er die gesamte **Lebensdauer – „Lifespan“** – der Anwendung ab (das Wort „Lifespan“ wird gleich wichtig sein 😉). +Da dieser Code ausgefÃŧhrt wird, bevor die Anwendung **beginnt**, Requests entgegenzunehmen, und unmittelbar, nachdem sie die Bearbeitung von Requests **abgeschlossen hat**, deckt er den gesamten Anwendungs-**Lifespan** ab (das Wort „Lifespan“ wird gleich wichtig sein 😉). -Dies kann sehr nÃŧtzlich sein, um **Ressourcen** einzurichten, die Sie in der gesamten Anwendung verwenden wollen und die von Requests **gemeinsam genutzt** werden und/oder die Sie anschließend **aufräumen** mÃŧssen. Zum Beispiel ein Pool von Datenbankverbindungen oder das Laden eines gemeinsam genutzten Modells fÃŧr maschinelles Lernen. +Dies kann sehr nÃŧtzlich sein, um **Ressourcen** einzurichten, die Sie in der gesamten App verwenden wollen und die von Requests **gemeinsam genutzt** werden und/oder die Sie anschließend **aufräumen** mÃŧssen. Zum Beispiel ein Pool von Datenbankverbindungen oder das Laden eines gemeinsam genutzten Modells fÃŧr maschinelles Lernen. -## Anwendungsfall +## Anwendungsfall { #use-case } Beginnen wir mit einem Beispiel-**Anwendungsfall** und schauen uns dann an, wie wir ihn mit dieser Methode implementieren kÃļnnen. @@ -22,9 +22,9 @@ Sie kÃļnnten das auf der obersten Ebene des Moduls/der Datei machen, aber das w Das wollen wir besser machen: Laden wir das Modell, bevor die Requests bearbeitet werden, aber unmittelbar bevor die Anwendung beginnt, Requests zu empfangen, und nicht, während der Code geladen wird. -## Lifespan +## Lifespan { #lifespan } -Sie kÃļnnen diese Logik beim *Hochfahren* und *Herunterfahren* mithilfe des `lifespan`-Parameters der `FastAPI`-App und eines „Kontextmanagers“ definieren (ich zeige Ihnen gleich, was das ist). +Sie kÃļnnen diese Logik beim *Startup* und *Shutdown* mithilfe des `lifespan`-Parameters der `FastAPI`-App und eines „Kontextmanagers“ definieren (ich zeige Ihnen gleich, was das ist). Beginnen wir mit einem Beispiel und sehen es uns dann im Detail an. @@ -32,19 +32,19 @@ Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt: {* ../../docs_src/events/tutorial003.py hl[16,19] *} -Hier simulieren wir das langsame *Hochfahren*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das Dictionary mit Modellen fÃŧr maschinelles Lernen einfÃŧgen. Dieser Code wird ausgefÃŧhrt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Hochfahrens*. +Hier simulieren wir den langsamen *Startup*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das Dictionary mit Modellen fÃŧr maschinelles Lernen einfÃŧgen. Dieser Code wird ausgefÃŧhrt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*. -Und dann, direkt nach dem `yield`, entladen wir das Modell. Dieser Code wird unmittelbar vor dem *Herunterfahren* ausgefÃŧhrt, **nachdem** die Anwendung **die Bearbeitung von Requests abgeschlossen hat**. Dadurch kÃļnnten beispielsweise Ressourcen wie Arbeitsspeicher oder eine GPU freigegeben werden. +Und dann, direkt nach dem `yield`, entladen wir das Modell. Dieser Code wird ausgefÃŧhrt, **nachdem** die Anwendung **die Bearbeitung von Requests abgeschlossen hat**, direkt vor dem *Shutdown*. Dadurch kÃļnnten beispielsweise Ressourcen wie Arbeitsspeicher oder eine GPU freigegeben werden. /// tip | Tipp -Das *Herunterfahren* wÃŧrde erfolgen, wenn Sie die Anwendung **stoppen**. +Das `shutdown` wÃŧrde erfolgen, wenn Sie die Anwendung **stoppen**. MÃļglicherweise mÃŧssen Sie eine neue Version starten, oder Sie haben es einfach satt, sie auszufÃŧhren. 🤷 /// -### Lifespan-Funktion +### Lifespan-Funktion { #lifespan-function } Das Erste, was auffällt, ist, dass wir eine asynchrone Funktion mit `yield` definieren. Das ist sehr ähnlich zu Abhängigkeiten mit `yield`. @@ -54,7 +54,7 @@ Der erste Teil der Funktion, vor dem `yield`, wird ausgefÃŧhrt **bevor** die Anw Und der Teil nach `yield` wird ausgefÃŧhrt, **nachdem** die Anwendung beendet ist. -### Asynchroner Kontextmanager +### Asynchroner Kontextmanager { #async-context-manager } Wie Sie sehen, ist die Funktion mit einem `@asynccontextmanager` versehen. @@ -84,23 +84,23 @@ Der Parameter `lifespan` der `FastAPI`-App benÃļtigt einen **asynchronen Kontext {* ../../docs_src/events/tutorial003.py hl[22] *} -## Alternative Events (deprecated) +## Alternative Events (deprecatet) { #alternative-events-deprecated } /// warning | Achtung -Der empfohlene Weg, das *Hochfahren* und *Herunterfahren* zu handhaben, ist die Verwendung des `lifespan`-Parameters der `FastAPI`-App, wie oben beschrieben. Wenn Sie einen `lifespan`-Parameter Ãŧbergeben, werden die `startup`- und `shutdown`-Eventhandler nicht mehr aufgerufen. Es ist entweder alles `lifespan` oder alles Events, nicht beides. +Der empfohlene Weg, den *Startup* und *Shutdown* zu handhaben, ist die Verwendung des `lifespan`-Parameters der `FastAPI`-App, wie oben beschrieben. Wenn Sie einen `lifespan`-Parameter Ãŧbergeben, werden die `startup`- und `shutdown`-Eventhandler nicht mehr aufgerufen. Es ist entweder alles `lifespan` oder alles Events, nicht beides. Sie kÃļnnen diesen Teil wahrscheinlich Ãŧberspringen. /// -Es gibt eine alternative MÃļglichkeit, diese Logik zu definieren, sodass sie beim *Hochfahren* und beim *Herunterfahren* ausgefÃŧhrt wird. +Es gibt eine alternative MÃļglichkeit, diese Logik zu definieren, sodass sie beim *Startup* und beim *Shutdown* ausgefÃŧhrt wird. -Sie kÃļnnen Eventhandler (Funktionen) definieren, die ausgefÃŧhrt werden sollen, bevor die Anwendung hochgefahren wird oder wenn die Anwendung heruntergefahren wird. +Sie kÃļnnen Eventhandler (Funktionen) definieren, die ausgefÃŧhrt werden sollen, bevor die Anwendung hochgefahren wird oder wenn die Anwendung heruntergefahren wird. Diese Funktionen kÃļnnen mit `async def` oder normalem `def` deklariert werden. -### `startup`-Event +### `startup`-Event { #startup-event } Um eine Funktion hinzuzufÃŧgen, die vor dem Start der Anwendung ausgefÃŧhrt werden soll, deklarieren Sie diese mit dem Event `startup`: @@ -110,17 +110,17 @@ In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenban Sie kÃļnnen mehr als eine Eventhandler-Funktion hinzufÃŧgen. -Und Ihre Anwendung empfängt erst dann Anfragen, wenn alle `startup`-Eventhandler abgeschlossen sind. +Und Ihre Anwendung empfängt erst dann Requests, wenn alle `startup`-Eventhandler abgeschlossen sind. -### `shutdown`-Event +### `shutdown`-Event { #shutdown-event } -Um eine Funktion hinzuzufÃŧgen, die beim Herunterfahren der Anwendung ausgefÃŧhrt werden soll, deklarieren Sie sie mit dem Event `shutdown`: +Um eine Funktion hinzuzufÃŧgen, die beim Shutdown der Anwendung ausgefÃŧhrt werden soll, deklarieren Sie sie mit dem Event `shutdown`: {* ../../docs_src/events/tutorial002.py hl[6] *} Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`. -/// info +/// info | Info In der Funktion `open()` bedeutet `mode="a"` „append“ („anhängen“), sodass die Zeile nach dem, was sich in dieser Datei befindet, hinzugefÃŧgt wird, ohne den vorherigen Inhalt zu Ãŧberschreiben. @@ -138,21 +138,21 @@ Daher deklarieren wir die Eventhandler-Funktion mit Standard-`def` statt mit `as /// -### `startup` und `shutdown` zusammen +### `startup` und `shutdown` zusammen { #startup-and-shutdown-together } -Es besteht eine hohe Wahrscheinlichkeit, dass die Logik fÃŧr Ihr *Hochfahren* und *Herunterfahren* miteinander verknÃŧpft ist. Vielleicht mÃļchten Sie etwas beginnen und es dann beenden, eine Ressource laden und sie dann freigeben usw. +Es besteht eine hohe Wahrscheinlichkeit, dass die Logik fÃŧr Ihr *Startup* und *Shutdown* miteinander verknÃŧpft ist. Vielleicht mÃļchten Sie etwas beginnen und es dann beenden, eine Ressource laden und sie dann freigeben usw. Bei getrennten Funktionen, die keine gemeinsame Logik oder Variablen haben, ist dies schwieriger, da Sie Werte in globalen Variablen speichern oder ähnliche Tricks verwenden mÃŧssen. Aus diesem Grund wird jetzt empfohlen, stattdessen `lifespan` wie oben erläutert zu verwenden. -## Technische Details +## Technische Details { #technical-details } Nur ein technisches Detail fÃŧr die neugierigen Nerds. 🤓 In der technischen ASGI-Spezifikation ist dies Teil des Lifespan Protokolls und definiert Events namens `startup` und `shutdown`. -/// info +/// info | Info Weitere Informationen zu Starlettes `lifespan`-Handlern finden Sie in Starlettes Lifespan-Dokumentation. @@ -160,6 +160,6 @@ Einschließlich, wie man Lifespan-Zustand handhabt, der in anderen Bereichen Ihr /// -## Unteranwendungen +## Unteranwendungen { #sub-applications } -🚨 Beachten Sie, dass diese Lifespan-Events (Hochfahren und Herunterfahren) nur fÃŧr die Hauptanwendung ausgefÃŧhrt werden, nicht fÃŧr [Unteranwendungen – Mounts](sub-applications.md){.internal-link target=_blank}. +🚨 Beachten Sie, dass diese Lifespan-Events (Startup und Shutdown) nur fÃŧr die Hauptanwendung ausgefÃŧhrt werden, nicht fÃŧr [Unteranwendungen – Mounts](sub-applications.md){.internal-link target=_blank}. diff --git a/docs/de/docs/advanced/generate-clients.md b/docs/de/docs/advanced/generate-clients.md index f491d29af..d8836295b 100644 --- a/docs/de/docs/advanced/generate-clients.md +++ b/docs/de/docs/advanced/generate-clients.md @@ -1,121 +1,86 @@ -# Clients generieren +# SDKs generieren { #generating-sdks } -Da **FastAPI** auf der OpenAPI-Spezifikation basiert, erhalten Sie automatische Kompatibilität mit vielen Tools, einschließlich der automatischen API-Dokumentation (bereitgestellt von Swagger UI). +Da **FastAPI** auf der **OpenAPI**-Spezifikation basiert, kÃļnnen dessen APIs in einem standardisierten Format beschrieben werden, das viele Tools verstehen. -Ein besonderer Vorteil, der nicht unbedingt offensichtlich ist, besteht darin, dass Sie fÃŧr Ihre API **Clients generieren** kÃļnnen (manchmal auch **SDKs** genannt), fÃŧr viele verschiedene **Programmiersprachen**. +Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (**SDKs**) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben. -## OpenAPI-Client-Generatoren +In diesem Leitfaden erfahren Sie, wie Sie ein **TypeScript-SDK** fÃŧr Ihr FastAPI-Backend generieren. -Es gibt viele Tools zum Generieren von Clients aus **OpenAPI**. +## Open Source SDK-Generatoren { #open-source-sdk-generators } -Ein gängiges Tool ist OpenAPI Generator. +Eine vielseitige MÃļglichkeit ist der OpenAPI Generator, der **viele Programmiersprachen** unterstÃŧtzt und SDKs aus Ihrer OpenAPI-Spezifikation generieren kann. -Wenn Sie ein **Frontend** erstellen, ist openapi-ts eine sehr interessante Alternative. +FÃŧr **TypeScript-Clients** ist Hey API eine speziell entwickelte LÃļsung, die ein optimiertes Erlebnis fÃŧr das TypeScript-Ökosystem bietet. -## Client- und SDK-Generatoren – Sponsor +Weitere SDK-Generatoren finden Sie auf OpenAPI.Tools. -Es gibt auch einige **vom Unternehmen entwickelte** Client- und SDK-Generatoren, die auf OpenAPI (FastAPI) basieren. In einigen Fällen kÃļnnen diese Ihnen **weitere Funktionalität** zusätzlich zu qualitativ hochwertigen generierten SDKs/Clients bieten. +/// tip | Tipp -Einige von diesen ✨ [**sponsern FastAPI**](../help-fastapi.md#den-autor-sponsern){.internal-link target=_blank} ✨, das gewährleistet die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem**. +FastAPI generiert automatisch **OpenAPI 3.1**-Spezifikationen, daher muss jedes von Ihnen verwendete Tool diese Version unterstÃŧtzen. -Und es zeigt deren wahres Engagement fÃŧr FastAPI und seine **Community** (Sie), da diese Ihnen nicht nur einen **guten Service** bieten mÃļchten, sondern auch sicherstellen mÃļchten, dass Sie Ãŧber ein **gutes und gesundes Framework** verfÃŧgen, FastAPI. 🙇 +/// -Beispielsweise kÃļnnten Sie Speakeasy ausprobieren. +## SDK-Generatoren von FastAPI-Sponsoren { #sdk-generators-from-fastapi-sponsors } -Es gibt auch mehrere andere Unternehmen, welche ähnliche Dienste anbieten und die Sie online suchen und finden kÃļnnen. 🤓 +Dieser Abschnitt hebt **venture-unterstÃŧtzte** und **firmengestÃŧtzte** LÃļsungen hervor, die von Unternehmen entwickelt werden, welche FastAPI sponsern. Diese Produkte bieten **zusätzliche Funktionen** und **Integrationen** zusätzlich zu hochwertig generierten SDKs. -## Einen TypeScript-Frontend-Client generieren +Durch das ✨ [**Sponsoring von FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ helfen diese Unternehmen sicherzustellen, dass das Framework und sein **Ökosystem** gesund und **nachhaltig** bleiben. + +Ihr Sponsoring zeigt auch ein starkes Engagement fÃŧr die FastAPI-**Community** (Sie), was bedeutet, dass sie nicht nur einen **großartigen Service** bieten mÃļchten, sondern auch ein **robustes und florierendes Framework**, FastAPI, unterstÃŧtzen mÃļchten. 🙇 + +Zum Beispiel kÃļnnten Sie ausprobieren: + +* Speakeasy +* Stainless +* liblab + +Einige dieser LÃļsungen sind mÃļglicherweise auch Open Source oder bieten kostenlose Tarife an, sodass Sie diese ohne finanzielle Verpflichtung ausprobieren kÃļnnen. Andere kommerzielle SDK-Generatoren sind online verfÃŧgbar und kÃļnnen dort gefunden werden. 🤓 + +## Ein TypeScript-SDK erstellen { #create-a-typescript-sdk } Beginnen wir mit einer einfachen FastAPI-Anwendung: {* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *} -Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, welche diese fÃŧr die Request- und Response-Payload verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden. +Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, die sie fÃŧr die Request- und Response-Payload verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden. -### API-Dokumentation +### API-Dokumentation { #api-docs } -Wenn Sie zur API-Dokumentation gehen, werden Sie sehen, dass diese die **Schemas** fÃŧr die Daten enthält, welche in Requests gesendet und in Responses empfangen werden: +Wenn Sie zu `/docs` gehen, sehen Sie, dass es die **Schemas** fÃŧr die Daten enthält, die in Requests gesendet und in Responses empfangen werden: -Sie kÃļnnen diese Schemas sehen, da sie mit den Modellen in der Anwendung deklariert wurden. +Sie kÃļnnen diese Schemas sehen, da sie mit den Modellen in der App deklariert wurden. -Diese Informationen sind im **OpenAPI-Schema** der Anwendung verfÃŧgbar und werden dann in der API-Dokumentation angezeigt (von Swagger UI). +Diese Informationen sind im **OpenAPI-Schema** der Anwendung verfÃŧgbar und werden in der API-Dokumentation angezeigt. -Und dieselben Informationen aus den Modellen, die in OpenAPI enthalten sind, kÃļnnen zum **Generieren des Client-Codes** verwendet werden. +Diese Informationen aus den Modellen, die in OpenAPI enthalten sind, kÃļnnen verwendet werden, um **den Client-Code zu generieren**. -### Einen TypeScript-Client generieren +### Hey API { #hey-api } -Nachdem wir nun die Anwendung mit den Modellen haben, kÃļnnen wir den Client-Code fÃŧr das Frontend generieren. +Sobald wir eine FastAPI-App mit den Modellen haben, kÃļnnen wir Hey API verwenden, um einen TypeScript-Client zu generieren. Der schnellste Weg das zu tun, ist Ãŧber npx. -#### `openapi-ts` installieren - -Sie kÃļnnen `openapi-ts` in Ihrem Frontend-Code installieren mit: - -
- -```console -$ npm install @hey-api/openapi-ts --save-dev - ----> 100% +```sh +npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client ``` -
+Dies generiert ein TypeScript-SDK in `./src/client`. -#### Client-Code generieren +Sie kÃļnnen lernen, wie man `@hey-api/openapi-ts` installiert und Ãŧber die erzeugte Ausgabe auf deren Website lesen. -Um den Client-Code zu generieren, kÃļnnen Sie das Kommandozeilentool `openapi-ts` verwenden, das soeben installiert wurde. +### Das SDK verwenden { #using-the-sdk } -Da es im lokalen Projekt installiert ist, kÃļnnten Sie diesen Befehl wahrscheinlich nicht direkt aufrufen, sondern wÃŧrden ihn in Ihre Datei `package.json` einfÃŧgen. - -Diese kÃļnnte so aussehen: - -```JSON hl_lines="7" -{ - "name": "frontend-app", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios" - }, - "author": "", - "license": "", - "devDependencies": { - "@hey-api/openapi-ts": "^0.27.38", - "typescript": "^4.6.2" - } -} -``` - -Nachdem Sie das NPM-Skript `generate-client` dort stehen haben, kÃļnnen Sie es ausfÃŧhren mit: - -
- -```console -$ npm run generate-client - -frontend-app@1.0.0 generate-client /home/user/code/frontend-app -> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios -``` - -
- -Dieser Befehl generiert Code in `./src/client` und verwendet intern `axios` (die Frontend-HTTP-Bibliothek). - -### Den Client-Code ausprobieren - -Jetzt kÃļnnen Sie den Client-Code importieren und verwenden. Er kÃļnnte wie folgt aussehen, beachten Sie, dass Sie automatische Codevervollständigung fÃŧr die Methoden erhalten: +Jetzt kÃļnnen Sie den Client-Code importieren und verwenden. Er kÃļnnte wie folgt aussehen, beachten Sie, dass Sie eine automatische Vervollständigung fÃŧr die Methoden erhalten: -Sie erhalten außerdem automatische Vervollständigung fÃŧr die zu sendende Payload: +Sie werden auch eine automatische Vervollständigung fÃŧr die zu sendende Payload erhalten: /// tip | Tipp -Beachten Sie die automatische Vervollständigung fÃŧr `name` und `price`, welche in der FastAPI-Anwendung im `Item`-Modell definiert wurden. +Beachten Sie die automatische Vervollständigung fÃŧr `name` und `price`, die in der FastAPI-Anwendung im `Item`-Modell definiert wurden. /// @@ -127,17 +92,17 @@ Das Response-Objekt hat auch automatische Vervollständigung: -## FastAPI-Anwendung mit Tags +## FastAPI-Anwendung mit Tags { #fastapi-app-with-tags } -In vielen Fällen wird Ihre FastAPI-Anwendung grÃļßer sein und Sie werden wahrscheinlich Tags verwenden, um verschiedene Gruppen von *Pfadoperationen* zu separieren. +In vielen Fällen wird Ihre FastAPI-App grÃļßer sein und Sie werden wahrscheinlich Tags verwenden, um verschiedene Gruppen von *Pfadoperationen* zu separieren. -Beispielsweise kÃļnnten Sie einen Abschnitt fÃŧr **Items (Artikel)** und einen weiteren Abschnitt fÃŧr **Users (Benutzer)** haben, und diese kÃļnnten durch Tags getrennt sein: +Zum Beispiel kÃļnnten Sie einen Abschnitt fÃŧr **Items (Artikel)** und einen weiteren Abschnitt fÃŧr **Users (Benutzer)** haben, und diese kÃļnnten durch Tags getrennt sein: {* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *} -### Einen TypeScript-Client mit Tags generieren +### Einen TypeScript-Client mit Tags generieren { #generate-a-typescript-client-with-tags } -Wenn Sie unter Verwendung von Tags einen Client fÃŧr eine FastAPI-Anwendung generieren, wird normalerweise auch der Client-Code anhand der Tags getrennt. +Wenn Sie einen Client fÃŧr eine FastAPI-App generieren, die Tags verwendet, wird normalerweise der Client-Code auch anhand der Tags getrennt. Auf diese Weise kÃļnnen Sie die Dinge fÃŧr den Client-Code richtig ordnen und gruppieren: @@ -148,7 +113,7 @@ In diesem Fall haben Sie: * `ItemsService` * `UsersService` -### Client-Methodennamen +### Client-Methodennamen { #client-method-names } Im Moment sehen die generierten Methodennamen wie `createItemItemsPost` nicht sehr sauber aus: @@ -158,31 +123,31 @@ ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) ... das liegt daran, dass der Client-Generator fÃŧr jede *Pfadoperation* die OpenAPI-interne **Operation-ID** verwendet. -OpenAPI erfordert, dass jede Operation-ID innerhalb aller *Pfadoperationen* eindeutig ist. Daher verwendet FastAPI den **Funktionsnamen**, den **Pfad** und die **HTTP-Methode/-Operation**, um diese Operation-ID zu generieren. Denn so kann sichergestellt werden, dass die Operation-IDs eindeutig sind. +OpenAPI erfordert, dass jede Operation-ID innerhalb aller *Pfadoperationen* einzigartig ist. Daher verwendet FastAPI den **Funktionsnamen**, den **Pfad** und die **HTTP-Methode/-Operation**, um diese Operation-ID zu generieren. Denn so kann sichergestellt werden, dass die Operation-IDs einzigartig sind. -Aber ich zeige Ihnen als nächstes, wie Sie das verbessern kÃļnnen. 🤓 +Aber ich zeige Ihnen als Nächstes, wie Sie das verbessern kÃļnnen. 🤓 -## Benutzerdefinierte Operation-IDs und bessere Methodennamen +## Benutzerdefinierte Operation-IDs und bessere Methodennamen { #custom-operation-ids-and-better-method-names } Sie kÃļnnen die Art und Weise, wie diese Operation-IDs **generiert** werden, **ändern**, um sie einfacher zu machen und **einfachere Methodennamen** in den Clients zu haben. -In diesem Fall mÃŧssen Sie auf andere Weise sicherstellen, dass jede Operation-ID **eindeutig** ist. +In diesem Fall mÃŧssen Sie auf andere Weise sicherstellen, dass jede Operation-ID **einzigartig** ist. -Sie kÃļnnten beispielsweise sicherstellen, dass jede *Pfadoperation* einen Tag hat, und dann die Operation-ID basierend auf dem **Tag** und dem **Namen** der *Pfadoperation* (dem Funktionsnamen) generieren. +Zum Beispiel kÃļnnten Sie sicherstellen, dass jede *Pfadoperation* einen Tag hat, und dann die Operation-ID basierend auf dem **Tag** und dem *Pfadoperation*-**Namen** (dem Funktionsnamen) generieren. -### Funktion zum Generieren einer eindeutigen ID erstellen +### Eine benutzerdefinierte Funktion zur Erzeugung einer eindeutigen ID erstellen { #custom-generate-unique-id-function } -FastAPI verwendet eine **eindeutige ID** fÃŧr jede *Pfadoperation*, diese wird fÃŧr die **Operation-ID** und auch fÃŧr die Namen aller benÃļtigten benutzerdefinierten Modelle fÃŧr Requests oder Responses verwendet. +FastAPI verwendet eine **eindeutige ID** fÃŧr jede *Pfadoperation*, die fÃŧr die **Operation-ID** und auch fÃŧr die Namen aller benÃļtigten benutzerdefinierten Modelle fÃŧr Requests oder Responses verwendet wird. -Sie kÃļnnen diese Funktion anpassen. Sie nimmt eine `APIRoute` und gibt einen String zurÃŧck. +Sie kÃļnnen diese Funktion anpassen. Sie nimmt ein `APIRoute` und gibt einen String zurÃŧck. -Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur einen Tag haben) und den Namen der *Pfadoperation* (den Funktionsnamen). +Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur einen Tag haben) und den *Pfadoperation*-Namen (den Funktionsnamen). -Anschließend kÃļnnen Sie diese benutzerdefinierte Funktion als Parameter `generate_unique_id_function` an **FastAPI** Ãŧbergeben: +Anschließend kÃļnnen Sie diese benutzerdefinierte Funktion als `generate_unique_id_function`-Parameter an **FastAPI** Ãŧbergeben: {* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *} -### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren +### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren { #generate-a-typescript-client-with-custom-operation-ids } Wenn Sie nun den Client erneut generieren, werden Sie feststellen, dass er Ãŧber die verbesserten Methodennamen verfÃŧgt: @@ -190,17 +155,17 @@ Wenn Sie nun den Client erneut generieren, werden Sie feststellen, dass er Ãŧber Wie Sie sehen, haben die Methodennamen jetzt den Tag und dann den Funktionsnamen, aber keine Informationen aus dem URL-Pfad und der HTTP-Operation. -### Vorab-Modifikation der OpenAPI-Spezifikation fÃŧr den Client-Generator +### Die OpenAPI-Spezifikation fÃŧr den Client-Generator vorab modifizieren { #preprocess-the-openapi-specification-for-the-client-generator } -Der generierte Code enthält immer noch etwas **verdoppelte Information**. +Der generierte Code enthält immer noch einige **verdoppelte Informationen**. -Wir wissen bereits, dass diese Methode mit den **Items** zusammenhängt, da sich dieses Wort in `ItemsService` befindet (vom Tag Ãŧbernommen), aber wir haben auch immer noch den Tagnamen im Methodennamen vorangestellt. 😕 +Wir wissen bereits, dass diese Methode mit den **Items** zusammenhängt, weil dieses Wort in `ItemsService` enthalten ist (vom Tag Ãŧbernommen), aber wir haben den Tag-Namen dennoch im Methodennamen vorangestellt. 😕 -Wir werden das wahrscheinlich weiterhin fÃŧr OpenAPI im Allgemeinen beibehalten wollen, da dadurch sichergestellt wird, dass die Operation-IDs **eindeutig** sind. +Wir werden das wahrscheinlich weiterhin fÃŧr OpenAPI allgemein beibehalten wollen, da dadurch sichergestellt wird, dass die Operation-IDs **einzigartig** sind. Aber fÃŧr den generierten Client kÃļnnten wir die OpenAPI-Operation-IDs direkt vor der Generierung der Clients **modifizieren**, um diese Methodennamen schÃļner und **sauberer** zu machen. -Wir kÃļnnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den vorangestellten Tag entfernen**: +Wir kÃļnnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den präfixierten Tag entfernen**: {* ../../docs_src/generate_clients/tutorial004.py *} @@ -214,44 +179,30 @@ Wir kÃļnnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dan Damit wÃŧrden die Operation-IDs von Dingen wie `items-get_items` in `get_items` umbenannt, sodass der Client-Generator einfachere Methodennamen generieren kann. -### Einen TypeScript-Client mit der modifizierten OpenAPI generieren +### Einen TypeScript-Client mit der modifizierten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi } -Da das Endergebnis nun in einer Datei `openapi.json` vorliegt, wÃŧrden Sie die `package.json` ändern, um diese lokale Datei zu verwenden, zum Beispiel: +Da das Endergebnis nun in einer `openapi.json`-Datei vorliegt, mÃŧssen Sie Ihren Eingabeort aktualisieren: -```JSON hl_lines="7" -{ - "name": "frontend-app", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios" - }, - "author": "", - "license": "", - "devDependencies": { - "@hey-api/openapi-ts": "^0.27.38", - "typescript": "^4.6.2" - } -} +```sh +npx @hey-api/openapi-ts -i ./openapi.json -o src/client ``` -Nach der Generierung des neuen Clients hätten Sie nun **saubere Methodennamen** mit allen **Autovervollständigungen**, **Inline-Fehlerberichten**, usw.: +Nach der Generierung des neuen Clients haben Sie jetzt **saubere Methodennamen**, mit allen **Autovervollständigungen**, **Inline-Fehlerberichten**, usw.: -## Vorteile +## Vorteile { #benefits } -Wenn Sie die automatisch generierten Clients verwenden, erhalten Sie **automatische Codevervollständigung** fÃŧr: +Wenn Sie die automatisch generierten Clients verwenden, erhalten Sie **Autovervollständigung** fÃŧr: * Methoden. * Request-Payloads im Body, Query-Parameter, usw. * Response-Payloads. -Außerdem erhalten Sie fÃŧr alles **Inline-Fehlerberichte**. +Sie erhalten auch **Inline-Fehlerberichte** fÃŧr alles. -Und wann immer Sie den Backend-Code aktualisieren und das Frontend **neu generieren**, stehen alle neuen *Pfadoperationen* als Methoden zur VerfÃŧgung, die alten werden entfernt und alle anderen Änderungen werden im generierten Code reflektiert. 🤓 +Und wann immer Sie den Backend-Code aktualisieren und **das Frontend neu generieren**, stehen alle neuen *Pfadoperationen* als Methoden zur VerfÃŧgung, die alten werden entfernt und alle anderen Änderungen werden im generierten Code reflektiert. 🤓 -Das bedeutet auch, dass, wenn sich etwas ändert, dies automatisch im Client-Code **reflektiert** wird. Und wenn Sie den Client **erstellen**, kommt es zu einer Fehlermeldung, wenn die verwendeten Daten **nicht Ãŧbereinstimmen**. +Das bedeutet auch, dass, wenn sich etwas ändert, dies automatisch im Client-Code **reflektiert** wird. Und wenn Sie den Client **erstellen**, wird eine Fehlermeldung ausgegeben, wenn die verwendeten Daten **nicht Ãŧbereinstimmen**. -Sie wÃŧrden also sehr frÃŧh im Entwicklungszyklus **viele Fehler erkennen**, anstatt darauf warten zu mÃŧssen, dass die Fehler Ihren Endbenutzern in der Produktion angezeigt werden, und dann zu versuchen, zu debuggen, wo das Problem liegt. ✨ +Sie wÃŧrden also **viele Fehler sehr frÃŧh** im Entwicklungszyklus erkennen, anstatt darauf warten zu mÃŧssen, dass die Fehler Ihren Endbenutzern in der Produktion angezeigt werden, und dann zu versuchen, zu debuggen, wo das Problem liegt. ✨ diff --git a/docs/de/docs/advanced/index.md b/docs/de/docs/advanced/index.md index d93cd5fe8..98fc7bc2f 100644 --- a/docs/de/docs/advanced/index.md +++ b/docs/de/docs/advanced/index.md @@ -1,6 +1,6 @@ -# Handbuch fÃŧr fortgeschrittene Benutzer +# Handbuch fÃŧr fortgeschrittene Benutzer { #advanced-user-guide } -## Zusatzfunktionen +## Zusatzfunktionen { #additional-features } Das Haupt-[Tutorial – Benutzerhandbuch](../tutorial/index.md){.internal-link target=_blank} sollte ausreichen, um Ihnen einen Überblick Ãŧber alle Hauptfunktionen von **FastAPI** zu geben. @@ -14,23 +14,8 @@ Und es ist mÃļglich, dass fÃŧr Ihren Anwendungsfall die LÃļsung in einem davon l /// -## Lesen Sie zuerst das Tutorial +## Das Tutorial zuerst lesen { #read-the-tutorial-first } Sie kÃļnnen immer noch die meisten Funktionen in **FastAPI** mit den Kenntnissen aus dem Haupt-[Tutorial – Benutzerhandbuch](../tutorial/index.md){.internal-link target=_blank} nutzen. -Und in den nächsten Abschnitten wird davon ausgegangen, dass Sie es bereits gelesen haben und dass Sie diese Haupt-Ideen kennen. - -## Externe Kurse - -Obwohl das [Tutorial – Benutzerhandbuch](../tutorial/index.md){.internal-link target=_blank} und dieses **Handbuch fÃŧr fortgeschrittene Benutzer** als gefÃŧhrtes Tutorial (wie ein Buch) geschrieben sind und fÃŧr Sie ausreichen sollten, um **FastAPI zu lernen**, mÃļchten Sie sie vielleicht durch zusätzliche Kurse ergänzen. - -Oder Sie belegen einfach lieber andere Kurse, weil diese besser zu Ihrem Lernstil passen. - -Einige Kursanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#den-autor-sponsern){.internal-link target=_blank} ✨, dies gewährleistet die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem**. - -Und es zeigt deren wahres Engagement fÃŧr FastAPI und seine **Gemeinschaft** (Sie), da diese Ihnen nicht nur eine **gute Lernerfahrung** bieten mÃļchten, sondern auch sicherstellen mÃļchten, dass Sie Ãŧber ein **gutes und gesundes Framework verfÃŧgen **, FastAPI. 🙇 - -Vielleicht mÃļchten Sie ihre Kurse ausprobieren: - -* Talk Python Training -* Test-Driven Development +Und die nächsten Abschnitte setzen voraus, dass Sie es bereits gelesen haben und dass Sie diese Hauptideen kennen. diff --git a/docs/de/docs/advanced/middleware.md b/docs/de/docs/advanced/middleware.md index 17b339788..0a2a39699 100644 --- a/docs/de/docs/advanced/middleware.md +++ b/docs/de/docs/advanced/middleware.md @@ -1,4 +1,4 @@ -# Fortgeschrittene Middleware +# Fortgeschrittene Middleware { #advanced-middleware } Im Haupttutorial haben Sie gelesen, wie Sie Ihrer Anwendung [benutzerdefinierte Middleware](../tutorial/middleware.md){.internal-link target=_blank} hinzufÃŧgen kÃļnnen. @@ -6,15 +6,15 @@ Und dann auch, wie man [CORS mittels der `CORSMiddleware`](../tutorial/cors.md){ In diesem Abschnitt werden wir sehen, wie man andere Middlewares verwendet. -## ASGI-Middleware hinzufÃŧgen +## ASGI-Middleware hinzufÃŧgen { #adding-asgi-middlewares } -Da **FastAPI** auf Starlette basiert und die ASGI-Spezifikation implementiert, kÃļnnen Sie jede ASGI-Middleware verwenden. +Da **FastAPI** auf Starlette basiert und die ASGI-Spezifikation implementiert, kÃļnnen Sie jede ASGI-Middleware verwenden. Eine Middleware muss nicht speziell fÃŧr FastAPI oder Starlette gemacht sein, um zu funktionieren, solange sie der ASGI-Spezifikation genÃŧgt. Im Allgemeinen handelt es sich bei ASGI-Middleware um Klassen, die als erstes Argument eine ASGI-Anwendung erwarten. -In der Dokumentation fÃŧr ASGI-Middlewares von Drittanbietern wird Ihnen wahrscheinlich gesagt, etwa Folgendes zu tun: +In der Dokumentation fÃŧr ASGI-Middlewares von Drittanbietern wird Ihnen wahrscheinlich gesagt, dass Sie etwa Folgendes tun sollen: ```Python from unicorn import UnicornMiddleware @@ -39,7 +39,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") `app.add_middleware()` empfängt eine Middleware-Klasse als erstes Argument und dann alle weiteren Argumente, die an die Middleware Ãŧbergeben werden sollen. -## Integrierte Middleware +## Integrierte Middleware { #integrated-middlewares } **FastAPI** enthält mehrere Middlewares fÃŧr gängige Anwendungsfälle. Wir werden als Nächstes sehen, wie man sie verwendet. @@ -51,15 +51,15 @@ FÃŧr die nächsten Beispiele kÃļnnten Sie auch `from starlette.middleware.someth /// -## `HTTPSRedirectMiddleware` +## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware } -Erzwingt, dass alle eingehenden Requests entweder `https` oder `wss` sein mÃŧssen. +Erzwingt, dass alle eingehenden Requests entweder `https` oder `wss` sein mÃŧssen. Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet. {* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *} -## `TrustedHostMiddleware` +## `TrustedHostMiddleware` { #trustedhostmiddleware } Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schÃŧtzen. @@ -68,10 +68,11 @@ Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header h Die folgenden Argumente werden unterstÃŧtzt: * `allowed_hosts` – Eine Liste von Domain-Namen, die als Hostnamen zulässig sein sollten. Wildcard-Domains wie `*.example.com` werden unterstÃŧtzt, um Subdomains zu matchen. Um jeden Hostnamen zu erlauben, verwenden Sie entweder `allowed_hosts=["*"]` oder lassen Sie diese Middleware weg. +* `www_redirect` – Wenn auf True gesetzt, werden Requests an Nicht-www-Versionen der erlaubten Hosts zu deren www-GegenstÃŧcken umgeleitet. Der Defaultwert ist `True`. -Wenn ein eingehender Request nicht korrekt validiert wird, wird eine „400“-Response gesendet. +Wenn ein eingehender Request nicht korrekt validiert wird, wird eine `400`-Response gesendet. -## `GZipMiddleware` +## `GZipMiddleware` { #gzipmiddleware } Verarbeitet GZip-Responses fÃŧr alle Requests, die `"gzip"` im `Accept-Encoding`-Header enthalten. @@ -81,9 +82,10 @@ Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses. Die folgenden Argumente werden unterstÃŧtzt: -* `minimum_size` – Antworten, die kleiner als diese MindestgrÃļße in Bytes sind, nicht per GZip komprimieren. Der Defaultwert ist `500`. +* `minimum_size` – Responses, die kleiner als diese MindestgrÃļße in Bytes sind, nicht per GZip komprimieren. Der Defaultwert ist `500`. +* `compresslevel` – Wird während der GZip-Kompression verwendet. Es ist ein Ganzzahlwert zwischen 1 und 9. Der Defaultwert ist `9`. Ein niedrigerer Wert resultiert in schnellerer Kompression, aber grÃļßeren DateigrÃļßen, während ein hÃļherer Wert langsamere Kompression, aber kleinere DateigrÃļßen zur Folge hat. -## Andere Middlewares +## Andere Middlewares { #other-middlewares } Es gibt viele andere ASGI-Middlewares. diff --git a/docs/de/docs/advanced/openapi-callbacks.md b/docs/de/docs/advanced/openapi-callbacks.md index 53f06e24e..afc48bbb8 100644 --- a/docs/de/docs/advanced/openapi-callbacks.md +++ b/docs/de/docs/advanced/openapi-callbacks.md @@ -1,12 +1,12 @@ -# OpenAPI-Callbacks +# OpenAPI-Callbacks { #openapi-callbacks } -Sie kÃļnnten eine API mit einer *Pfadoperation* erstellen, die einen Request an eine *externe API* auslÃļsen kÃļnnte, welche von jemand anderem erstellt wurde (wahrscheinlich derselbe Entwickler, der Ihre API *verwenden* wÃŧrde). +Sie kÃļnnten eine API mit einer *Pfadoperation* erstellen, die einen Request an eine *externe API* auslÃļsen kÃļnnte, welche von jemand anderem erstellt wurde (wahrscheinlich derselbe Entwickler, der Ihre API *verwenden* wÃŧrde). -Der Vorgang, der stattfindet, wenn Ihre API-Anwendung die *externe API* aufruft, wird als „Callback“ („RÃŧckruf“) bezeichnet. Denn die Software, die der externe Entwickler geschrieben hat, sendet einen Request an Ihre API und dann *ruft Ihre API zurÃŧck* (*calls back*) und sendet einen Request an eine *externe API* (die wahrscheinlich vom selben Entwickler erstellt wurde). +Der Vorgang, der stattfindet, wenn Ihre API-Anwendung die *externe API* aufruft, wird als „Callback“ bezeichnet. Denn die Software, die der externe Entwickler geschrieben hat, sendet einen Request an Ihre API und dann *ruft Ihre API zurÃŧck* (*calls back*) und sendet einen Request an eine *externe API* (die wahrscheinlich vom selben Entwickler erstellt wurde). -In diesem Fall mÃļchten Sie mÃļglicherweise dokumentieren, wie diese externe API aussehen *sollte*. Welche *Pfadoperation* sie haben sollte, welchen Body sie erwarten sollte, welche Response sie zurÃŧckgeben sollte, usw. +In diesem Fall mÃļchten Sie mÃļglicherweise dokumentieren, wie diese externe API aussehen *sollte*. Welche *Pfadoperation* sie haben sollte, welchen Body sie erwarten sollte, welche Response sie zurÃŧckgeben sollte, usw. -## Eine Anwendung mit Callbacks +## Eine Anwendung mit Callbacks { #an-app-with-callbacks } Sehen wir uns das alles anhand eines Beispiels an. @@ -16,14 +16,14 @@ Diese Rechnungen haben eine `id`, einen optionalen `title`, einen `customer` (Ku Der Benutzer Ihrer API (ein externer Entwickler) erstellt mit einem POST-Request eine Rechnung in Ihrer API. -Dann wird Ihre API (beispielsweise): +Dann wird Ihre API (stellen wir uns vor): * die Rechnung an einen Kunden des externen Entwicklers senden. * das Geld einsammeln. * eine Benachrichtigung an den API-Benutzer (den externen Entwickler) zurÃŧcksenden. * Dies erfolgt durch Senden eines POST-Requests (von *Ihrer API*) an eine *externe API*, die von diesem externen Entwickler bereitgestellt wird (das ist der „Callback“). -## Die normale **FastAPI**-Anwendung +## Die normale **FastAPI**-Anwendung { #the-normal-fastapi-app } Sehen wir uns zunächst an, wie die normale API-Anwendung aussehen wÃŧrde, bevor wir den Callback hinzufÃŧgen. @@ -41,7 +41,7 @@ Der Query-Parameter `callback_url` verwendet einen Pydantic-OpenAPI-3-Ausdruck enthalten (mehr dazu weiter unten), wo er Variablen mit Parametern und Teilen des ursprÃŧnglichen Requests verwenden kann, der an *Ihre API* gesendet wurde. -### Der Callback-Pfadausdruck +### Der Callback-Pfadausdruck { #the-callback-path-expression } Der Callback-*Pfad* kann einen OpenAPI-3-Ausdruck enthalten, welcher Teile des ursprÃŧnglichen Requests enthalten kann, der an *Ihre API* gesendet wurde. @@ -163,7 +163,7 @@ Beachten Sie, dass die verwendete Callback-URL die URL enthält, die als Query-P /// -### Den Callback-Router hinzufÃŧgen +### Den Callback-Router hinzufÃŧgen { #add-the-callback-router } An diesem Punkt haben Sie die benÃļtigte(n) *Callback-Pfadoperation(en)* (diejenige(n), die der *externe Entwickler* in der *externen API* implementieren sollte) im Callback-Router, den Sie oben erstellt haben. @@ -177,9 +177,9 @@ Beachten Sie, dass Sie nicht den Router selbst (`invoices_callback_router`) an ` /// -### Es in der Dokumentation ansehen +### Es in der Dokumentation testen { #check-the-docs } -Jetzt kÃļnnen Sie Ihre Anwendung mit Uvicorn starten und auf http://127.0.0.1:8000/docs gehen. +Jetzt kÃļnnen Sie Ihre Anwendung starten und auf http://127.0.0.1:8000/docs gehen. Sie sehen Ihre Dokumentation, einschließlich eines Abschnitts „Callbacks“ fÃŧr Ihre *Pfadoperation*, der zeigt, wie die *externe API* aussehen sollte: diff --git a/docs/de/docs/advanced/openapi-webhooks.md b/docs/de/docs/advanced/openapi-webhooks.md index 50b95eaf8..a09a675ed 100644 --- a/docs/de/docs/advanced/openapi-webhooks.md +++ b/docs/de/docs/advanced/openapi-webhooks.md @@ -1,54 +1,54 @@ -# OpenAPI-Webhooks +# OpenAPI Webhooks { #openapi-webhooks } -Es gibt Fälle, in denen Sie Ihren API-Benutzern mitteilen mÃļchten, dass Ihre Anwendung mit einigen Daten *deren* Anwendung aufrufen (ein Request senden) kÃļnnte, normalerweise um Ãŧber ein bestimmtes **Event** zu **benachrichtigen**. +Es gibt Fälle, in denen Sie Ihren API-**Benutzern** mitteilen mÃļchten, dass Ihre App *deren* App mit einigen Daten aufrufen (einen Request senden) kÃļnnte, normalerweise um Ãŧber ein bestimmtes **Event** zu **benachrichtigen**. -Das bedeutet, dass anstelle des normalen Prozesses, bei dem Benutzer Requests an Ihre API senden, **Ihre API** (oder Ihre Anwendung) **Requests an deren System** (an deren API, deren Anwendung) senden kÃļnnte. +Das bedeutet, dass anstelle des normalen Prozesses, bei dem Ihre Benutzer Requests an Ihre API senden, **Ihre API** (oder Ihre App) **Requests an deren System** (an deren API, deren App) senden kÃļnnte. -Das wird normalerweise als **Webhook** bezeichnet. +Das wird normalerweise als **Webhook** bezeichnet. -## Webhooks-Schritte +## Webhooks-Schritte { #webhooks-steps } Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden mÃļchten, den **Body des Requests**. -Sie definieren auch auf irgendeine Weise, zu welchen **Momenten** Ihre Anwendung diese Requests oder Events sendet. +Sie definieren auch auf irgendeine Weise, in welchen **Momenten** Ihre App diese Requests oder Events senden wird. -Und **Ihre Benutzer** definieren auf irgendeine Weise (zum Beispiel irgendwo in einem Web-Dashboard) die **URL**, an die Ihre Anwendung diese Requests senden soll. +Und **Ihre Benutzer** definieren auf irgendeine Weise (zum Beispiel irgendwo in einem Web-Dashboard) die **URL**, an die Ihre App diese Requests senden soll. Die gesamte **Logik** zur Registrierung der URLs fÃŧr Webhooks und der Code zum tatsächlichen Senden dieser Requests liegt bei Ihnen. Sie schreiben es so, wie Sie mÃļchten, in **Ihrem eigenen Code**. -## Webhooks mit **FastAPI** und OpenAPI dokumentieren +## Webhooks mit **FastAPI** und OpenAPI dokumentieren { #documenting-webhooks-with-fastapi-and-openapi } -Mit **FastAPI** kÃļnnen Sie mithilfe von OpenAPI die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre Anwendung senden kann (z. B. `POST`, `PUT`, usw.) und die Request**bodys** definieren, die Ihre Anwendung senden wÃŧrde. +Mit **FastAPI**, mithilfe von OpenAPI, kÃļnnen Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die Request**bodys** definieren, die Ihre App senden wÃŧrde. -Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. MÃļglicherweise kÃļnnen diese sogar einen Teil des eigenem API-Codes automatisch generieren. +Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. MÃļglicherweise kÃļnnen diese sogar einen Teil ihres eigenen API-Codes automatisch generieren. -/// info +/// info | Info Webhooks sind in OpenAPI 3.1.0 und hÃļher verfÃŧgbar und werden von FastAPI `0.99.0` und hÃļher unterstÃŧtzt. /// -## Eine Anwendung mit Webhooks +## Eine App mit Webhooks { #an-app-with-webhooks } -Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, mit dem Sie *Webhooks* definieren kÃļnnen, genauso wie Sie *Pfadoperationen* definieren wÃŧrden, zum Beispiel mit `@app.webhooks.post()`. +Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, das Sie verwenden kÃļnnen, um *Webhooks* zu definieren, genauso wie Sie *Pfadoperationen* definieren wÃŧrden, zum Beispiel mit `@app.webhooks.post()`. {* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *} Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**. -/// info +/// info | Info -Das `app.webhooks`-Objekt ist eigentlich nur ein `APIRouter`, derselbe Typ, den Sie verwenden wÃŧrden, wenn Sie Ihre Anwendung mit mehreren Dateien strukturieren. +Das `app.webhooks`-Objekt ist eigentlich nur ein `APIRouter`, derselbe Typ, den Sie verwenden wÃŧrden, wenn Sie Ihre App mit mehreren Dateien strukturieren. /// -Beachten Sie, dass Sie bei Webhooks tatsächlich keinen *Pfad* (wie `/items/`) deklarieren, sondern dass der Text, den Sie dort Ãŧbergeben, lediglich eine **Kennzeichnung** des Webhooks (der Name des Events) ist. Zum Beispiel ist in `@app.webhooks.post("new-subscription")` der Webhook-Name `new-subscription`. +Beachten Sie, dass Sie bei Webhooks tatsächlich keinen *Pfad* (wie `/items/`) deklarieren, der Text, den Sie dort Ãŧbergeben, ist lediglich eine **Kennzeichnung** des Webhooks (der Name des Events). Zum Beispiel ist in `@app.webhooks.post("new-subscription")` der Webhook-Name `new-subscription`. -Das liegt daran, dass erwartet wird, dass **Ihre Benutzer** den tatsächlichen **URL-Pfad**, an dem diese den Webhook-Request empfangen mÃļchten, auf andere Weise definieren (z. B. Ãŧber ein Web-Dashboard). +Das liegt daran, dass erwartet wird, dass **Ihre Benutzer** den tatsächlichen **URL-Pfad**, an dem sie den Webhook-Request empfangen mÃļchten, auf andere Weise definieren (z. B. Ãŧber ein Web-Dashboard). -### Es in der Dokumentation ansehen +### Die Dokumentation testen { #check-the-docs } -Jetzt kÃļnnen Sie Ihre Anwendung mit Uvicorn starten und auf http://127.0.0.1:8000/docs gehen. +Jetzt kÃļnnen Sie Ihre App starten und auf http://127.0.0.1:8000/docs gehen. Sie werden sehen, dass Ihre Dokumentation die normalen *Pfadoperationen* und jetzt auch einige **Webhooks** enthält: diff --git a/docs/de/docs/advanced/path-operation-advanced-configuration.md b/docs/de/docs/advanced/path-operation-advanced-configuration.md index b6e88d2c9..f5ec7c49e 100644 --- a/docs/de/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/de/docs/advanced/path-operation-advanced-configuration.md @@ -1,6 +1,6 @@ -# Fortgeschrittene Konfiguration der Pfadoperation +# Fortgeschrittene Konfiguration der Pfadoperation { #path-operation-advanced-configuration } -## OpenAPI operationId +## OpenAPI operationId { #openapi-operationid } /// warning | Achtung @@ -14,13 +14,13 @@ Sie mÃŧssten sicherstellen, dass sie fÃŧr jede Operation eindeutig ist. {* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} -### Verwendung des Namens der *Pfadoperation-Funktion* als operationId +### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid } Wenn Sie die Funktionsnamen Ihrer API als `operationId`s verwenden mÃļchten, kÃļnnen Sie Ãŧber alle iterieren und die `operation_id` jeder *Pfadoperation* mit deren `APIRoute.name` Ãŧberschreiben. Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefÃŧgt haben. -{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *} /// tip | Tipp @@ -36,13 +36,13 @@ Auch wenn diese sich in unterschiedlichen Modulen (Python-Dateien) befinden. /// -## Von OpenAPI ausschließen +## Von OpenAPI ausschließen { #exclude-from-openapi } Um eine *Pfadoperation* aus dem generierten OpenAPI-Schema (und damit aus den automatischen Dokumentationssystemen) auszuschließen, verwenden Sie den Parameter `include_in_schema` und setzen Sie ihn auf `False`: {* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} -## Fortgeschrittene Beschreibung mittels Docstring +## Fortgeschrittene Beschreibung mittels Docstring { #advanced-description-from-docstring } Sie kÃļnnen die verwendeten Zeilen aus dem Docstring einer *Pfadoperation-Funktion* einschränken, die fÃŧr OpenAPI verwendet werden. @@ -52,17 +52,17 @@ Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) {* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *} -## Zusätzliche Responses +## Zusätzliche Responses { #additional-responses } Sie haben wahrscheinlich gesehen, wie man das `response_model` und den `status_code` fÃŧr eine *Pfadoperation* deklariert. -Das definiert die Metadaten der Haupt-Response einer *Pfadoperation*. +Das definiert die Metadaten der Haupt-Response einer *Pfadoperation*. Sie kÃļnnen auch zusätzliche Responses mit deren Modellen, Statuscodes usw. deklarieren. Es gibt hier in der Dokumentation ein ganzes Kapitel darÃŧber, Sie kÃļnnen es unter [Zusätzliche Responses in OpenAPI](additional-responses.md){.internal-link target=_blank} lesen. -## OpenAPI-Extra +## OpenAPI-Extra { #openapi-extra } Wenn Sie in Ihrer Anwendung eine *Pfadoperation* deklarieren, generiert **FastAPI** automatisch die relevanten Metadaten dieser *Pfadoperation*, die in das OpenAPI-Schema aufgenommen werden sollen. @@ -80,7 +80,7 @@ Dieses *Pfadoperation*-spezifische OpenAPI-Schema wird normalerweise automatisch /// tip | Tipp -Dies ist ein Low-Level Erweiterungspunkt. +Dies ist ein Low-Level-Erweiterungspunkt. Wenn Sie nur zusätzliche Responses deklarieren mÃŧssen, kÃļnnen Sie dies bequemer mit [Zusätzliche Responses in OpenAPI](additional-responses.md){.internal-link target=_blank} tun. @@ -88,9 +88,9 @@ Wenn Sie nur zusätzliche Responses deklarieren mÃŧssen, kÃļnnen Sie dies bequem Sie kÃļnnen das OpenAPI-Schema fÃŧr eine *Pfadoperation* erweitern, indem Sie den Parameter `openapi_extra` verwenden. -### OpenAPI-Erweiterungen +### OpenAPI-Erweiterungen { #openapi-extensions } -Dieses `openapi_extra` kann beispielsweise hilfreich sein, um OpenAPI-Erweiterungen zu deklarieren: +Dieses `openapi_extra` kann beispielsweise hilfreich sein, um [OpenAPI-Erweiterungen](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) zu deklarieren: {* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *} @@ -129,43 +129,43 @@ Und wenn Sie die resultierende OpenAPI sehen (unter `/openapi.json` in Ihrer API } ``` -### Benutzerdefiniertes OpenAPI-*Pfadoperation*-Schema +### Benutzerdefiniertes OpenAPI-*Pfadoperation*-Schema { #custom-openapi-path-operation-schema } -Das Dictionary in `openapi_extra` wird mit dem automatisch generierten OpenAPI-Schema fÃŧr die *Pfadoperation* zusammengefÃŧhrt (mittels Deep Merge). +Das Dictionary in `openapi_extra` wird mit dem automatisch generierten OpenAPI-Schema fÃŧr die *Pfadoperation* zusammengefÃŧhrt (mittels Deep Merge). Sie kÃļnnen dem automatisch generierten Schema also zusätzliche Daten hinzufÃŧgen. -Sie kÃļnnten sich beispielsweise dafÃŧr entscheiden, den Request mit Ihrem eigenen Code zu lesen und zu validieren, ohne die automatischen Funktionen von FastAPI mit Pydantic zu verwenden, aber Sie kÃļnnten den Request trotzdem im OpenAPI-Schema definieren wollen. +Sie kÃļnnten sich beispielsweise dafÃŧr entscheiden, den Request mit Ihrem eigenen Code zu lesen und zu validieren, ohne die automatischen Funktionen von FastAPI mit Pydantic zu verwenden, aber Sie kÃļnnten den Request trotzdem im OpenAPI-Schema definieren wollen. Das kÃļnnte man mit `openapi_extra` machen: -{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[20:37,39:40] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *} -In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON geparst, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader ()` wäre dafÃŧr verantwortlich, ihn in irgendeiner Weise zu parsen. +In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON geparst, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafÃŧr verantwortlich, ihn in irgendeiner Weise zu parsen. Dennoch kÃļnnen wir das zu erwartende Schema fÃŧr den Requestbody deklarieren. -### Benutzerdefinierter OpenAPI-Content-Type +### Benutzerdefinierter OpenAPI-Content-Type { #custom-openapi-content-type } Mit demselben Trick kÃļnnten Sie ein Pydantic-Modell verwenden, um das JSON-Schema zu definieren, das dann im benutzerdefinierten Abschnitt des OpenAPI-Schemas fÃŧr die *Pfadoperation* enthalten ist. -Und Sie kÃļnnten dies auch tun, wenn der Datentyp in der Anfrage nicht JSON ist. +Und Sie kÃļnnten dies auch tun, wenn der Datentyp im Request nicht JSON ist. In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung fÃŧr JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON: //// tab | Pydantic v2 -{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22,24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *} //// //// tab | Pydantic v1 -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22,24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *} //// -/// info +/// info | Info In Pydantic Version 1 hieß die Methode zum Abrufen des JSON-Schemas fÃŧr ein Modell `Item.schema()`, in Pydantic Version 2 heißt die Methode `Item.model_json_schema()`. @@ -189,7 +189,7 @@ Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann //// -/// info +/// info | Info In Pydantic Version 1 war die Methode zum Parsen und Validieren eines Objekts `Item.parse_obj()`, in Pydantic Version 2 heißt die Methode `Item.model_validate()`. diff --git a/docs/de/docs/advanced/response-change-status-code.md b/docs/de/docs/advanced/response-change-status-code.md index 0aac32f4e..b079e241d 100644 --- a/docs/de/docs/advanced/response-change-status-code.md +++ b/docs/de/docs/advanced/response-change-status-code.md @@ -1,31 +1,31 @@ -# Response – Statuscode ändern +# Response – Statuscode ändern { #response-change-status-code } -Sie haben wahrscheinlich schon vorher gelesen, dass Sie einen Standard-[Response-Statuscode](../tutorial/response-status-code.md){.internal-link target=_blank} festlegen kÃļnnen. +Sie haben wahrscheinlich schon vorher gelesen, dass Sie einen Default-[Response-Statuscode](../tutorial/response-status-code.md){.internal-link target=_blank} festlegen kÃļnnen. -In manchen Fällen mÃŧssen Sie jedoch einen anderen als den Standard-Statuscode zurÃŧckgeben. +In manchen Fällen mÃŧssen Sie jedoch einen anderen als den Default-Statuscode zurÃŧckgeben. -## Anwendungsfall +## Anwendungsfall { #use-case } Stellen Sie sich zum Beispiel vor, Sie mÃļchten standardmäßig den HTTP-Statuscode „OK“ `200` zurÃŧckgeben. -Wenn die Daten jedoch nicht vorhanden waren, mÃļchten Sie diese erstellen und den HTTP-Statuscode „CREATED“ `201` zurÃŧckgeben. +Wenn die Daten jedoch nicht vorhanden sind, mÃļchten Sie diese erstellen und den HTTP-Statuscode „CREATED“ `201` zurÃŧckgeben. Sie mÃļchten aber dennoch in der Lage sein, die von Ihnen zurÃŧckgegebenen Daten mit einem `response_model` zu filtern und zu konvertieren. In diesen Fällen kÃļnnen Sie einen `Response`-Parameter verwenden. -## Einen `Response`-Parameter verwenden +## Einen `Response`-Parameter verwenden { #use-a-response-parameter } Sie kÃļnnen einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion* deklarieren (wie Sie es auch fÃŧr Cookies und Header tun kÃļnnen). -Anschließend kÃļnnen Sie den `status_code` in diesem *vorÃŧbergehenden* Response-Objekt festlegen. +Anschließend kÃļnnen Sie den `status_code` in diesem *vorÃŧbergehenden* Response-Objekt festlegen. {* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} -Und dann kÃļnnen Sie wie gewohnt jedes benÃļtigte Objekt zurÃŧckgeben (ein `dict`, ein Datenbankmodell usw.). +Und dann kÃļnnen Sie jedes benÃļtigte Objekt zurÃŧckgeben, wie Sie es normalerweise tun wÃŧrden (ein `dict`, ein Datenbankmodell usw.). Und wenn Sie ein `response_model` deklariert haben, wird es weiterhin zum Filtern und Konvertieren des von Ihnen zurÃŧckgegebenen Objekts verwendet. **FastAPI** verwendet diese *vorÃŧbergehende* Response, um den Statuscode (auch Cookies und Header) zu extrahieren und fÃŧgt diese in die endgÃŧltige Response ein, die den von Ihnen zurÃŧckgegebenen Wert enthält, gefiltert nach einem beliebigen `response_model`. -Sie kÃļnnen den Parameter `Response` auch in Abhängigkeiten deklarieren und den Statuscode darin festlegen. Bedenken Sie jedoch, dass der gewinnt, welcher zuletzt gesetzt wird. +Sie kÃļnnen den Parameter `Response` auch in Abhängigkeiten deklarieren und den Statuscode darin festlegen. Bedenken Sie jedoch, dass der zuletzt gesetzte gewinnt. diff --git a/docs/de/docs/advanced/response-cookies.md b/docs/de/docs/advanced/response-cookies.md index 5fe2cf7e3..0dd4175dd 100644 --- a/docs/de/docs/advanced/response-cookies.md +++ b/docs/de/docs/advanced/response-cookies.md @@ -1,12 +1,12 @@ -# Response-Cookies +# Response-Cookies { #response-cookies } -## Einen `Response`-Parameter verwenden +## Einen `Response`-Parameter verwenden { #use-a-response-parameter } Sie kÃļnnen einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion* deklarieren. -Und dann kÃļnnen Sie Cookies in diesem *vorÃŧbergehenden* Response-Objekt setzen. +Und dann kÃļnnen Sie Cookies in diesem *vorÃŧbergehenden* Response-Objekt setzen. -{* ../../docs_src/response_cookies/tutorial002.py hl[1,8:9] *} +{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *} Anschließend kÃļnnen Sie wie gewohnt jedes gewÃŧnschte Objekt zurÃŧckgeben (ein `dict`, ein Datenbankmodell, usw.). @@ -16,7 +16,7 @@ Und wenn Sie ein `response_model` deklariert haben, wird es weiterhin zum Filter Sie kÃļnnen den `Response`-Parameter auch in Abhängigkeiten deklarieren und darin Cookies (und Header) setzen. -## Eine `Response` direkt zurÃŧckgeben +## Eine `Response` direkt zurÃŧckgeben { #return-a-response-directly } Sie kÃļnnen Cookies auch erstellen, wenn Sie eine `Response` direkt in Ihrem Code zurÃŧckgeben. @@ -36,7 +36,7 @@ Und auch, dass Sie keine Daten senden, die durch ein `response_model` hätten ge /// -### Mehr Informationen +### Mehr Informationen { #more-info } /// note | Technische Details diff --git a/docs/de/docs/advanced/response-directly.md b/docs/de/docs/advanced/response-directly.md index b84aa8ab9..d99517373 100644 --- a/docs/de/docs/advanced/response-directly.md +++ b/docs/de/docs/advanced/response-directly.md @@ -1,16 +1,16 @@ -# Eine Response direkt zurÃŧckgeben +# Eine Response direkt zurÃŧckgeben { #return-a-response-directly } -Wenn Sie eine **FastAPI** *Pfadoperation* erstellen, kÃļnnen Sie normalerweise beliebige Daten davon zurÃŧckgeben: ein `dict`, eine `list`e, ein Pydantic-Modell, ein Datenbankmodell, usw. +Wenn Sie eine **FastAPI** *Pfadoperation* erstellen, kÃļnnen Sie normalerweise beliebige Daten davon zurÃŧckgeben: ein `dict`, eine `list`, ein Pydantic-Modell, ein Datenbankmodell, usw. Standardmäßig konvertiert **FastAPI** diesen RÃŧckgabewert automatisch nach JSON, mithilfe des `jsonable_encoder`, der in [JSON-kompatibler Encoder](../tutorial/encoder.md){.internal-link target=_blank} erläutert wird. -Dann wÃŧrde es hinter den Kulissen diese JSON-kompatiblen Daten (z. B. ein `dict`) in eine `JSONResponse` einfÃŧgen, die zum Senden der Response an den Client verwendet wÃŧrde. +Dann wÃŧrde es hinter den Kulissen diese JSON-kompatiblen Daten (z. B. ein `dict`) in eine `JSONResponse` einfÃŧgen, die zum Senden der Response an den Client verwendet wird. Sie kÃļnnen jedoch direkt eine `JSONResponse` von Ihren *Pfadoperationen* zurÃŧckgeben. Das kann beispielsweise nÃŧtzlich sein, um benutzerdefinierte Header oder Cookies zurÃŧckzugeben. -## Eine `Response` zurÃŧckgeben +## Eine `Response` zurÃŧckgeben { #return-a-response } Tatsächlich kÃļnnen Sie jede `Response` oder jede Unterklasse davon zurÃŧckgeben. @@ -26,7 +26,7 @@ Es wird keine Datenkonvertierung mit Pydantic-Modellen durchfÃŧhren, es wird den Dadurch haben Sie viel Flexibilität. Sie kÃļnnen jeden Datentyp zurÃŧckgeben, jede Datendeklaration oder -validierung Ãŧberschreiben, usw. -## Verwendung des `jsonable_encoder` in einer `Response` +## Verwendung des `jsonable_encoder` in einer `Response` { #using-the-jsonable-encoder-in-a-response } Da **FastAPI** keine Änderungen an einer von Ihnen zurÃŧckgegebenen `Response` vornimmt, mÃŧssen Sie sicherstellen, dass deren Inhalt dafÃŧr bereit ist. @@ -38,13 +38,13 @@ In diesen Fällen kÃļnnen Sie den `jsonable_encoder` verwenden, um Ihre Daten zu /// note | Technische Details -Sie kÃļnnen auch `from starlette.responses import JSONResponse` verwenden. +Sie kÃļnnten auch `from starlette.responses import JSONResponse` verwenden. **FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. /// -## Eine benutzerdefinierte `Response` zurÃŧckgeben +## Eine benutzerdefinierte `Response` zurÃŧckgeben { #returning-a-custom-response } Das obige Beispiel zeigt alle Teile, die Sie benÃļtigen, ist aber noch nicht sehr nÃŧtzlich, da Sie das `item` einfach direkt hätten zurÃŧckgeben kÃļnnen, und **FastAPI** wÃŧrde es fÃŧr Sie in eine `JSONResponse` einfÃŧgen, es in ein `dict` konvertieren, usw. All das standardmäßig. @@ -56,7 +56,7 @@ Sie kÃļnnten Ihren XML-Inhalt als String in eine `Response` einfÃŧgen und sie zu {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} -## Anmerkungen +## Anmerkungen { #notes } Wenn Sie eine `Response` direkt zurÃŧcksenden, werden deren Daten weder validiert, konvertiert (serialisiert), noch automatisch dokumentiert. diff --git a/docs/de/docs/advanced/response-headers.md b/docs/de/docs/advanced/response-headers.md index bf0bd7296..a5e310d55 100644 --- a/docs/de/docs/advanced/response-headers.md +++ b/docs/de/docs/advanced/response-headers.md @@ -1,12 +1,12 @@ -# Response-Header +# Response-Header { #response-headers } -## Verwenden Sie einen `Response`-Parameter +## Einen `Response`-Parameter verwenden { #use-a-response-parameter } Sie kÃļnnen einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion* deklarieren (wie Sie es auch fÃŧr Cookies tun kÃļnnen). -Und dann kÃļnnen Sie Header in diesem *vorÃŧbergehenden* Response-Objekt festlegen. +Und dann kÃļnnen Sie Header in diesem *vorÃŧbergehenden* Response-Objekt festlegen. -{* ../../docs_src/response_headers/tutorial002.py hl[1,7:8] *} +{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *} Anschließend kÃļnnen Sie wie gewohnt jedes gewÃŧnschte Objekt zurÃŧckgeben (ein `dict`, ein Datenbankmodell, usw.). @@ -16,7 +16,7 @@ Und wenn Sie ein `response_model` deklariert haben, wird es weiterhin zum Filter Sie kÃļnnen den Parameter `Response` auch in Abhängigkeiten deklarieren und darin Header (und Cookies) festlegen. -## Eine `Response` direkt zurÃŧckgeben +## Eine `Response` direkt zurÃŧckgeben { #return-a-response-directly } Sie kÃļnnen auch Header hinzufÃŧgen, wenn Sie eine `Response` direkt zurÃŧckgeben. @@ -34,8 +34,8 @@ Und da die `Response` häufig zum Setzen von Headern und Cookies verwendet wird, /// -## Benutzerdefinierte Header +## Benutzerdefinierte Header { #custom-headers } -Beachten Sie, dass benutzerdefinierte proprietäre Header mittels des Präfix 'X-' hinzugefÃŧgt werden kÃļnnen. +Beachten Sie, dass benutzerdefinierte proprietäre Header mittels des Präfix `X-` hinzugefÃŧgt werden kÃļnnen. -Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen kÃļnnen soll, mÃŧssen Sie diese zu Ihren CORS-Konfigurationen hinzufÃŧgen (weitere Informationen finden Sie unter [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), unter Verwendung des Parameters `expose_headers`, dokumentiert in Starlettes CORS-Dokumentation. +Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen kÃļnnen soll, mÃŧssen Sie diese zu Ihrer CORS-Konfiguration hinzufÃŧgen (weitere Informationen finden Sie unter [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), unter Verwendung des Parameters `expose_headers`, dokumentiert in Starlettes CORS-Dokumentation. diff --git a/docs/de/docs/advanced/security/http-basic-auth.md b/docs/de/docs/advanced/security/http-basic-auth.md index 36498c01d..f906ecd92 100644 --- a/docs/de/docs/advanced/security/http-basic-auth.md +++ b/docs/de/docs/advanced/security/http-basic-auth.md @@ -1,4 +1,4 @@ -# HTTP Basic Auth +# HTTP Basic Auth { #http-basic-auth } FÃŧr die einfachsten Fälle kÃļnnen Sie HTTP Basic Auth verwenden. @@ -6,13 +6,13 @@ Bei HTTP Basic Auth erwartet die Anwendung einen Header, der einen Benutzernamen Wenn sie diesen nicht empfängt, gibt sie den HTTP-Error 401 „Unauthorized“ zurÃŧck. -Und gibt einen Header `WWW-Authenticate` mit dem Wert `Basic` und einem optionalen `realm`-Parameter („Bereich“) zurÃŧck. +Und gibt einen Header `WWW-Authenticate` mit dem Wert `Basic` und einem optionalen `realm`-Parameter zurÃŧck. Dadurch wird der Browser angewiesen, die integrierte Eingabeaufforderung fÃŧr einen Benutzernamen und ein Passwort anzuzeigen. Wenn Sie dann den Benutzernamen und das Passwort eingeben, sendet der Browser diese automatisch im Header. -## Einfaches HTTP Basic Auth +## Einfaches HTTP Basic Auth { #simple-http-basic-auth } * Importieren Sie `HTTPBasic` und `HTTPBasicCredentials`. * Erstellen Sie mit `HTTPBasic` ein „`security`-Schema“. @@ -21,11 +21,12 @@ Wenn Sie dann den Benutzernamen und das Passwort eingeben, sendet der Browser di * Es enthält den gesendeten `username` und das gesendete `password`. {* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *} + Wenn Sie versuchen, die URL zum ersten Mal zu Ãļffnen (oder in der Dokumentation auf den Button „Execute“ zu klicken), wird der Browser Sie nach Ihrem Benutzernamen und Passwort fragen: -## Den Benutzernamen ÃŧberprÃŧfen +## Den Benutzernamen ÃŧberprÃŧfen { #check-the-username } Hier ist ein vollständigeres Beispiel. @@ -51,13 +52,13 @@ if not (credentials.username == "stanleyjobson") or not (credentials.password == Aber durch die Verwendung von `secrets.compare_digest()` ist dieser Code sicher vor einer Art von Angriffen, die „Timing-Angriffe“ genannt werden. -### Timing-Angriffe +### Timing-Angriffe { #timing-attacks } Aber was ist ein „Timing-Angriff“? Stellen wir uns vor, dass einige Angreifer versuchen, den Benutzernamen und das Passwort zu erraten. -Und sie senden eine Anfrage mit dem Benutzernamen `johndoe` und dem Passwort `love123`. +Und sie senden einen Request mit dem Benutzernamen `johndoe` und dem Passwort `love123`. Dann wÃŧrde der Python-Code in Ihrer Anwendung etwa so aussehen: @@ -77,21 +78,21 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": ... ``` -Python muss das gesamte `stanleyjobso` in `stanleyjobsox` und `stanleyjobson` vergleichen, bevor es erkennt, dass beide Zeichenfolgen nicht gleich sind. Daher wird es einige zusätzliche Mikrosekunden dauern, bis die Antwort „Incorrect username or password“ erfolgt. +Python muss das gesamte `stanleyjobso` in `stanleyjobsox` und `stanleyjobson` vergleichen, bevor es erkennt, dass beide Zeichenfolgen nicht gleich sind. Daher wird es einige zusätzliche Mikrosekunden dauern, bis die Response „Incorrect username or password“ erfolgt. -#### Die Zeit zum Antworten hilft den Angreifern +#### Die Zeit zum Antworten hilft den Angreifern { #the-time-to-answer-helps-the-attackers } -Wenn die Angreifer zu diesem Zeitpunkt feststellen, dass der Server einige Mikrosekunden länger braucht, um die Antwort „Incorrect username or password“ zu senden, wissen sie, dass sie _etwas_ richtig gemacht haben, einige der Anfangsbuchstaben waren richtig. +Wenn die Angreifer zu diesem Zeitpunkt feststellen, dass der Server einige Mikrosekunden länger braucht, um die Response „Incorrect username or password“ zu senden, wissen sie, dass sie _etwas_ richtig gemacht haben, einige der Anfangsbuchstaben waren richtig. Und dann kÃļnnen sie es noch einmal versuchen, wohl wissend, dass es wahrscheinlich eher etwas mit `stanleyjobsox` als mit `johndoe` zu tun hat. -#### Ein „professioneller“ Angriff +#### Ein „professioneller“ Angriff { #a-professional-attack } NatÃŧrlich wÃŧrden die Angreifer das alles nicht von Hand versuchen, sondern ein Programm dafÃŧr schreiben, mÃļglicherweise mit Tausenden oder Millionen Tests pro Sekunde. Und wÃŧrden jeweils nur einen zusätzlichen richtigen Buchstaben erhalten. Aber so hätten die Angreifer in wenigen Minuten oder Stunden mit der „Hilfe“ unserer Anwendung den richtigen Benutzernamen und das richtige Passwort erraten, indem sie die Zeitspanne zur Hilfe nehmen, die diese zur Beantwortung benÃļtigt. -#### Das Problem beheben mittels `secrets.compare_digest()` +#### Das Problem beheben mittels `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest } Aber in unserem Code verwenden wir tatsächlich `secrets.compare_digest()`. @@ -99,7 +100,7 @@ Damit wird, kurz gesagt, der Vergleich von `stanleyjobsox` mit `stanleyjobson` g So ist Ihr Anwendungscode, dank der Verwendung von `secrets.compare_digest()`, vor dieser ganzen Klasse von Sicherheitsangriffen geschÃŧtzt. -### Den Error zurÃŧckgeben +### Den Error zurÃŧckgeben { #return-the-error } Nachdem Sie festgestellt haben, dass die Anmeldeinformationen falsch sind, geben Sie eine `HTTPException` mit dem Statuscode 401 zurÃŧck (derselbe, der auch zurÃŧckgegeben wird, wenn keine Anmeldeinformationen angegeben werden) und fÃŧgen den Header `WWW-Authenticate` hinzu, damit der Browser die Anmeldeaufforderung erneut anzeigt: diff --git a/docs/de/docs/advanced/security/index.md b/docs/de/docs/advanced/security/index.md index 25eeb25b5..d7e633231 100644 --- a/docs/de/docs/advanced/security/index.md +++ b/docs/de/docs/advanced/security/index.md @@ -1,6 +1,6 @@ -# Fortgeschrittene Sicherheit +# Fortgeschrittene Sicherheit { #advanced-security } -## Zusatzfunktionen +## Zusatzfunktionen { #additional-features } Neben den in [Tutorial – Benutzerhandbuch: Sicherheit](../../tutorial/security/index.md){.internal-link target=_blank} behandelten Funktionen gibt es noch einige zusätzliche Funktionen zur Handhabung der Sicherheit. @@ -12,8 +12,8 @@ Und es ist mÃļglich, dass fÃŧr Ihren Anwendungsfall die LÃļsung in einem davon l /// -## Lesen Sie zuerst das Tutorial +## Das Tutorial zuerst lesen { #read-the-tutorial-first } -In den nächsten Abschnitten wird davon ausgegangen, dass Sie das Haupt-[Tutorial – Benutzerhandbuch: Sicherheit](../../tutorial/security/index.md){.internal-link target=_blank} bereits gelesen haben. +Die nächsten Abschnitte setzen voraus, dass Sie das Haupt-[Tutorial – Benutzerhandbuch: Sicherheit](../../tutorial/security/index.md){.internal-link target=_blank} bereits gelesen haben. Sie basieren alle auf den gleichen Konzepten, ermÃļglichen jedoch einige zusätzliche Funktionalitäten. diff --git a/docs/de/docs/advanced/security/oauth2-scopes.md b/docs/de/docs/advanced/security/oauth2-scopes.md index ed8f69d18..b96715d5a 100644 --- a/docs/de/docs/advanced/security/oauth2-scopes.md +++ b/docs/de/docs/advanced/security/oauth2-scopes.md @@ -1,12 +1,12 @@ -# OAuth2-Scopes +# OAuth2-Scopes { #oauth2-scopes } Sie kÃļnnen OAuth2-Scopes direkt in **FastAPI** verwenden, sie sind nahtlos integriert. Das ermÃļglicht es Ihnen, ein feingranuliertes Berechtigungssystem nach dem OAuth2-Standard in Ihre OpenAPI-Anwendung (und deren API-Dokumentation) zu integrieren. -OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, Twitter usw. verwendet wird. Sie verwenden ihn, um Benutzern und Anwendungen spezifische Berechtigungen zu erteilen. +OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, X (Twitter) usw. verwendet wird. Sie verwenden ihn, um Benutzern und Anwendungen spezifische Berechtigungen zu erteilen. -Jedes Mal, wenn Sie sich mit Facebook, Google, GitHub, Microsoft oder Twitter anmelden („log in with“), verwendet die entsprechende Anwendung OAuth2 mit Scopes. +Jedes Mal, wenn Sie sich mit Facebook, Google, GitHub, Microsoft oder X (Twitter) anmelden („log in with“), verwendet die entsprechende Anwendung OAuth2 mit Scopes. In diesem Abschnitt erfahren Sie, wie Sie Authentifizierung und Autorisierung mit demselben OAuth2, mit Scopes in Ihrer **FastAPI**-Anwendung verwalten. @@ -26,7 +26,7 @@ Aber wenn Sie wissen, dass Sie es brauchen oder neugierig sind, lesen Sie weiter /// -## OAuth2-Scopes und OpenAPI +## OAuth2-Scopes und OpenAPI { #oauth2-scopes-and-openapi } Die OAuth2-Spezifikation definiert „Scopes“ als eine Liste von durch Leerzeichen getrennten Strings. @@ -46,7 +46,7 @@ Er wird normalerweise verwendet, um bestimmte Sicherheitsberechtigungen zu dekla * `instagram_basic` wird von Facebook / Instagram verwendet. * `https://www.googleapis.com/auth/drive` wird von Google verwendet. -/// info +/// info | Info In OAuth2 ist ein „Scope“ nur ein String, der eine bestimmte erforderliche Berechtigung deklariert. @@ -58,21 +58,21 @@ FÃŧr OAuth2 sind es einfach nur Strings. /// -## GesamtÃŧbersicht +## GesamtÃŧbersicht { #global-view } Sehen wir uns zunächst kurz die Teile an, die sich gegenÃŧber den Beispielen im Haupt-**Tutorial – Benutzerhandbuch** fÃŧr [OAuth2 mit Password (und Hashing), Bearer mit JWT-Tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank} ändern. Diesmal verwenden wir OAuth2-Scopes: -{* ../../docs_src/security/tutorial005_an_py310.py hl[4,8,12,46,64,105,107:115,121:124,128:134,139,155] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *} Sehen wir uns diese Änderungen nun Schritt fÃŧr Schritt an. -## OAuth2-Sicherheitsschema +## OAuth2-Sicherheitsschema { #oauth2-security-scheme } Die erste Änderung ist, dass wir jetzt das OAuth2-Sicherheitsschema mit zwei verfÃŧgbaren Scopes deklarieren: `me` und `items`. -Der `scopes`-Parameter erhält ein `dict` mit jedem Scope als SchlÃŧssel und dessen Beschreibung als Wert: +Der `scopes`-Parameter erhält ein `dict` mit jedem Scope als SchlÃŧssel und dessen Beschreibung als Wert: -{* ../../docs_src/security/tutorial005_an_py310.py hl[62:65] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *} Da wir diese Scopes jetzt deklarieren, werden sie in der API-Dokumentation angezeigt, wenn Sie sich einloggen/autorisieren. @@ -82,11 +82,11 @@ Das ist derselbe Mechanismus, der verwendet wird, wenn Sie beim Anmelden mit Fac -## JWT-Token mit Scopes +## JWT-Token mit Scopes { #jwt-token-with-scopes } Ändern Sie nun die Token-*Pfadoperation*, um die angeforderten Scopes zurÃŧckzugeben. -Wir verwenden immer noch dasselbe `OAuth2PasswordRequestForm`. Es enthält eine Eigenschaft `scopes` mit einer `list`e von `str`s fÃŧr jeden Scope, den es im Request erhalten hat. +Wir verwenden immer noch dasselbe `OAuth2PasswordRequestForm`. Es enthält eine Eigenschaft `scopes` mit einer `list`e von `str`s fÃŧr jeden Scope, den es im Request erhalten hat. Und wir geben die Scopes als Teil des JWT-Tokens zurÃŧck. @@ -98,9 +98,9 @@ Aus SicherheitsgrÃŧnden sollten Sie jedoch sicherstellen, dass Sie in Ihrer Anwe /// -{* ../../docs_src/security/tutorial005_an_py310.py hl[155] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *} -## Scopes in *Pfadoperationen* und Abhängigkeiten deklarieren +## Scopes in *Pfadoperationen* und Abhängigkeiten deklarieren { #declare-scopes-in-path-operations-and-dependencies } Jetzt deklarieren wir, dass die *Pfadoperation* fÃŧr `/users/me/items/` den Scope `items` erfordert. @@ -124,7 +124,7 @@ Wir tun dies hier, um zu demonstrieren, wie **FastAPI** auf verschiedenen Ebenen /// -{* ../../docs_src/security/tutorial005_an_py310.py hl[4,139,170] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *} /// info | Technische Details @@ -136,7 +136,7 @@ Wenn Sie jedoch `Query`, `Path`, `Depends`, `Security` und andere von `fastapi` /// -## `SecurityScopes` verwenden +## `SecurityScopes` verwenden { #use-securityscopes } Aktualisieren Sie nun die Abhängigkeit `get_current_user`. @@ -150,9 +150,9 @@ Wir deklarieren auch einen speziellen Parameter vom Typ `SecurityScopes`, der au Diese `SecurityScopes`-Klasse ähnelt `Request` (`Request` wurde verwendet, um das Request-Objekt direkt zu erhalten). -{* ../../docs_src/security/tutorial005_an_py310.py hl[8,105] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *} -## Die `scopes` verwenden +## Die `scopes` verwenden { #use-the-scopes } Der Parameter `security_scopes` wird vom Typ `SecurityScopes` sein. @@ -164,9 +164,9 @@ Wir erstellen eine `HTTPException`, die wir später an mehreren Stellen wiederve In diese Exception fÃŧgen wir (falls vorhanden) die erforderlichen Scopes als durch Leerzeichen getrennten String ein (unter Verwendung von `scope_str`). Wir fÃŧgen diesen String mit den Scopes in den Header `WWW-Authenticate` ein (das ist Teil der Spezifikation). -{* ../../docs_src/security/tutorial005_an_py310.py hl[105,107:115] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *} -## Den `username` und das Format der Daten ÃŧberprÃŧfen +## Den `username` und das Format der Daten ÃŧberprÃŧfen { #verify-the-username-and-data-shape } Wir verifizieren, dass wir einen `username` erhalten, und extrahieren die Scopes. @@ -180,17 +180,17 @@ Anstelle beispielsweise eines `dict`s oder etwas anderem, was später in der Anw Wir verifizieren auch, dass wir einen Benutzer mit diesem Benutzernamen haben, und wenn nicht, lÃļsen wir dieselbe Exception aus, die wir zuvor erstellt haben. -{* ../../docs_src/security/tutorial005_an_py310.py hl[46,116:127] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *} -## Die `scopes` verifizieren +## Die `scopes` verifizieren { #verify-the-scopes } -Wir ÃŧberprÃŧfen nun, ob das empfangenen Token alle Scopes enthält, die von dieser Abhängigkeit und deren Verwendern (einschließlich *Pfadoperationen*) gefordert werden. Andernfalls lÃļsen wir eine `HTTPException` aus. +Wir ÃŧberprÃŧfen nun, ob das empfangene Token alle Scopes enthält, die von dieser Abhängigkeit und deren Verwendern (einschließlich *Pfadoperationen*) gefordert werden. Andernfalls lÃļsen wir eine `HTTPException` aus. Hierzu verwenden wir `security_scopes.scopes`, das eine `list`e mit allen diesen Scopes als `str` enthält. -{* ../../docs_src/security/tutorial005_an_py310.py hl[128:134] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *} -## Abhängigkeitsbaum und Scopes +## Abhängigkeitsbaum und Scopes { #dependency-tree-and-scopes } Sehen wir uns diesen Abhängigkeitsbaum und die Scopes noch einmal an. @@ -223,7 +223,7 @@ Alles hängt von den „Scopes“ ab, die in jeder *Pfadoperation* und jeder Abh /// -## Weitere Details zu `SecurityScopes`. +## Weitere Details zu `SecurityScopes` { #more-details-about-securityscopes } Sie kÃļnnen `SecurityScopes` an jeder Stelle und an mehreren Stellen verwenden, es muss sich nicht in der „Wurzel“-Abhängigkeit befinden. @@ -233,7 +233,7 @@ Da die `SecurityScopes` alle von den Verwendern der Abhängigkeiten deklarierten Diese werden fÃŧr jede *Pfadoperation* unabhängig ÃŧberprÃŧft. -## Testen Sie es +## Es testen { #check-it } Wenn Sie die API-Dokumentation Ãļffnen, kÃļnnen Sie sich authentisieren und angeben, welche Scopes Sie autorisieren mÃļchten. @@ -245,7 +245,7 @@ Und wenn Sie den Scope `me`, aber nicht den Scope `items` auswählen, kÃļnnen Si Das wÃŧrde einer Drittanbieteranwendung passieren, die versucht, auf eine dieser *Pfadoperationen* mit einem Token zuzugreifen, das von einem Benutzer bereitgestellt wurde, abhängig davon, wie viele Berechtigungen der Benutzer dieser Anwendung erteilt hat. -## Über Integrationen von Drittanbietern +## Über Integrationen von Drittanbietern { #about-third-party-integrations } In diesem Beispiel verwenden wir den OAuth2-Flow „Password“. @@ -269,6 +269,6 @@ Aber am Ende implementieren sie denselben OAuth2-Standard. **FastAPI** enthält Werkzeuge fÃŧr alle diese OAuth2-Authentifizierungs-Flows in `fastapi.security.oauth2`. -## `Security` in Dekorator-`dependencies` +## `Security` in Dekorator-`dependencies` { #security-in-decorator-dependencies } Auf die gleiche Weise kÃļnnen Sie eine `list`e von `Depends` im Parameter `dependencies` des Dekorators definieren (wie in [Abhängigkeiten in Pfadoperation-Dekoratoren](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} erläutert), Sie kÃļnnten auch dort `Security` mit `scopes` verwenden. diff --git a/docs/de/docs/advanced/settings.md b/docs/de/docs/advanced/settings.md index 00cc2ac37..ccd7f373d 100644 --- a/docs/de/docs/advanced/settings.md +++ b/docs/de/docs/advanced/settings.md @@ -1,4 +1,4 @@ -# Einstellungen und Umgebungsvariablen +# Einstellungen und Umgebungsvariablen { #settings-and-environment-variables } In vielen Fällen benÃļtigt Ihre Anwendung mÃļglicherweise einige externe Einstellungen oder Konfigurationen, zum Beispiel geheime SchlÃŧssel, Datenbank-Anmeldeinformationen, Anmeldeinformationen fÃŧr E-Mail-Dienste, usw. @@ -6,143 +6,25 @@ Die meisten dieser Einstellungen sind variabel (kÃļnnen sich ändern), wie z. B. Aus diesem Grund werden diese Ãŧblicherweise in Umgebungsvariablen bereitgestellt, die von der Anwendung gelesen werden. -## Umgebungsvariablen - /// tip | Tipp -Wenn Sie bereits wissen, was „Umgebungsvariablen“ sind und wie man sie verwendet, kÃļnnen Sie gerne mit dem nächsten Abschnitt weiter unten fortfahren. +Um Umgebungsvariablen zu verstehen, kÃļnnen Sie [Umgebungsvariablen](../environment-variables.md){.internal-link target=_blank} lesen. /// -Eine Umgebungsvariable (auch bekannt als „env var“) ist eine Variable, die sich außerhalb des Python-Codes im Betriebssystem befindet und von Ihrem Python-Code (oder auch von anderen Programmen) gelesen werden kann. - -Sie kÃļnnen Umgebungsvariablen in der Shell erstellen und verwenden, ohne Python zu benÃļtigen: - -//// tab | Linux, macOS, Windows Bash - -
- -```console -// Sie kÃļnnten eine Umgebungsvariable MY_NAME erstellen mittels -$ export MY_NAME="Wade Wilson" - -// Dann kÃļnnten Sie diese mit anderen Programmen verwenden, etwa -$ echo "Hello $MY_NAME" - -Hello Wade Wilson -``` - -
- -//// - -//// tab | Windows PowerShell - -
- -```console -// Erstelle eine Umgebungsvariable MY_NAME -$ $Env:MY_NAME = "Wade Wilson" - -// Verwende sie mit anderen Programmen, etwa -$ echo "Hello $Env:MY_NAME" - -Hello Wade Wilson -``` - -
- -//// - -### Umgebungsvariablen mit Python auslesen - -Sie kÃļnnen Umgebungsvariablen auch außerhalb von Python im Terminal (oder mit einer anderen Methode) erstellen und diese dann mit Python auslesen. - -Sie kÃļnnten zum Beispiel eine Datei `main.py` haben mit: - -```Python hl_lines="3" -import os - -name = os.getenv("MY_NAME", "World") -print(f"Hello {name} from Python") -``` - -/// tip | Tipp - -Das zweite Argument fÃŧr `os.getenv()` ist der zurÃŧckzugebende Defaultwert. - -Wenn nicht angegeben, ist er standardmäßig `None`. Hier Ãŧbergeben wir `"World"` als Defaultwert. - -/// - -Dann kÃļnnten Sie dieses Python-Programm aufrufen: - -
- -```console -// Hier legen wir die Umgebungsvariable noch nicht fest -$ python main.py - -// Da wir die Umgebungsvariable nicht festgelegt haben, erhalten wir den Standardwert - -Hello World from Python - -// Aber wenn wir zuerst eine Umgebungsvariable erstellen -$ export MY_NAME="Wade Wilson" - -// Und dann das Programm erneut aufrufen -$ python main.py - -// Kann es jetzt die Umgebungsvariable lesen - -Hello Wade Wilson from Python -``` - -
- -Da Umgebungsvariablen außerhalb des Codes festgelegt, aber vom Code gelesen werden kÃļnnen und nicht zusammen mit den Ãŧbrigen Dateien gespeichert (an `git` committet) werden mÃŧssen, werden sie häufig fÃŧr Konfigurationen oder Einstellungen verwendet. - -Sie kÃļnnen eine Umgebungsvariable auch nur fÃŧr einen bestimmten Programmaufruf erstellen, die nur fÃŧr dieses Programm und nur fÃŧr dessen Dauer verfÃŧgbar ist. - -Erstellen Sie diese dazu direkt vor dem Programm selbst, in derselben Zeile: - -
- -```console -// Erstelle eine Umgebungsvariable MY_NAME inline fÃŧr diesen Programmaufruf -$ MY_NAME="Wade Wilson" python main.py - -// main.py kann jetzt diese Umgebungsvariable lesen - -Hello Wade Wilson from Python - -// Die Umgebungsvariable existiert danach nicht mehr -$ python main.py - -Hello World from Python -``` - -
- -/// tip | Tipp - -Weitere Informationen dazu finden Sie unter The Twelve-Factor App: Config. - -/// - -### Typen und Validierung +## Typen und Validierung { #types-and-validation } Diese Umgebungsvariablen kÃļnnen nur Text-Zeichenketten verarbeiten, da sie außerhalb von Python liegen und mit anderen Programmen und dem Rest des Systems (und sogar mit verschiedenen Betriebssystemen wie Linux, Windows, macOS) kompatibel sein mÃŧssen. Das bedeutet, dass jeder in Python aus einer Umgebungsvariablen gelesene Wert ein `str` ist und jede Konvertierung in einen anderen Typ oder jede Validierung im Code erfolgen muss. -## Pydantic `Settings` +## Pydantic `Settings` { #pydantic-settings } GlÃŧcklicherweise bietet Pydantic ein großartiges Werkzeug zur Verarbeitung dieser Einstellungen, die von Umgebungsvariablen stammen, mit Pydantic: Settings Management. -### `pydantic-settings` installieren +### `pydantic-settings` installieren { #install-pydantic-settings } -Installieren Sie zunächst das Package `pydantic-settings`: +Stellen Sie zunächst sicher, dass Sie Ihre [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellt und aktiviert haben, und installieren Sie dann das Package `pydantic-settings`:
@@ -164,13 +46,13 @@ $ pip install "fastapi[all]"
-/// info +/// info | Info -In Pydantic v1 war das im Hauptpackage enthalten. Jetzt wird es als unabhängiges Package verteilt, sodass Sie wählen kÃļnnen, ob Sie es installieren mÃļchten oder nicht, falls Sie die Funktionalität nicht benÃļtigen. +In Pydantic v1 war es im Hauptpackage enthalten. Jetzt wird es als unabhängiges Package verteilt, sodass Sie wählen kÃļnnen, ob Sie es installieren mÃļchten oder nicht, falls Sie die Funktionalität nicht benÃļtigen. /// -### Das `Settings`-Objekt erstellen +### Das `Settings`-Objekt erstellen { #create-the-settings-object } Importieren Sie `BaseSettings` aus Pydantic und erstellen Sie eine Unterklasse, ganz ähnlich wie bei einem Pydantic-Modell. @@ -186,7 +68,7 @@ Sie kÃļnnen dieselben Validierungs-Funktionen und -Tools verwenden, die Sie fÃŧr //// tab | Pydantic v1 -/// info +/// info | Info In Pydantic v1 wÃŧrden Sie `BaseSettings` direkt von `pydantic` statt von `pydantic_settings` importieren. @@ -206,20 +88,20 @@ Wenn Sie dann eine Instanz dieser `Settings`-Klasse erstellen (in diesem Fall al Als Nächstes werden die Daten konvertiert und validiert. Wenn Sie also dieses `settings`-Objekt verwenden, verfÃŧgen Sie Ãŧber Daten mit den von Ihnen deklarierten Typen (z. B. ist `items_per_user` ein `int`). -### `settings` verwenden +### `settings` verwenden { #use-the-settings } Dann kÃļnnen Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden: {* ../../docs_src/settings/tutorial001.py hl[18:20] *} -### Den Server ausfÃŧhren +### Den Server ausfÃŧhren { #run-the-server } Als Nächstes wÃŧrden Sie den Server ausfÃŧhren und die Konfigurationen als Umgebungsvariablen Ãŧbergeben. Sie kÃļnnten beispielsweise `ADMIN_EMAIL` und `APP_NAME` festlegen mit:
```console -$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app +$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -236,9 +118,9 @@ Und dann wÃŧrde die Einstellung `admin_email` auf `"deadpool@example.com"` geset Der `app_name` wäre `"ChimichangApp"`. -Und `items_per_user` wÃŧrde seinen Standardwert von `50` behalten. +Und `items_per_user` wÃŧrde seinen Defaultwert von `50` behalten. -## Einstellungen in einem anderen Modul +## Einstellungen in einem anderen Modul { #settings-in-another-module } Sie kÃļnnten diese Einstellungen in eine andere Moduldatei einfÃŧgen, wie Sie in [GrÃļßere Anwendungen – mehrere Dateien](../tutorial/bigger-applications.md){.internal-link target=_blank} gesehen haben. @@ -256,13 +138,13 @@ Sie benÃļtigen außerdem eine Datei `__init__.py`, wie in [GrÃļßere Anwendungen /// -## Einstellungen in einer Abhängigkeit +## Einstellungen in einer Abhängigkeit { #settings-in-a-dependency } In manchen Fällen kann es nÃŧtzlich sein, die Einstellungen mit einer Abhängigkeit bereitzustellen, anstatt ein globales Objekt `settings` zu haben, das Ãŧberall verwendet wird. Dies kÃļnnte besonders beim Testen nÃŧtzlich sein, da es sehr einfach ist, eine Abhängigkeit mit Ihren eigenen benutzerdefinierten Einstellungen zu Ãŧberschreiben. -### Die Konfigurationsdatei +### Die Konfigurationsdatei { #the-config-file } Ausgehend vom vorherigen Beispiel kÃļnnte Ihre Datei `config.py` so aussehen: @@ -270,7 +152,7 @@ Ausgehend vom vorherigen Beispiel kÃļnnte Ihre Datei `config.py` so aussehen: Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen. -### Die Haupt-Anwendungsdatei +### Die Haupt-Anwendungsdatei { #the-main-app-file } Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurÃŧckgibt. @@ -288,7 +170,7 @@ Und dann kÃļnnen wir das von der *Pfadoperation-Funktion* als Abhängigkeit einf {* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *} -### Einstellungen und Tests +### Einstellungen und Tests { #settings-and-testing } Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine AbhängigkeitsÃŧberschreibung fÃŧr `get_settings` erstellt: @@ -298,7 +180,7 @@ Bei der AbhängigkeitsÃŧberschreibung legen wir einen neuen Wert fÃŧr `admin_ema Dann kÃļnnen wir testen, ob das verwendet wird. -## Lesen einer `.env`-Datei +## Lesen einer `.env`-Datei { #reading-a-env-file } Wenn Sie viele Einstellungen haben, die sich mÃļglicherweise oft ändern, vielleicht in verschiedenen Umgebungen, kann es nÃŧtzlich sein, diese in eine Datei zu schreiben und sie dann daraus zu lesen, als wären sie Umgebungsvariablen. @@ -320,7 +202,7 @@ Damit das funktioniert, mÃŧssen Sie `pip install python-dotenv` ausfÃŧhren. /// -### Die `.env`-Datei +### Die `.env`-Datei { #the-env-file } Sie kÃļnnten eine `.env`-Datei haben, mit: @@ -329,7 +211,7 @@ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" ``` -### Einstellungen aus `.env` lesen +### Einstellungen aus `.env` lesen { #read-settings-from-env } Und dann aktualisieren Sie Ihre `config.py` mit: @@ -339,7 +221,7 @@ Und dann aktualisieren Sie Ihre `config.py` mit: /// tip | Tipp -Das Attribut `model_config` wird nur fÃŧr die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter Pydantic: Configuration. +Das Attribut `model_config` wird nur fÃŧr die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter Pydantic: Concepts: Configuration. /// @@ -357,17 +239,17 @@ Die Klasse `Config` wird nur fÃŧr die Pydantic-Konfiguration verwendet. Weitere //// -/// info +/// info | Info -In Pydantic Version 1 erfolgte die Konfiguration in einer internen Klasse `Config`, in Pydantic Version 2 erfolgt sie in einem Attribut `model_config`. Dieses Attribut akzeptiert ein `dict`. Um automatische Codevervollständigung und Inline-Fehlerberichte zu erhalten, kÃļnnen Sie `SettingsConfigDict` importieren und verwenden, um dieses `dict` zu definieren. +In Pydantic Version 1 erfolgte die Konfiguration in einer internen Klasse `Config`, in Pydantic Version 2 erfolgt sie in einem Attribut `model_config`. Dieses Attribut akzeptiert ein `dict`. Um automatische Codevervollständigung und Inline-Fehlerberichte zu erhalten, kÃļnnen Sie `SettingsConfigDict` importieren und verwenden, um dieses `dict` zu definieren. /// Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden mÃļchten. -### Die `Settings` nur einmal laden mittels `lru_cache` +### Die `Settings` nur einmal laden mittels `lru_cache` { #creating-the-settings-only-once-with-lru-cache } -Das Lesen einer Datei von der Festplatte ist normalerweise ein kostspieliger (langsamer) Vorgang, daher mÃļchten Sie ihn wahrscheinlich nur einmal ausfÃŧhren und dann dasselbe Einstellungsobjekt erneut verwenden, anstatt es fÃŧr jeden Request zu lesen. +Das Lesen einer Datei von der Festplatte ist normalerweise ein kostspieliger (langsamer) Vorgang, daher mÃļchten Sie ihn wahrscheinlich nur einmal ausfÃŧhren und dann dasselbe Einstellungsobjekt erneut verwenden, anstatt es fÃŧr jeden Request zu lesen. Aber jedes Mal, wenn wir ausfÃŧhren: @@ -392,7 +274,7 @@ Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Obj Dann wird bei allen nachfolgenden Aufrufen von `get_settings()`, in den Abhängigkeiten fÃŧr darauffolgende Requests, dasselbe Objekt zurÃŧckgegeben, das beim ersten Aufruf zurÃŧckgegeben wurde, anstatt den Code von `get_settings()` erneut auszufÃŧhren und ein neues `Settings`-Objekt zu erstellen. -#### Technische Details zu `lru_cache` +#### Technische Details zu `lru_cache` { #lru-cache-technical-details } `@lru_cache` ändert die Funktion, die es dekoriert, dahingehend, denselben Wert zurÃŧckzugeben, der beim ersten Mal zurÃŧckgegeben wurde, anstatt ihn erneut zu berechnen und den Code der Funktion jedes Mal auszufÃŧhren. @@ -413,7 +295,7 @@ sequenceDiagram participant code as Code participant function as say_hi() -participant execute as Funktion ausgefÃŧhrt +participant execute as Funktion ausfÃŧhren rect rgba(0, 255, 0, .1) code ->> function: say_hi(name="Camila") @@ -455,7 +337,7 @@ Auf diese Weise verhält es sich fast so, als wäre es nur eine globale Variable `@lru_cache` ist Teil von `functools`, welches Teil von Pythons Standardbibliothek ist. Weitere Informationen dazu finden Sie in der Python Dokumentation fÃŧr `@lru_cache`. -## Zusammenfassung +## Zusammenfassung { #recap } Mit Pydantic Settings kÃļnnen Sie die Einstellungen oder Konfigurationen fÃŧr Ihre Anwendung verwalten und dabei die gesamte Leistungsfähigkeit der Pydantic-Modelle nutzen. diff --git a/docs/de/docs/advanced/sub-applications.md b/docs/de/docs/advanced/sub-applications.md index f123147b3..d634aac23 100644 --- a/docs/de/docs/advanced/sub-applications.md +++ b/docs/de/docs/advanced/sub-applications.md @@ -1,41 +1,41 @@ -# Unteranwendungen – Mounts +# Unteranwendungen – Mounts { #sub-applications-mounts } Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen OpenAPI und deren eigenen Dokumentationsoberflächen benÃļtigen, kÃļnnen Sie eine Hauptanwendung haben und dann eine (oder mehrere) Unteranwendung(en) „mounten“. -## Mounten einer **FastAPI**-Anwendung +## Eine **FastAPI**-Anwendung mounten { #mounting-a-fastapi-application } „Mounten“ („Einhängen“) bedeutet das HinzufÃŧgen einer vÃļllig „unabhängigen“ Anwendung an einem bestimmten Pfad, die sich dann um die Handhabung aller unter diesem Pfad liegenden _Pfadoperationen_ kÃŧmmert, welche in dieser Unteranwendung deklariert sind. -### Hauptanwendung +### Hauptanwendung { #top-level-application } Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*: -{* ../../docs_src/sub_applications/tutorial001.py hl[3,6:8] *} +{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *} -### Unteranwendung +### Unteranwendung { #sub-application } Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*. Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“: -{* ../../docs_src/sub_applications/tutorial001.py hl[11,14:16] *} +{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *} -### Die Unteranwendung mounten +### Die Unteranwendung mounten { #mount-the-sub-application } Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`. In diesem Fall wird sie im Pfad `/subapi` gemountet: -{* ../../docs_src/sub_applications/tutorial001.py hl[11,19] *} +{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *} -### Es in der automatischen API-Dokumentation betrachten +### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs } -FÃŧhren Sie nun `uvicorn` mit der Hauptanwendung aus. Wenn Ihre Datei `main.py` lautet, wäre das: +FÃŧhren Sie nun den `fastapi`-Befehl mit Ihrer Datei aus:
```console -$ uvicorn main:app --reload +$ fastapi dev main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -56,7 +56,7 @@ Sie sehen die automatische API-Dokumentation fÃŧr die Unteranwendung, welche nur Wenn Sie versuchen, mit einer der beiden Benutzeroberflächen zu interagieren, funktionieren diese ordnungsgemäß, da der Browser mit jeder spezifischen Anwendung oder Unteranwendung kommunizieren kann. -### Technische Details: `root_path` +### Technische Details: `root_path` { #technical-details-root-path } Wenn Sie eine Unteranwendung wie oben beschrieben mounten, kÃŧmmert sich FastAPI darum, den Mount-Pfad fÃŧr die Unteranwendung zu kommunizieren, mithilfe eines Mechanismus aus der ASGI-Spezifikation namens `root_path`. diff --git a/docs/de/docs/advanced/templates.md b/docs/de/docs/advanced/templates.md index 136ce6027..fdaeb3413 100644 --- a/docs/de/docs/advanced/templates.md +++ b/docs/de/docs/advanced/templates.md @@ -1,4 +1,4 @@ -# Templates +# Templates { #templates } Sie kÃļnnen jede gewÃŧnschte Template-Engine mit **FastAPI** verwenden. @@ -6,9 +6,9 @@ Eine häufige Wahl ist Jinja2, dasselbe, was auch von Flask und anderen Tools ve Es gibt Werkzeuge zur einfachen Konfiguration, die Sie direkt in Ihrer **FastAPI**-Anwendung verwenden kÃļnnen (bereitgestellt von Starlette). -## Abhängigkeiten installieren +## Abhängigkeiten installieren { #install-dependencies } -Installieren Sie `jinja2`: +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und `jinja2` installieren:
@@ -20,12 +20,12 @@ $ pip install jinja2
-## Verwendung von `Jinja2Templates` +## `Jinja2Templates` verwenden { #using-jinja2templates } * Importieren Sie `Jinja2Templates`. * Erstellen Sie ein `templates`-Objekt, das Sie später wiederverwenden kÃļnnen. -* Deklarieren Sie einen `Request`-Parameter in der *Pfadoperation*, welcher ein Template zurÃŧckgibt. -* Verwenden Sie die von Ihnen erstellten `templates`, um eine `TemplateResponse` zu rendern und zurÃŧckzugeben, Ãŧbergeben Sie den Namen des Templates, das Requestobjekt und ein „Kontext“-Dictionary mit SchlÃŧssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen. +* Deklarieren Sie einen `Request`-Parameter in der *Pfadoperation*, welcher ein Template zurÃŧckgibt. +* Verwenden Sie die von Ihnen erstellten `templates`, um eine `TemplateResponse` zu rendern und zurÃŧckzugeben, Ãŧbergeben Sie den Namen des Templates, das Requestobjekt und ein „Kontext“-Dictionary mit SchlÃŧssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen. {* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *} @@ -39,7 +39,7 @@ Außerdem wurde in frÃŧheren Versionen das `request`-Objekt als Teil der SchlÃŧs /// tip | Tipp -Durch die Deklaration von `response_class=HTMLResponse` kann die Dokumentationsoberfläche erkennen, dass die Response HTML sein wird. +Durch die Deklaration von `response_class=HTMLResponse` kann die Dokumentationsoberfläche erkennen, dass die Response HTML sein wird. /// @@ -47,11 +47,11 @@ Durch die Deklaration von `response_class=HTMLResponse` kann die Dokumentationso Sie kÃļnnen auch `from starlette.templating import Jinja2Templates` verwenden. -**FastAPI** bietet dasselbe `starlette.templating` auch via `fastapi.templating` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Es kommt aber direkt von Starlette. Das Gleiche gilt fÃŧr `Request` und `StaticFiles`. +**FastAPI** bietet dasselbe `starlette.templating` auch via `fastapi.templating` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Aber die meisten der verfÃŧgbaren Responses kommen direkt von Starlette. Das Gleiche gilt fÃŧr `Request` und `StaticFiles`. /// -## Templates erstellen +## Templates erstellen { #writing-templates } Dann kÃļnnen Sie unter `templates/item.html` ein Template erstellen, mit z. B. folgendem Inhalt: @@ -59,7 +59,7 @@ Dann kÃļnnen Sie unter `templates/item.html` ein Template erstellen, mit z. B. f {!../../docs_src/templates/templates/item.html!} ``` -### Template-Kontextwerte +### Template-Kontextwerte { #template-context-values } Im HTML, welches enthält: @@ -83,7 +83,7 @@ Mit beispielsweise einer ID `42` wÃŧrde das wie folgt gerendert werden: Item ID: 42 ``` -### Template-`url_for`-Argumente +### Template-`url_for`-Argumente { #template-url-for-arguments } Sie kÃļnnen `url_for()` auch innerhalb des Templates verwenden, es nimmt als Argumente dieselben Argumente, die von Ihrer *Pfadoperation-Funktion* verwendet werden. @@ -105,7 +105,7 @@ Mit beispielsweise der ID `42` wÃŧrde dies Folgendes ergeben: ``` -## Templates und statische Dateien +## Templates und statische Dateien { #templates-and-static-files } Sie kÃļnnen `url_for()` innerhalb des Templates auch beispielsweise mit den `StaticFiles` verwenden, die Sie mit `name="static"` gemountet haben. @@ -119,8 +119,8 @@ In diesem Beispiel wÃŧrde das zu einer CSS-Datei unter `static/styles.css` verli {!../../docs_src/templates/static/styles.css!} ``` -Und da Sie `StaticFiles` verwenden, wird diese CSS-Datei automatisch von Ihrer **FastAPI**-Anwendung unter der URL `/static/styles.css` bereitgestellt. +Und da Sie `StaticFiles` verwenden, wird diese CSS-Datei automatisch von Ihrer **FastAPI**-Anwendung unter der URL `/static/styles.css` ausgeliefert. -## Mehr Details +## Mehr Details { #more-details } -Weitere Informationen, einschließlich, wie man Templates testet, finden Sie in der Starlette Dokumentation zu Templates. +Weitere Informationen, einschließlich, wie man Templates testet, finden Sie in Starlettes Dokumentation zu Templates. diff --git a/docs/de/docs/advanced/testing-dependencies.md b/docs/de/docs/advanced/testing-dependencies.md index 8299d6dd7..4fc653f77 100644 --- a/docs/de/docs/advanced/testing-dependencies.md +++ b/docs/de/docs/advanced/testing-dependencies.md @@ -1,6 +1,6 @@ -# Testen mit Ersatz fÃŧr Abhängigkeiten +# Testen mit Überschreibungen fÃŧr Abhängigkeiten { #testing-dependencies-with-overrides } -## Abhängigkeiten beim Testen Ãŧberschreiben +## Abhängigkeiten beim Testen Ãŧberschreiben { #overriding-dependencies-during-testing } Es gibt einige Szenarien, in denen Sie beim Testen mÃļglicherweise eine Abhängigkeit Ãŧberschreiben mÃļchten. @@ -8,21 +8,21 @@ Sie mÃļchten nicht, dass die ursprÃŧngliche Abhängigkeit ausgefÃŧhrt wird (und Stattdessen mÃļchten Sie eine andere Abhängigkeit bereitstellen, die nur während Tests (mÃļglicherweise nur bei einigen bestimmten Tests) verwendet wird und einen Wert bereitstellt, der dort verwendet werden kann, wo der Wert der ursprÃŧnglichen Abhängigkeit verwendet wurde. -### Anwendungsfälle: Externer Service +### Anwendungsfälle: Externer Service { #use-cases-external-service } Ein Beispiel kÃļnnte sein, dass Sie einen externen Authentifizierungsanbieter haben, mit dem Sie sich verbinden mÃŧssen. Sie senden ihm ein Token und er gibt einen authentifizierten Benutzer zurÃŧck. -Dieser Anbieter berechnet Ihnen mÃļglicherweise GebÃŧhren pro Anfrage, und der Aufruf kÃļnnte etwas länger dauern, als wenn Sie einen vordefinierten Scheinbenutzer fÃŧr Tests hätten. +Dieser Anbieter berechnet Ihnen mÃļglicherweise GebÃŧhren pro Request, und der Aufruf kÃļnnte etwas länger dauern, als wenn Sie einen vordefinierten Mock-Benutzer fÃŧr Tests hätten. Sie mÃļchten den externen Anbieter wahrscheinlich einmal testen, ihn aber nicht unbedingt bei jedem weiteren ausgefÃŧhrten Test aufrufen. -In diesem Fall kÃļnnen Sie die Abhängigkeit, die diesen Anbieter aufruft, Ãŧberschreiben und eine benutzerdefinierte Abhängigkeit verwenden, die einen Scheinbenutzer zurÃŧckgibt, nur fÃŧr Ihre Tests. +In diesem Fall kÃļnnen Sie die Abhängigkeit, die diesen Anbieter aufruft, Ãŧberschreiben und eine benutzerdefinierte Abhängigkeit verwenden, die einen Mock-Benutzer zurÃŧckgibt, nur fÃŧr Ihre Tests. -### Verwenden Sie das Attribut `app.dependency_overrides`. +### Das Attribut `app.dependency_overrides` verwenden { #use-the-app-dependency-overrides-attribute } -FÃŧr diese Fälle verfÃŧgt Ihre **FastAPI**-Anwendung Ãŧber das Attribut `app.dependency_overrides`, bei diesem handelt sich um ein einfaches `dict`. +FÃŧr diese Fälle verfÃŧgt Ihre **FastAPI**-Anwendung Ãŧber das Attribut `app.dependency_overrides`, bei diesem handelt sich um ein einfaches `dict`. Um eine Abhängigkeit fÃŧr das Testen zu Ãŧberschreiben, geben Sie als SchlÃŧssel die ursprÃŧngliche Abhängigkeit (eine Funktion) und als Wert Ihre Überschreibung der Abhängigkeit (eine andere Funktion) ein. @@ -46,6 +46,7 @@ Anschließend kÃļnnen Sie Ihre Überschreibungen zurÃŧcksetzen (entfernen), inde app.dependency_overrides = {} ``` + /// tip | Tipp Wenn Sie eine Abhängigkeit nur während einiger Tests Ãŧberschreiben mÃļchten, kÃļnnen Sie die Überschreibung zu Beginn des Tests (innerhalb der Testfunktion) festlegen und am Ende (am Ende der Testfunktion) zurÃŧcksetzen. diff --git a/docs/de/docs/advanced/testing-events.md b/docs/de/docs/advanced/testing-events.md index 05d6bcb2b..1a68b7714 100644 --- a/docs/de/docs/advanced/testing-events.md +++ b/docs/de/docs/advanced/testing-events.md @@ -1,5 +1,12 @@ -# Events testen: Hochfahren – Herunterfahren +# Events testen: Lifespan und Startup – Shutdown { #testing-events-lifespan-and-startup-shutdown } -Wenn Sie in Ihren Tests Ihre Event-Handler (`startup` und `shutdown`) ausfÃŧhren wollen, kÃļnnen Sie den `TestClient` mit einer `with`-Anweisung verwenden: +Wenn Sie `lifespan` in Ihren Tests ausfÃŧhren mÃŧssen, kÃļnnen Sie den `TestClient` mit einer `with`-Anweisung verwenden: + +{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *} + + +Sie kÃļnnen mehr Details unter [„Lifespan in Tests ausfÃŧhren in der offiziellen Starlette-Dokumentation.“](https://www.starlette.io/lifespan/#running-lifespan-in-tests) nachlesen. + +FÃŧr die deprecateten Events `startup` und `shutdown` kÃļnnen Sie den `TestClient` wie folgt verwenden: {* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *} diff --git a/docs/de/docs/advanced/testing-websockets.md b/docs/de/docs/advanced/testing-websockets.md index 5932e6d6a..a71310cbf 100644 --- a/docs/de/docs/advanced/testing-websockets.md +++ b/docs/de/docs/advanced/testing-websockets.md @@ -1,4 +1,4 @@ -# WebSockets testen +# WebSockets testen { #testing-websockets } Sie kÃļnnen den schon bekannten `TestClient` zum Testen von WebSockets verwenden. @@ -8,6 +8,6 @@ Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung z /// note | Hinweis -Weitere Informationen finden Sie in der Starlette-Dokumentation zum Testen von WebSockets. +Weitere Informationen finden Sie in Starlettes Dokumentation zum Testen von WebSockets. /// diff --git a/docs/de/docs/advanced/using-request-directly.md b/docs/de/docs/advanced/using-request-directly.md index a0a5ec1ab..7782237ec 100644 --- a/docs/de/docs/advanced/using-request-directly.md +++ b/docs/de/docs/advanced/using-request-directly.md @@ -1,6 +1,6 @@ -# Den Request direkt verwenden +# Den Request direkt verwenden { #using-the-request-directly } -Bisher haben Sie die Teile des Requests, die Sie benÃļtigen, mithilfe von deren Typen deklariert. +Bisher haben Sie die Teile des Requests, die Sie benÃļtigen, mithilfe von deren Typen deklariert. Daten nehmend von: @@ -13,9 +13,9 @@ Und indem Sie das tun, validiert **FastAPI** diese Daten, konvertiert sie und ge Es gibt jedoch Situationen, in denen Sie mÃļglicherweise direkt auf das `Request`-Objekt zugreifen mÃŧssen. -## Details zum `Request`-Objekt +## Details zum `Request`-Objekt { #details-about-the-request-object } -Da **FastAPI** unter der Haube eigentlich **Starlette** ist, mit einer Ebene von mehreren Tools darÃŧber, kÃļnnen Sie Starlette's `Request`-Objekt direkt verwenden, wenn Sie es benÃļtigen. +Da **FastAPI** unter der Haube eigentlich **Starlette** ist, mit einer Ebene von mehreren Tools darÃŧber, kÃļnnen Sie Starlettes `Request`-Objekt direkt verwenden, wenn Sie es benÃļtigen. Das bedeutet allerdings auch, dass, wenn Sie Daten direkt vom `Request`-Objekt nehmen (z. B. dessen Body lesen), diese von FastAPI nicht validiert, konvertiert oder dokumentiert werden (mit OpenAPI, fÃŧr die automatische API-Benutzeroberfläche). @@ -23,7 +23,7 @@ Obwohl jeder andere normal deklarierte Parameter (z. B. der Body, mit einem Pyda Es gibt jedoch bestimmte Fälle, in denen es nÃŧtzlich ist, auf das `Request`-Objekt zuzugreifen. -## Das `Request`-Objekt direkt verwenden +## Das `Request`-Objekt direkt verwenden { #use-the-request-object-directly } Angenommen, Sie mÃļchten auf die IP-Adresse/den Host des Clients in Ihrer *Pfadoperation-Funktion* zugreifen. @@ -43,7 +43,7 @@ Auf die gleiche Weise kÃļnnen Sie wie gewohnt jeden anderen Parameter deklariere /// -## `Request`-Dokumentation +## `Request`-Dokumentation { #request-documentation } Weitere Details zum `Request`-Objekt finden Sie in der offiziellen Starlette-Dokumentation. diff --git a/docs/de/docs/advanced/websockets.md b/docs/de/docs/advanced/websockets.md index 020c20bc0..ad1f6f5b1 100644 --- a/docs/de/docs/advanced/websockets.md +++ b/docs/de/docs/advanced/websockets.md @@ -1,10 +1,10 @@ -# WebSockets +# WebSockets { #websockets } Sie kÃļnnen WebSockets mit **FastAPI** verwenden. -## `WebSockets` installieren +## `websockets` installieren { #install-websockets } -Zuerst mÃŧssen Sie `WebSockets` installieren: +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und `websockets` installieren (eine Python-Bibliothek, die die Verwendung des „WebSocket“-Protokolls erleichtert):
@@ -16,9 +16,9 @@ $ pip install websockets
-## WebSockets-Client +## WebSockets-Client { #websockets-client } -### In Produktion +### In Produktion { #in-production } In Ihrem Produktionssystem haben Sie wahrscheinlich ein Frontend, das mit einem modernen Framework wie React, Vue.js oder Angular erstellt wurde. @@ -36,11 +36,11 @@ Das ist natÃŧrlich nicht optimal und man wÃŧrde das nicht in der Produktion mach In der Produktion hätten Sie eine der oben genannten Optionen. -Aber es ist die einfachste MÃļglichkeit, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben: +Aber es ist der einfachste Weg, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben: {* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} -## Einen `websocket` erstellen +## Einen `websocket` erstellen { #create-a-websocket } Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`: @@ -48,13 +48,13 @@ Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`: /// note | Technische Details -Sie kÃļnnen auch `from starlette.websockets import WebSocket` verwenden. +Sie kÃļnnten auch `from starlette.websockets import WebSocket` verwenden. **FastAPI** stellt den gleichen `WebSocket` direkt zur VerfÃŧgung, als Annehmlichkeit fÃŧr Sie, den Entwickler. Er kommt aber direkt von Starlette. /// -## Nachrichten erwarten und Nachrichten senden +## Nachrichten erwarten und Nachrichten senden { #await-for-messages-and-send-messages } In Ihrer WebSocket-Route kÃļnnen Sie Nachrichten `await`en und Nachrichten senden. @@ -62,14 +62,14 @@ In Ihrer WebSocket-Route kÃļnnen Sie Nachrichten `await`en und Nachrichten sende Sie kÃļnnen Binär-, Text- und JSON-Daten empfangen und senden. -## Es ausprobieren +## Es ausprobieren { #try-it } Wenn Ihre Datei `main.py` heißt, fÃŧhren Sie Ihre Anwendung so aus:
```console -$ uvicorn main:app --reload +$ fastapi dev main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -96,7 +96,7 @@ Sie kÃļnnen viele Nachrichten senden (und empfangen): Und alle verwenden dieselbe WebSocket-Verbindung. -## Verwendung von `Depends` und anderen +## Verwendung von `Depends` und anderen { #using-depends-and-others } In WebSocket-Endpunkten kÃļnnen Sie Folgendes aus `fastapi` importieren und verwenden: @@ -111,7 +111,7 @@ Diese funktionieren auf die gleiche Weise wie fÃŧr andere FastAPI-Endpunkte/*Pfa {* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *} -/// info +/// info | Info Da es sich um einen WebSocket handelt, macht es keinen Sinn, eine `HTTPException` auszulÃļsen, stattdessen lÃļsen wir eine `WebSocketException` aus. @@ -119,14 +119,14 @@ Sie kÃļnnen einen „Closing“-Code verwenden, aus den ```console -$ uvicorn main:app --reload +$ fastapi dev main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -142,7 +142,7 @@ Dort kÃļnnen Sie einstellen: /// tip | Tipp -Beachten Sie, dass der Query-„Token“ von einer Abhängigkeit verarbeitet wird. +Beachten Sie, dass die Query `token` von einer Abhängigkeit verarbeitet wird. /// @@ -150,7 +150,7 @@ Damit kÃļnnen Sie den WebSocket verbinden und dann Nachrichten senden und empfan -## VerbindungsabbrÃŧche und mehreren Clients handhaben +## VerbindungsabbrÃŧche und mehrere Clients handhaben { #handling-disconnections-and-multiple-clients } Wenn eine WebSocket-Verbindung geschlossen wird, lÃļst `await websocket.receive_text()` eine `WebSocketDisconnect`-Exception aus, die Sie dann wie in folgendem Beispiel abfangen und behandeln kÃļnnen. @@ -178,7 +178,7 @@ Wenn Sie etwas benÃļtigen, das sich leicht in FastAPI integrieren lässt, aber r /// -## Mehr Informationen +## Mehr Informationen { #more-info } Weitere Informationen zu Optionen finden Sie in der Dokumentation von Starlette: diff --git a/docs/de/docs/advanced/wsgi.md b/docs/de/docs/advanced/wsgi.md index c0998a621..1de9739dd 100644 --- a/docs/de/docs/advanced/wsgi.md +++ b/docs/de/docs/advanced/wsgi.md @@ -1,10 +1,10 @@ -# WSGI inkludieren – Flask, Django und andere +# WSGI inkludieren – Flask, Django und andere { #including-wsgi-flask-django-others } Sie kÃļnnen WSGI-Anwendungen mounten, wie Sie es in [Unteranwendungen – Mounts](sub-applications.md){.internal-link target=_blank}, [Hinter einem Proxy](behind-a-proxy.md){.internal-link target=_blank} gesehen haben. Dazu kÃļnnen Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wrappen, zum Beispiel Flask, Django usw. -## `WSGIMiddleware` verwenden +## `WSGIMiddleware` verwenden { #using-wsgimiddleware } Sie mÃŧssen `WSGIMiddleware` importieren. @@ -12,15 +12,15 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware. Und dann mounten Sie das auf einem Pfad. -{* ../../docs_src/wsgi/tutorial001.py hl[2:3,23] *} +{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *} -## Es ansehen +## Es testen { #check-it } -Jetzt wird jede Anfrage unter dem Pfad `/v1/` von der Flask-Anwendung verarbeitet. +Jetzt wird jeder Request unter dem Pfad `/v1/` von der Flask-Anwendung verarbeitet. Und der Rest wird von **FastAPI** gehandhabt. -Wenn Sie das mit Uvicorn ausfÃŧhren und auf http://localhost:8000/v1/ gehen, sehen Sie die Response von Flask: +Wenn Sie das ausfÃŧhren und auf http://localhost:8000/v1/ gehen, sehen Sie die Response von Flask: ```txt Hello, World from Flask! diff --git a/docs/de/docs/alternatives.md b/docs/de/docs/alternatives.md index 611315501..15c0719fb 100644 --- a/docs/de/docs/alternatives.md +++ b/docs/de/docs/alternatives.md @@ -1,8 +1,8 @@ -# Alternativen, Inspiration und Vergleiche +# Alternativen, Inspiration und Vergleiche { #alternatives-inspiration-and-comparisons } -Was hat **FastAPI** inspiriert, ein Vergleich zu Alternativen, und was FastAPI von diesen gelernt hat. +Was hat **FastAPI** inspiriert, wie es sich im Vergleich zu Alternativen verhält und was es von ihnen gelernt hat. -## EinfÃŧhrung +## EinfÃŧhrung { #intro } **FastAPI** wÃŧrde ohne die frÃŧhere Arbeit anderer nicht existieren. @@ -12,17 +12,17 @@ Ich habe die Schaffung eines neuen Frameworks viele Jahre lang vermieden. Zuerst Aber irgendwann gab es keine andere MÃļglichkeit, als etwas zu schaffen, das all diese Funktionen bereitstellte, die besten Ideen frÃŧherer Tools aufnahm und diese auf die bestmÃļgliche Weise kombinierte, wobei Sprachfunktionen verwendet wurden, die vorher noch nicht einmal verfÃŧgbar waren (Python 3.6+ Typhinweise). -## Vorherige Tools +## Vorherige Tools { #previous-tools } -### Django +### Django { #django } Es ist das beliebteste Python-Framework und genießt großes Vertrauen. Es wird zum Aufbau von Systemen wie Instagram verwendet. -Ist relativ eng mit relationalen Datenbanken (wie MySQL oder PostgreSQL) gekoppelt, daher ist es nicht sehr einfach, eine NoSQL-Datenbank (wie Couchbase, MongoDB, Cassandra, usw.) als Hauptspeicherengine zu verwenden. +Es ist relativ eng mit relationalen Datenbanken (wie MySQL oder PostgreSQL) gekoppelt, daher ist es nicht sehr einfach, eine NoSQL-Datenbank (wie Couchbase, MongoDB, Cassandra, usw.) als Hauptspeicherengine zu verwenden. -Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie IoT-Geräten) verwendet werden, um mit ihm zu kommunizieren. +Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie IoT-Geräten) verwendet werden, um mit ihm zu kommunizieren. -### Django REST Framework +### Django REST Framework { #django-rest-framework } Das Django REST Framework wurde als flexibles Toolkit zum Erstellen von Web-APIs unter Verwendung von Django entwickelt, um dessen API-MÃļglichkeiten zu verbessern. @@ -42,7 +42,7 @@ Eine automatische API-Dokumentationsoberfläche zu haben. /// -### Flask +### Flask { #flask } Flask ist ein „Mikroframework“, es enthält weder Datenbankintegration noch viele der Dinge, die standardmäßig in Django enthalten sind. @@ -64,7 +64,7 @@ Ein Mikroframework zu sein. Es einfach zu machen, die benÃļtigten Tools und Teil /// -### Requests +### Requests { #requests } **FastAPI** ist eigentlich keine Alternative zu **Requests**. Der Umfang der beiden ist sehr unterschiedlich. @@ -82,7 +82,7 @@ Aus diesem Grund heißt es auf der offiziellen Website: > Requests ist eines der am häufigsten heruntergeladenen Python-Packages aller Zeiten -Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-Request zu machen, wÃŧrden Sie schreiben: +Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-Request zu machen, wÃŧrden Sie schreiben: ```Python response = requests.get("http://example.com/some/url") @@ -106,7 +106,7 @@ Sehen Sie sich die Ähnlichkeiten in `requests.get(...)` und `@app.get(...)` an. /// -### Swagger / OpenAPI +### Swagger / OpenAPI { #swagger-openapi } Die Hauptfunktion, die ich vom Django REST Framework haben wollte, war die automatische API-Dokumentation. @@ -131,13 +131,13 @@ Diese beiden wurden ausgewählt, weil sie ziemlich beliebt und stabil sind, aber /// -### Flask REST Frameworks +### Flask REST Frameworks { #flask-rest-frameworks } Es gibt mehrere Flask REST Frameworks, aber nachdem ich die Zeit und Arbeit investiert habe, sie zu untersuchen, habe ich festgestellt, dass viele nicht mehr unterstÃŧtzt werden oder abgebrochen wurden und dass mehrere fortbestehende Probleme sie unpassend machten. -### Marshmallow +### Marshmallow { #marshmallow } -Eine der von API-Systemen benÃļtigen Hauptfunktionen ist die Daten-„Serialisierung“, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw. +Eine der von API-Systemen benÃļtigten Hauptfunktionen ist die Daten-„Serialisierung“, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw. Eine weitere wichtige Funktion, benÃļtigt von APIs, ist die Datenvalidierung, welche sicherstellt, dass die Daten unter gegebenen Umständen gÃŧltig sind. Zum Beispiel, dass ein Feld ein `int` ist und kein zufälliger String. Das ist besonders nÃŧtzlich fÃŧr hereinkommende Daten. @@ -145,7 +145,7 @@ Ohne ein Datenvalidierungssystem mÃŧssten Sie alle PrÃŧfungen manuell im Code du FÃŧr diese Funktionen wurde Marshmallow entwickelt. Es ist eine großartige Bibliothek und ich habe sie schon oft genutzt. -Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein Schema zu definieren, mÃŧssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden. +Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein Schema zu definieren, mÃŧssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden. /// check | Inspirierte **FastAPI** @@ -153,7 +153,7 @@ Code zu verwenden, um „Schemas“ zu definieren, welche Datentypen und Validie /// -### Webargs +### Webargs { #webargs } Eine weitere wichtige Funktion, die von APIs benÃļtigt wird, ist das Parsen von Daten aus eingehenden Requests. @@ -163,7 +163,7 @@ Es verwendet unter der Haube Marshmallow, um die Datenvalidierung durchzufÃŧhren Es ist ein großartiges Tool und ich habe es auch oft verwendet, bevor ich **FastAPI** hatte. -/// info +/// info | Info Webargs wurde von denselben Marshmallow-Entwicklern erstellt. @@ -175,7 +175,7 @@ Eingehende Requestdaten automatisch zu validieren. /// -### APISpec +### APISpec { #apispec } Marshmallow und Webargs bieten Validierung, Parsen und Serialisierung als Plugins. @@ -193,7 +193,7 @@ Aber dann haben wir wieder das Problem einer Mikrosyntax innerhalb eines Python- Der Texteditor kann dabei nicht viel helfen. Und wenn wir Parameter oder Marshmallow-Schemas ändern und vergessen, auch den YAML-Docstring zu ändern, wäre das generierte Schema veraltet. -/// info +/// info | Info APISpec wurde von denselben Marshmallow-Entwicklern erstellt. @@ -205,7 +205,7 @@ Den offenen Standard fÃŧr APIs, OpenAPI, zu unterstÃŧtzen. /// -### Flask-apispec +### Flask-apispec { #flask-apispec } Hierbei handelt es sich um ein Flask-Plugin, welches Webargs, Marshmallow und APISpec miteinander verbindet. @@ -225,7 +225,7 @@ Die Verwendung fÃŧhrte zur Entwicklung mehrerer Flask-Full-Stack-Generatoren. Di Und dieselben Full-Stack-Generatoren bildeten die Basis der [**FastAPI**-Projektgeneratoren](project-generation.md){.internal-link target=_blank}. -/// info +/// info | Info Flask-apispec wurde von denselben Marshmallow-Entwicklern erstellt. @@ -237,7 +237,7 @@ Das OpenAPI-Schema automatisch zu generieren, aus demselben Code, welcher die Se /// -### NestJS (und Angular) +### NestJS (und Angular) { #nestjs-and-angular } Dies ist nicht einmal Python, NestJS ist ein von Angular inspiriertes JavaScript (TypeScript) NodeJS Framework. @@ -249,7 +249,7 @@ Da die Parameter mit TypeScript-Typen beschrieben werden (ähnlich den Python-Ty Da TypeScript-Daten jedoch nach der Kompilierung nach JavaScript nicht erhalten bleiben, kÃļnnen die Typen nicht gleichzeitig die Validierung, Serialisierung und Dokumentation definieren. Aus diesem Grund und aufgrund einiger Designentscheidungen ist es fÃŧr die Validierung, Serialisierung und automatische Schemagenerierung erforderlich, an vielen Stellen Dekoratoren hinzuzufÃŧgen. Es wird also ziemlich ausfÃŧhrlich. -Es kann nicht sehr gut mit verschachtelten Modellen umgehen. Wenn es sich beim JSON-Body in der Anfrage also um ein JSON-Objekt mit inneren Feldern handelt, die wiederum verschachtelte JSON-Objekte sind, kann er nicht richtig dokumentiert und validiert werden. +Es kann nicht sehr gut mit verschachtelten Modellen umgehen. Wenn es sich beim JSON-Body im Request also um ein JSON-Objekt mit inneren Feldern handelt, die wiederum verschachtelte JSON-Objekte sind, kann er nicht richtig dokumentiert und validiert werden. /// check | Inspirierte **FastAPI** @@ -259,7 +259,7 @@ Python-Typen zu verwenden, um eine hervorragende EditorunterstÃŧtzung zu erhalte /// -### Sanic +### Sanic { #sanic } Es war eines der ersten extrem schnellen Python-Frameworks, welches auf `asyncio` basierte. Es wurde so gestaltet, dass es Flask sehr ähnlich ist. @@ -279,11 +279,11 @@ Aus diesem Grund basiert **FastAPI** auf Starlette, da dieses das schnellste ver /// -### Falcon +### Falcon { #falcon } Falcon ist ein weiteres leistungsstarkes Python-Framework. Es ist minimalistisch konzipiert und dient als Grundlage fÃŧr andere Frameworks wie Hug. -Es ist so konzipiert, dass es Ãŧber Funktionen verfÃŧgt, welche zwei Parameter empfangen, einen „Request“ und eine „Response“. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht mÃļglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren. +Es ist so konzipiert, dass es Ãŧber Funktionen verfÃŧgt, welche zwei Parameter empfangen, einen „Request“ und eine „Response“. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht mÃļglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren. Daher mÃŧssen Datenvalidierung, Serialisierung und Dokumentation im Code und nicht automatisch erfolgen. Oder sie mÃŧssen als Framework oberhalb von Falcon implementiert werden, so wie Hug. Dieselbe Unterscheidung findet auch in anderen Frameworks statt, die vom Design von Falcon inspiriert sind und ein Requestobjekt und ein Responseobjekt als Parameter haben. @@ -297,7 +297,7 @@ Obwohl er in FastAPI optional ist und hauptsächlich zum Festlegen von Headern, /// -### Molten +### Molten { #molten } Ich habe Molten in den ersten Phasen der Entwicklung von **FastAPI** entdeckt. Und es hat ganz ähnliche Ideen: @@ -321,7 +321,7 @@ Das hat tatsächlich dazu gefÃŧhrt, dass Teile von Pydantic aktualisiert wurden, /// -### Hug +### Hug { #hug } Hug war eines der ersten Frameworks, welches die Deklaration von API-Parametertypen mithilfe von Python-Typhinweisen implementierte. Das war eine großartige Idee, die andere Tools dazu inspirierte, dasselbe zu tun. @@ -335,9 +335,9 @@ Es verfÃŧgt Ãŧber eine interessante, ungewÃļhnliche Funktion: Mit demselben Fram Da es auf dem bisherigen Standard fÃŧr synchrone Python-Webframeworks (WSGI) basiert, kann es nicht mit Websockets und anderen Dingen umgehen, verfÃŧgt aber dennoch Ãŧber eine hohe Performanz. -/// info +/// info | Info -Hug wurde von Timothy Crosley erstellt, dem gleichen SchÃļpfer von `isort`, einem großartigen Tool zum automatischen Sortieren von Importen in Python-Dateien. +Hug wurde von Timothy Crosley erstellt, demselben SchÃļpfer von `isort`, einem großartigen Tool zum automatischen Sortieren von Importen in Python-Dateien. /// @@ -351,7 +351,7 @@ Hug inspirierte **FastAPI** dazu, einen `response`-Parameter in Funktionen zu de /// -### APIStar (â‰Ļ 0.5) +### APIStar (â‰Ļ 0.5) { #apistar-0-5 } Kurz bevor ich mich entschied, **FastAPI** zu erstellen, fand ich den **APIStar**-Server. Er hatte fast alles, was ich suchte, und ein tolles Design. @@ -375,7 +375,7 @@ Es handelte sich nicht länger um ein API-Webframework, da sich der Entwickler a Jetzt handelt es sich bei APIStar um eine Reihe von Tools zur Validierung von OpenAPI-Spezifikationen, nicht um ein Webframework. -/// info +/// info | Info APIStar wurde von Tom Christie erstellt. Derselbe, welcher Folgendes erstellt hat: @@ -399,9 +399,9 @@ Ich betrachte **FastAPI** als einen „spirituellen Nachfolger“ von APIStar, w /// -## Verwendet von **FastAPI** +## Verwendet von **FastAPI** { #used-by-fastapi } -### Pydantic +### Pydantic { #pydantic } Pydantic ist eine Bibliothek zum Definieren von Datenvalidierung, Serialisierung und Dokumentation (unter Verwendung von JSON Schema) basierend auf Python-Typhinweisen. @@ -417,7 +417,7 @@ Die gesamte Datenvalidierung, Datenserialisierung und automatische Modelldokumen /// -### Starlette +### Starlette { #starlette } Starlette ist ein leichtgewichtiges ASGI-Framework/Toolkit, welches sich ideal fÃŧr die Erstellung hochperformanter asynchroner Dienste eignet. @@ -428,9 +428,9 @@ Es bietet: * Eine sehr beeindruckende Leistung. * WebSocket-UnterstÃŧtzung. * Hintergrundtasks im selben Prozess. -* Events fÃŧr das Hoch- und Herunterfahren. +* Startup- und Shutdown-Events. * Testclient basierend auf HTTPX. -* CORS, GZip, statische Dateien, Streamende Responses. +* CORS, GZip, statische Dateien, Responses streamen. * Session- und Cookie-UnterstÃŧtzung. * 100 % Testabdeckung. * 100 % Typannotierte Codebasis. @@ -462,7 +462,7 @@ Alles, was Sie also mit Starlette machen kÃļnnen, kÃļnnen Sie direkt mit **FastA /// -### Uvicorn +### Uvicorn { #uvicorn } Uvicorn ist ein blitzschneller ASGI-Server, der auf uvloop und httptools basiert. @@ -474,12 +474,12 @@ Es ist der empfohlene Server fÃŧr Starlette und **FastAPI**. Hauptwebserver zum AusfÃŧhren von **FastAPI**-Anwendungen. -Sie kÃļnnen ihn mit Gunicorn kombinieren, um einen asynchronen Multiprozess-Server zu erhalten. +Sie kÃļnnen auch die Kommandozeilenoption `--workers` verwenden, um einen asynchronen Multiprozess-Server zu erhalten. Weitere Details finden Sie im Abschnitt [Deployment](deployment/index.md){.internal-link target=_blank}. /// -## Benchmarks und Geschwindigkeit +## Benchmarks und Geschwindigkeit { #benchmarks-and-speed } Um den Unterschied zwischen Uvicorn, Starlette und FastAPI zu verstehen, zu vergleichen und zu sehen, lesen Sie den Abschnitt Ãŧber [Benchmarks](benchmarks.md){.internal-link target=_blank}. diff --git a/docs/de/docs/async.md b/docs/de/docs/async.md index b5b3a4c52..3dbd442e5 100644 --- a/docs/de/docs/async.md +++ b/docs/de/docs/async.md @@ -1,8 +1,8 @@ -# Nebenläufigkeit und async / await +# Nebenläufigkeit und async / await { #concurrency-and-async-await } Details zur `async def`-Syntax fÃŧr *Pfadoperation-Funktionen* und Hintergrundinformationen zu asynchronem Code, Nebenläufigkeit und Parallelität. -## In Eile? +## In Eile? { #in-a-hurry } TL;DR: @@ -12,7 +12,7 @@ Wenn Sie Bibliotheken von Dritten verwenden, die mit `await` aufgerufen werden m results = await some_library() ``` -Dann deklarieren Sie Ihre *Pfadoperation-Funktionen* mit `async def` wie in: +Dann deklarieren Sie Ihre *Pfadoperation-Funktionen* mit `async def`, wie in: ```Python hl_lines="2" @app.get('/') @@ -21,7 +21,7 @@ async def read_results(): return results ``` -/// note +/// note | Hinweis Sie kÃļnnen `await` nur innerhalb von Funktionen verwenden, die mit `async def` erstellt wurden. @@ -29,7 +29,7 @@ Sie kÃļnnen `await` nur innerhalb von Funktionen verwenden, die mit `async def` --- -Wenn Sie eine Bibliothek eines Dritten verwenden, die mit etwas kommuniziert (einer Datenbank, einer API, dem Dateisystem, usw.) und welche die Verwendung von `await` nicht unterstÃŧtzt (dies ist derzeit bei den meisten Datenbankbibliotheken der Fall), dann deklarieren Sie Ihre *Pfadoperation-Funktionen* ganz normal nur mit `def`, etwa: +Wenn Sie eine Bibliothek eines Dritten verwenden, die mit etwas kommuniziert (einer Datenbank, einer API, dem Dateisystem, usw.) und welche die Verwendung von `await` nicht unterstÃŧtzt (dies ist derzeit bei den meisten Datenbankbibliotheken der Fall), dann deklarieren Sie Ihre *Pfadoperation-Funktionen* ganz normal nur mit `def`, wie in: ```Python hl_lines="2" @app.get('/') @@ -40,7 +40,7 @@ def results(): --- -Wenn Ihre Anwendung (irgendwie) mit nichts anderem kommunizieren und auf dessen Antwort warten muss, verwenden Sie `async def`. +Wenn Ihre Anwendung (irgendwie) nicht mit etwas anderem kommunizieren und auf dessen Antwort warten muss, verwenden Sie `async def`, auch wenn Sie `await` im Inneren nicht verwenden mÃŧssen. --- @@ -52,11 +52,11 @@ Wenn Sie sich unsicher sind, verwenden Sie einfach `def`. Wie dem auch sei, in jedem der oben genannten Fälle wird FastAPI immer noch asynchron arbeiten und extrem schnell sein. -Wenn Sie jedoch den oben genannten Schritten folgen, kÃļnnen einige Performance-Optimierungen vorgenommen werden. +Wenn Sie jedoch den oben genannten Schritten folgen, kÃļnnen einige Performanz-Optimierungen vorgenommen werden. -## Technische Details +## Technische Details { #technical-details } -Moderne Versionen von Python unterstÃŧtzen **„asynchronen Code“** unter Verwendung sogenannter **„Coroutinen“** mithilfe der Syntax **`async`** und **`await`**. +Moderne Versionen von Python unterstÃŧtzen **„asynchronen Code“** unter Verwendung sogenannter **„Coroutinen“** mithilfe der Syntax **`async` und `await`**. Nehmen wir obigen Satz in den folgenden Abschnitten Schritt fÃŧr Schritt unter die Lupe: @@ -64,13 +64,13 @@ Nehmen wir obigen Satz in den folgenden Abschnitten Schritt fÃŧr Schritt unter d * **`async` und `await`** * **Coroutinen** -## Asynchroner Code +## Asynchroner Code { #asynchronous-code } -Asynchroner Code bedeutet lediglich, dass die Sprache đŸ’Ŧ eine MÃļglichkeit hat, dem Computersystem / Programm 🤖 mitzuteilen, dass es 🤖 an einem bestimmten Punkt im Code darauf warten muss, dass *etwas anderes* irgendwo anders fertig wird. Nehmen wir an, *etwas anderes* ist hier „Langsam-Datei“ 📝. +Asynchroner Code bedeutet lediglich, dass die Sprache đŸ’Ŧ eine MÃļglichkeit hat, dem Computer / Programm 🤖 mitzuteilen, dass es 🤖 an einem bestimmten Punkt im Code darauf warten muss, dass *etwas anderes* irgendwo anders fertig wird. Nehmen wir an, *etwas anderes* ist hier „Langsam-Datei“ 📝. Während der Zeit, die „Langsam-Datei“ 📝 benÃļtigt, kann das System also andere Aufgaben erledigen. -Dann kommt das System / Programm 🤖 bei jeder Gelegenheit zurÃŧck, wenn es entweder wieder wartet, oder wann immer es 🤖 die ganze Arbeit erledigt hat, die zu diesem Zeitpunkt zu tun war. Und es 🤖 wird nachschauen, ob eine der Aufgaben, auf die es gewartet hat, fertig damit ist, zu tun, was sie tun sollte. +Dann kommt der Computer / das Programm 🤖 bei jeder Gelegenheit zurÃŧck, weil es entweder wieder wartet oder wann immer es 🤖 die ganze Arbeit erledigt hat, die zu diesem Zeitpunkt zu tun war. Und es 🤖 wird nachschauen, ob eine der Aufgaben, auf die es gewartet hat, fertig ist. Dann nimmt es 🤖 die erste erledigte Aufgabe (sagen wir, unsere „Langsam-Datei“ 📝) und bearbeitet sie weiter. @@ -87,13 +87,13 @@ Das „Warten auf etwas anderes“ bezieht sich normalerweise auf I/O-Operationen verbraucht wird, nennt man dies auch „I/O-lastige“ („I/O bound“) Operationen. -„Asynchron“, sagt man, weil das Computersystem / Programm nicht mit einer langsamen Aufgabe „synchronisiert“ werden muss und nicht auf den genauen Moment warten muss, in dem die Aufgabe beendet ist, ohne dabei etwas zu tun, um schließlich das Ergebnis der Aufgabe zu Ãŧbernehmen und die Arbeit fortsetzen zu kÃļnnen. +„Asynchron“, sagt man, weil der Computer / das Programm nicht mit einer langsamen Aufgabe „synchronisiert“ werden muss und nicht auf den genauen Moment warten muss, in dem die Aufgabe beendet ist, ohne dabei etwas zu tun, um schließlich das Ergebnis der Aufgabe zu Ãŧbernehmen und die Arbeit fortsetzen zu kÃļnnen. -Da es sich stattdessen um ein „asynchrones“ System handelt, kann die Aufgabe nach Abschluss ein wenig (einige Mikrosekunden) in der Schlange warten, bis das System / Programm seine anderen Dinge erledigt hat und zurÃŧckkommt, um die Ergebnisse entgegenzunehmen und mit ihnen weiterzuarbeiten. +Da es sich stattdessen um ein „asynchrones“ System handelt, kann die Aufgabe nach Abschluss ein wenig (einige Mikrosekunden) in der Schlange warten, bis der Computer / das Programm seine anderen Dinge erledigt hat und zurÃŧckkommt, um die Ergebnisse entgegenzunehmen und mit ihnen weiterzuarbeiten. -FÃŧr „synchron“ (im Gegensatz zu „asynchron“) wird auch oft der Begriff „sequentiell“ verwendet, da das System / Programm alle Schritte in einer Sequenz („der Reihe nach“) ausfÃŧhrt, bevor es zu einer anderen Aufgabe wechselt, auch wenn diese Schritte mit Warten verbunden sind. +FÃŧr „synchron“ (im Gegensatz zu „asynchron“) wird auch oft der Begriff „sequentiell“ verwendet, da der Computer / das Programm alle Schritte in einer Sequenz („der Reihe nach“) ausfÃŧhrt, bevor es zu einer anderen Aufgabe wechselt, auch wenn diese Schritte mit Warten verbunden sind. -### Nebenläufigkeit und Hamburger +### Nebenläufigkeit und Hamburger { #concurrency-and-burgers } Diese oben beschriebene Idee von **asynchronem** Code wird manchmal auch **„Nebenläufigkeit“** genannt. Sie unterscheidet sich von **„Parallelität“**. @@ -103,7 +103,7 @@ Aber die Details zwischen *Nebenläufigkeit* und *Parallelität* sind ziemlich u Um den Unterschied zu erkennen, stellen Sie sich die folgende Geschichte Ãŧber Hamburger vor: -### Nebenläufige Hamburger +### Nebenläufige Hamburger { #concurrent-burgers } Sie gehen mit Ihrem Schwarm Fastfood holen, stehen in der Schlange, während der Kassierer die Bestellungen der Leute vor Ihnen entgegennimmt. 😍 @@ -139,7 +139,7 @@ Sie und Ihr Schwarm essen die Burger und haben eine schÃļne Zeit. ✨ -/// info +/// info | Info Die wunderschÃļnen Illustrationen stammen von Ketrina Thompson. 🎨 @@ -147,7 +147,7 @@ Die wunderschÃļnen Illustrationen stammen von Ketrina Thompson. 🎨 @@ -233,15 +233,15 @@ Und man muss lange in der Schlange warten 🕙 sonst kommt man nicht an die Reih Sie wÃŧrden Ihren Schwarm 😍 wahrscheinlich nicht mitnehmen wollen, um Besorgungen bei der Bank zu erledigen đŸĻ. -### Hamburger Schlussfolgerung +### Hamburger Schlussfolgerung { #burger-conclusion } -In diesem Szenario „Fast Food Burger mit Ihrem Schwarm“ ist es viel sinnvoller, ein nebenläufiges System zu haben â¸đŸ”€â¯, da viel gewartet wird 🕙. +In diesem Szenario „Fastfood-Burger mit Ihrem Schwarm“ ist es viel sinnvoller, ein nebenläufiges System zu haben â¸đŸ”€â¯, da viel gewartet wird 🕙. Das ist auch bei den meisten Webanwendungen der Fall. -Viele, viele Benutzer, aber Ihr Server wartet 🕙 darauf, dass deren nicht so gute Internetverbindungen die Requests Ãŧbermitteln. +Viele, viele Benutzer, aber Ihr Server wartet 🕙 darauf, dass deren nicht so gute Internetverbindungen die Requests Ãŧbermitteln. -Und dann warten 🕙, bis die Responses zurÃŧckkommen. +Und dann wieder warten 🕙, bis die Responses zurÃŧckkommen. Dieses „Warten“ 🕙 wird in Mikrosekunden gemessen, aber zusammenfassend lässt sich sagen, dass am Ende eine Menge gewartet wird. @@ -253,7 +253,7 @@ Und das ist das gleiche Leistungsniveau, das Sie mit **FastAPI** erhalten. Und da Sie Parallelität und Asynchronität gleichzeitig haben kÃļnnen, erzielen Sie eine hÃļhere Performanz als die meisten getesteten NodeJS-Frameworks und sind mit Go auf AugenhÃļhe, einer kompilierten Sprache, die näher an C liegt (alles dank Starlette). -### Ist Nebenläufigkeit besser als Parallelität? +### Ist Nebenläufigkeit besser als Parallelität? { #is-concurrency-better-than-parallelism } Nein! Das ist nicht die Moral der Geschichte. @@ -290,17 +290,17 @@ Zum Beispiel: * **Maschinelles Lernen**: Normalerweise sind viele „Matrix“- und „Vektor“-Multiplikationen erforderlich. Stellen Sie sich eine riesige Tabelle mit Zahlen vor, in der Sie alle Zahlen gleichzeitig multiplizieren. * **Deep Learning**: Dies ist ein Teilgebiet des maschinellen Lernens, daher gilt das Gleiche. Es ist nur so, dass es nicht eine einzige Tabelle mit Zahlen zum Multiplizieren gibt, sondern eine riesige Menge davon, und in vielen Fällen verwendet man einen speziellen Prozessor, um diese Modelle zu erstellen und / oder zu verwenden. -### Nebenläufigkeit + Parallelität: Web + maschinelles Lernen +### Nebenläufigkeit + Parallelität: Web + maschinelles Lernen { #concurrency-parallelism-web-machine-learning } Mit **FastAPI** kÃļnnen Sie die Vorteile der Nebenläufigkeit nutzen, die in der Webentwicklung weit verbreitet ist (derselbe Hauptvorteil von NodeJS). -Sie kÃļnnen aber auch die Vorteile von Parallelität und Multiprocessing (Mehrere Prozesse werden parallel ausgefÃŧhrt) fÃŧr **CPU-lastige** Workloads wie in Systemen fÃŧr maschinelles Lernen nutzen. +Sie kÃļnnen aber auch die Vorteile von Parallelität und Multiprocessing (mehrere Prozesse werden parallel ausgefÃŧhrt) fÃŧr **CPU-lastige** Workloads wie in Systemen fÃŧr maschinelles Lernen nutzen. Dies und die einfache Tatsache, dass Python die Hauptsprache fÃŧr **Data Science**, maschinelles Lernen und insbesondere Deep Learning ist, machen FastAPI zu einem sehr passenden Werkzeug fÃŧr Web-APIs und Anwendungen fÃŧr Data Science / maschinelles Lernen (neben vielen anderen). Wie Sie diese Parallelität in der Produktion erreichen, erfahren Sie im Abschnitt Ãŧber [Deployment](deployment/index.md){.internal-link target=_blank}. -## `async` und `await`. +## `async` und `await` { #async-and-await } Moderne Versionen von Python verfÃŧgen Ãŧber eine sehr intuitive MÃļglichkeit, asynchronen Code zu schreiben. Dadurch sieht es wie normaler „sequentieller“ Code aus und Ãŧbernimmt im richtigen Moment das „Warten“ fÃŧr Sie. @@ -316,16 +316,16 @@ Damit `await` funktioniert, muss es sich in einer Funktion befinden, die diese A ```Python hl_lines="1" async def get_burgers(number: int): - # Mach Sie hier etwas Asynchrones, um die Burger zu erstellen + # Mache hier etwas Asynchrones, um die Burger zu erstellen return burgers ``` ... statt mit `def`: ```Python hl_lines="2" -# Die ist nicht asynchron +# Dies ist nicht asynchron def get_sequential_burgers(number: int): - # Mach Sie hier etwas Sequentielles, um die Burger zu erstellen + # Mache hier etwas Sequentielles, um die Burger zu erstellen return burgers ``` @@ -349,7 +349,7 @@ async def read_burgers(): return burgers ``` -### Weitere technische Details +### Weitere technische Details { #more-technical-details } Ihnen ist wahrscheinlich aufgefallen, dass `await` nur innerhalb von Funktionen verwendet werden kann, die mit `async def` definiert sind. @@ -361,15 +361,17 @@ Wenn Sie mit **FastAPI** arbeiten, mÃŧssen Sie sich darÃŧber keine Sorgen machen Wenn Sie jedoch `async` / `await` ohne FastAPI verwenden mÃļchten, kÃļnnen Sie dies auch tun. -### Schreiben Sie Ihren eigenen asynchronen Code +### Schreiben Sie Ihren eigenen asynchronen Code { #write-your-own-async-code } -Starlette (und **FastAPI**) basiert auf AnyIO, was bedeutet, es ist sowohl kompatibel mit der Python-Standardbibliothek asyncio, als auch mit Trio. +Starlette (und **FastAPI**) basieren auf AnyIO, was bedeutet, dass es sowohl kompatibel mit der Python-Standardbibliothek asyncio als auch mit Trio ist. -Insbesondere kÃļnnen Sie AnyIO direkt verwenden fÃŧr Ihre fortgeschritten nebenläufigen und parallelen Anwendungsfälle, die fortgeschrittenere Muster in Ihrem eigenen Code erfordern. +Insbesondere kÃļnnen Sie AnyIO direkt verwenden fÃŧr Ihre fortgeschrittenen nebenläufigen Anwendungsfälle, die fortgeschrittenere Muster in Ihrem eigenen Code erfordern. -Und selbst wenn Sie FastAPI nicht verwenden wÃŧrden, kÃļnnten Sie auch Ihre eigenen asynchronen Anwendungen mit AnyIO so schreiben, dass sie hoch kompatibel sind und Sie dessen Vorteile nutzen kÃļnnen (z. B. *strukturierte Nebenläufigkeit*). +Und auch wenn Sie FastAPI nicht verwenden wÃŧrden, kÃļnnten Sie Ihre eigenen asynchronen Anwendungen mit AnyIO schreiben, um hochkompatibel zu sein und dessen Vorteile zu nutzen (z. B. *strukturierte Nebenläufigkeit*). -### Andere Formen von asynchronem Code +Ich habe eine weitere Bibliothek auf Basis von AnyIO erstellt, als dÃŧnne Schicht obendrauf, um die Typannotationen etwas zu verbessern und bessere **Autovervollständigung**, **Inline-Fehler** usw. zu erhalten. Sie hat auch eine freundliche EinfÃŧhrung und ein Tutorial, um Ihnen zu helfen, **Ihren eigenen asynchronen Code zu verstehen** und zu schreiben: Asyncer. Sie ist insbesondere nÃŧtzlich, wenn Sie **asynchronen Code mit regulärem** (blockierendem/synchronem) Code kombinieren mÃŧssen. + +### Andere Formen von asynchronem Code { #other-forms-of-asynchronous-code } Diese Art der Verwendung von `async` und `await` ist in der Sprache relativ neu. @@ -381,25 +383,25 @@ Davor war der Umgang mit asynchronem Code jedoch deutlich komplexer und schwieri In frÃŧheren Versionen von Python hätten Sie Threads oder Gevent verwenden kÃļnnen. Der Code ist jedoch viel komplexer zu verstehen, zu debuggen und nachzuvollziehen. -In frÃŧheren Versionen von NodeJS / Browser JavaScript hätten Sie „Callbacks“ verwendet. Was zur Callback-HÃļlle fÃŧhrt. +In frÃŧheren Versionen von NodeJS / Browser JavaScript hätten Sie „Callbacks“ verwendet. Was zur „Callback-HÃļlle“ fÃŧhrt. -## Coroutinen +## Coroutinen { #coroutines } **Coroutine** ist nur ein schicker Begriff fÃŧr dasjenige, was von einer `async def`-Funktion zurÃŧckgegeben wird. Python weiß, dass es so etwas wie eine Funktion ist, die es starten kann und die irgendwann endet, aber auch dass sie pausiert ⏸ werden kann, wann immer darin ein `await` steht. Aber all diese Funktionalität der Verwendung von asynchronem Code mit `async` und `await` wird oft als Verwendung von „Coroutinen“ zusammengefasst. Es ist vergleichbar mit dem Hauptmerkmal von Go, den „Goroutinen“. -## Fazit +## Fazit { #conclusion } Sehen wir uns den gleichen Satz von oben noch mal an: -> Moderne Versionen von Python unterstÃŧtzen **„asynchronen Code“** unter Verwendung sogenannter **„Coroutinen“** mithilfe der Syntax **`async`** und **`await`**. +> Moderne Versionen von Python unterstÃŧtzen **„asynchronen Code“** unter Verwendung sogenannter **„Coroutinen“** mithilfe der Syntax **`async` und `await`**. Das sollte jetzt mehr Sinn ergeben. ✨ All das ist es, was FastAPI (via Starlette) befeuert und es eine so beeindruckende Performanz haben lässt. -## Sehr technische Details +## Sehr technische Details { #very-technical-details } /// warning | Achtung @@ -411,23 +413,23 @@ Wenn Sie Ãŧber gute technische Kenntnisse verfÃŧgen (Coroutinen, Threads, Blocki /// -### Pfadoperation-Funktionen +### Pfadoperation-Funktionen { #path-operation-functions } Wenn Sie eine *Pfadoperation-Funktion* mit normalem `def` anstelle von `async def` deklarieren, wird sie in einem externen Threadpool ausgefÃŧhrt, der dann `await`et wird, anstatt direkt aufgerufen zu werden (da dies den Server blockieren wÃŧrde). Wenn Sie von einem anderen asynchronen Framework kommen, das nicht auf die oben beschriebene Weise funktioniert, und Sie es gewohnt sind, triviale, nur-berechnende *Pfadoperation-Funktionen* mit einfachem `def` zu definieren, um einen geringfÃŧgigen Geschwindigkeitsgewinn (etwa 100 Nanosekunden) zu erzielen, beachten Sie bitte, dass der Effekt in **FastAPI** genau gegenteilig wäre. In solchen Fällen ist es besser, `async def` zu verwenden, es sei denn, Ihre *Pfadoperation-Funktionen* verwenden Code, der blockierende I/O-Operationen durchfÃŧhrt. -Dennoch besteht in beiden Fällen eine gute Chance, dass **FastAPI** [immer noch schneller](index.md#performanz){.internal-link target=_blank} als Ihr bisheriges Framework (oder zumindest damit vergleichbar) ist. +Dennoch besteht in beiden Fällen eine gute Chance, dass **FastAPI** [immer noch schneller](index.md#performance){.internal-link target=_blank} als Ihr bisheriges Framework (oder zumindest damit vergleichbar) ist. -### Abhängigkeiten +### Abhängigkeiten { #dependencies } -Das Gleiche gilt fÃŧr [Abhängigkeiten](tutorial/dependencies/index.md){.internal-link target=_blank}. Wenn eine Abhängigkeit eine normale `def`-Funktion ist, anstelle einer `async def`-Funktion, dann wird sie im externen Threadpool ausgefÃŧhrt. +Das Gleiche gilt fÃŧr [Abhängigkeiten](tutorial/dependencies/index.md){.internal-link target=_blank}. Wenn eine Abhängigkeit eine normale `def`-Funktion anstelle einer `async def` ist, wird sie im externen Threadpool ausgefÃŧhrt. -### Unterabhängigkeiten +### Unterabhängigkeiten { #sub-dependencies } -Sie kÃļnnen mehrere Abhängigkeiten und [Unterabhängigkeiten](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} haben, die einander bedingen (als Parameter der Funktionsdefinitionen), einige davon kÃļnnten erstellt werden mit `async def` und einige mit normalem `def`. Es wÃŧrde immer noch funktionieren und diejenigen, die mit normalem `def` erstellt wurden, wÃŧrden in einem externen Thread (vom Threadpool stammend) aufgerufen werden, anstatt `await`et zu werden. +Sie kÃļnnen mehrere Abhängigkeiten und [Unterabhängigkeiten](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} haben, die einander bedingen (als Parameter der Funktionsdefinitionen), einige davon kÃļnnten erstellt werden mit `async def` und einige mit normalem `def`. Es wÃŧrde immer noch funktionieren, und diejenigen, die mit normalem `def` erstellt wurden, wÃŧrden in einem externen Thread (vom Threadpool stammend) aufgerufen werden, anstatt `await`et zu werden. -### Andere Hilfsfunktionen +### Andere Hilfsfunktionen { #other-utility-functions } Jede andere Hilfsfunktion, die Sie direkt aufrufen, kann mit normalem `def` oder `async def` erstellt werden, und FastAPI beeinflusst nicht die Art und Weise, wie Sie sie aufrufen. @@ -439,4 +441,4 @@ Wenn Ihre Hilfsfunktion eine normale Funktion mit `def` ist, wird sie direkt auf Nochmal, es handelt sich hier um sehr technische Details, die Ihnen helfen, falls Sie danach gesucht haben. -Andernfalls liegen Sie richtig, wenn Sie sich an die Richtlinien aus dem obigen Abschnitt halten: In Eile?. +Andernfalls liegen Sie richtig, wenn Sie sich an die Richtlinien aus dem obigen Abschnitt halten: In Eile?. diff --git a/docs/de/docs/benchmarks.md b/docs/de/docs/benchmarks.md index 6efd56e83..09126c5d9 100644 --- a/docs/de/docs/benchmarks.md +++ b/docs/de/docs/benchmarks.md @@ -1,16 +1,16 @@ -# Benchmarks +# Benchmarks { #benchmarks } -Unabhängige TechEmpower-Benchmarks zeigen, **FastAPI**-Anwendungen, die unter Uvicorn ausgefÃŧhrt werden, gehÃļren zu den schnellsten existierenden Python-Frameworks, nur Starlette und Uvicorn selbst (intern von FastAPI verwendet) sind schneller. +Unabhängige TechEmpower-Benchmarks zeigen **FastAPI**-Anwendungen, die unter Uvicorn ausgefÃŧhrt werden, als eines der schnellsten verfÃŧgbaren Python-Frameworks, nur unterhalb von Starlette und Uvicorn selbst (die intern von FastAPI verwendet werden). -Beim Ansehen von Benchmarks und Vergleichen sollten Sie jedoch Folgende Punkte beachten. +Aber bei der Betrachtung von Benchmarks und Vergleichen sollten Sie Folgendes beachten. -## Benchmarks und Geschwindigkeit +## Benchmarks und Geschwindigkeit { #benchmarks-and-speed } -Wenn Sie sich die Benchmarks ansehen, werden häufig mehrere Tools mit unterschiedlichen Eigenschaften als gleichwertig verglichen. +Wenn Sie die Benchmarks ansehen, ist es Ãŧblich, dass mehrere Tools unterschiedlichen Typs als gleichwertig verglichen werden. -Konkret geht es darum, Uvicorn, Starlette und FastAPI miteinander zu vergleichen (neben vielen anderen Tools). +Insbesondere dass Uvicorn, Starlette und FastAPI zusammen verglichen werden (neben vielen anderen Tools). -Je einfacher das Problem, welches durch das Tool gelÃļst wird, desto besser ist die Performanz. Und die meisten Benchmarks testen nicht die zusätzlichen Funktionen, welche das Tool bietet. +Je einfacher das Problem, das durch das Tool gelÃļst wird, desto besser wird die Performanz sein. Und die meisten Benchmarks testen nicht die zusätzlichen Funktionen, die das Tool bietet. Die Hierarchie ist wie folgt: @@ -19,16 +19,16 @@ Die Hierarchie ist wie folgt: * **FastAPI**: (verwendet Starlette) ein API-Mikroframework mit mehreren zusätzlichen Funktionen zum Erstellen von APIs, mit Datenvalidierung, usw. * **Uvicorn**: - * Bietet die beste Leistung, da außer dem Server selbst nicht viel zusätzlicher Code vorhanden ist. - * Sie wÃŧrden eine Anwendung nicht direkt in Uvicorn schreiben. Das wÃŧrde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten mÃŧsste. Und wenn Sie das täten, hätte Ihre endgÃŧltige Anwendung den gleichen Overhead wie die Verwendung eines Frameworks nebst Minimierung Ihres Anwendungscodes und der Fehler. + * Wird die beste Performanz haben, da außer dem Server selbst nicht viel zusätzlicher Code vorhanden ist. + * Sie wÃŧrden eine Anwendung nicht direkt in Uvicorn schreiben. Das wÃŧrde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten mÃŧsste. Und wenn Sie das täten, hätte Ihre endgÃŧltige Anwendung den gleichen Overhead wie bei der Verwendung eines Frameworks und der Minimierung Ihres Anwendungscodes und der Fehler. * Wenn Sie Uvicorn vergleichen, vergleichen Sie es mit Anwendungsservern wie Daphne, Hypercorn, uWSGI, usw. * **Starlette**: - * Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich nutzt Starlette intern Uvicorn. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn sein, weil mehr Code ausgefÃŧhrt wird. - * Aber es bietet Ihnen die Tools zum Erstellen einfacher Webanwendungen, mit Routing basierend auf Pfaden, usw. + * Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette intern Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgefÃŧhrt werden muss. + * Aber es bietet Ihnen die Werkzeuge, um einfache Webanwendungen zu erstellen, mit Routing basierend auf Pfaden, usw. * Wenn Sie Starlette vergleichen, vergleichen Sie es mit Webframeworks (oder Mikroframeworks) wie Sanic, Flask, Django, usw. * **FastAPI**: * So wie Starlette Uvicorn verwendet und nicht schneller als dieses sein kann, verwendet **FastAPI** Starlette, sodass es nicht schneller als dieses sein kann. - * FastAPI bietet zusätzlich zu Starlette weitere Funktionen. Funktionen, die Sie beim Erstellen von APIs fast immer benÃļtigen, wie Datenvalidierung und Serialisierung. Und wenn Sie es verwenden, erhalten Sie kostenlos automatische Dokumentation (die automatische Dokumentation verursacht nicht einmal zusätzlichen Aufwand fÃŧr laufende Anwendungen, sie wird beim Start generiert). - * Wenn Sie FastAPI nicht, und direkt Starlette (oder ein anderes Tool wie Sanic, Flask, Responder, usw.) verwenden wÃŧrden, mÃŧssten Sie die gesamte Datenvalidierung und Serialisierung selbst implementieren. Ihre finale Anwendung hätte also immer noch den gleichen Overhead, als ob sie mit FastAPI erstellt worden wäre. Und in vielen Fällen ist diese Datenvalidierung und Serialisierung der grÃļßte Teil des in Anwendungen geschriebenen Codes. - * Durch die Verwendung von FastAPI sparen Sie also Entwicklungszeit, Fehler und Codezeilen und wÃŧrden wahrscheinlich die gleiche Leistung (oder eine bessere) erzielen, die Sie hätten, wenn Sie es nicht verwenden wÃŧrden (da Sie alles in Ihrem Code implementieren mÃŧssten). - * Wenn Sie FastAPI vergleichen, vergleichen Sie es mit einem Webanwendung-Framework (oder einer Reihe von Tools), welche Datenvalidierung, Serialisierung und Dokumentation bereitstellen, wie Flask-apispec, NestJS, Molten, usw. – Frameworks mit integrierter automatischer Datenvalidierung, Serialisierung und Dokumentation. + * FastAPI bietet zusätzliche Funktionen auf Basis von Starlette. Funktionen, die Sie beim Erstellen von APIs fast immer benÃļtigen, wie Datenvalidierung und Serialisierung. Und wenn Sie es verwenden, erhalten Sie kostenlose automatische Dokumentation (die automatische Dokumentation verursacht nicht einmal zusätzlichen Overhead fÃŧr laufende Anwendungen, sie wird beim Starten generiert). + * Wenn Sie FastAPI nicht verwenden und stattdessen Starlette direkt (oder ein anderes Tool wie Sanic, Flask, Responder, usw.) verwenden wÃŧrden, mÃŧssten Sie die gesamte Datenvalidierung und Serialisierung selbst implementieren. Ihre finale Anwendung hätte also immer noch den gleichen Overhead, als ob sie mit FastAPI erstellt worden wäre. Und in vielen Fällen ist diese Datenvalidierung und Serialisierung der grÃļßte Teil des in Anwendungen geschriebenen Codes. + * Durch die Verwendung von FastAPI sparen Sie also Entwicklungszeit, Fehler und Codezeilen und wÃŧrden wahrscheinlich die gleiche Performanz (oder eine bessere) erzielen, die Sie hätten, wenn Sie es nicht verwenden wÃŧrden (da Sie alles in Ihrem Code implementieren mÃŧssten). + * Wenn Sie FastAPI vergleichen, vergleichen Sie es mit einem Webanwendungs-Framework (oder einer Reihe von Tools), das Datenvalidierung, Serialisierung und Dokumentation bereitstellt, wie Flask-apispec, NestJS, Molten, usw. – Frameworks mit integrierter automatischer Datenvalidierung, Serialisierung und Dokumentation. diff --git a/docs/de/docs/deployment/cloud.md b/docs/de/docs/deployment/cloud.md index 2d70fe4e5..ca1ba3b3b 100644 --- a/docs/de/docs/deployment/cloud.md +++ b/docs/de/docs/deployment/cloud.md @@ -1,17 +1,16 @@ -# FastAPI-Deployment bei Cloud-Anbietern +# FastAPI bei Cloudanbietern bereitstellen { #deploy-fastapi-on-cloud-providers } -Sie kÃļnnen praktisch **jeden Cloud-Anbieter** fÃŧr das Deployment Ihrer FastAPI-Anwendung verwenden. +Sie kÃļnnen praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung bereitzustellen. -In den meisten Fällen verfÃŧgen die Haupt-Cloud-Anbieter Ãŧber Anleitungen zum Deployment von FastAPI. +In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Bereitstellen von FastAPI an. -## Cloud-Anbieter – Sponsoren +## Cloudanbieter – Sponsoren { #cloud-providers-sponsors } -Einige Cloud-Anbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#den-autor-sponsern){.internal-link target=_blank} ✨, dies gewährleistet die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem**. +Einige Cloudanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, dies stellt die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem** sicher. -Und es zeigt deren wahres Engagement fÃŧr FastAPI und seine **Community** (Sie), da diese Ihnen nicht nur einen **guten Service** bieten mÃļchten, sondern auch sicherstellen mÃļchten, dass Sie Ãŧber ein **gutes und gesundes Framework** verfÃŧgen, FastAPI. 🙇 +Und es zeigt ihr wahres Engagement fÃŧr FastAPI und seine **Community** (Sie), da sie Ihnen nicht nur einen **guten Service** bieten mÃļchten, sondern auch sicherstellen mÃļchten, dass Sie ein **gutes und gesundes Framework**, FastAPI, haben. 🙇 Vielleicht mÃļchten Sie deren Dienste ausprobieren und deren Anleitungen folgen: -* Platform.sh -* Porter -* Coherence +* Render +* Railway diff --git a/docs/de/docs/deployment/concepts.md b/docs/de/docs/deployment/concepts.md index 907598e54..ef0f458a7 100644 --- a/docs/de/docs/deployment/concepts.md +++ b/docs/de/docs/deployment/concepts.md @@ -1,4 +1,4 @@ -# Deployment-Konzepte +# Deployment-Konzepte { #deployments-concepts } Bei dem Deployment – der Bereitstellung – einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe der Sie die **am besten geeignete** Methode zur **Bereitstellung Ihrer Anwendung** finden kÃļnnen. @@ -13,7 +13,7 @@ Einige wichtige Konzepte sind: Wir werden sehen, wie diese sich auf das **Deployment** auswirken. -Letztendlich besteht das ultimative Ziel darin, **Ihre API-Clients** auf **sichere** Weise zu bedienen, um **Unterbrechungen** zu vermeiden und die **Rechenressourcen** (z. B. entfernte Server/virtuelle Maschinen) so effizient wie mÃļglich zu nutzen. 🚀 +Letztendlich besteht das ultimative Ziel darin, **Ihre API-Clients** auf **sichere** Weise zu versorgen, um **Unterbrechungen** zu vermeiden und die **Rechenressourcen** (z. B. entfernte Server/virtuelle Maschinen) so effizient wie mÃļglich zu nutzen. 🚀 Ich erzähle Ihnen hier etwas mehr Ãŧber diese **Konzepte**, was Ihnen hoffentlich die **Intuition** gibt, die Sie benÃļtigen, um zu entscheiden, wie Sie Ihre API in sehr unterschiedlichen Umgebungen bereitstellen, mÃļglicherweise sogar in **zukÃŧnftigen**, die jetzt noch nicht existieren. @@ -23,7 +23,7 @@ In den nächsten Kapiteln werde ich Ihnen mehr **konkrete Rezepte** fÃŧr die Ber Aber schauen wir uns zunächst einmal diese grundlegenden **konzeptionellen Ideen** an. Diese Konzepte gelten auch fÃŧr jede andere Art von Web-API. 💡 -## Sicherheit – HTTPS +## Sicherheit – HTTPS { #security-https } Im [vorherigen Kapitel Ãŧber HTTPS](https.md){.internal-link target=_blank} haben wir erfahren, wie HTTPS VerschlÃŧsselung fÃŧr Ihre API bereitstellt. @@ -31,7 +31,7 @@ Wir haben auch gesehen, dass HTTPS normalerweise von einer Komponente **außerha Und es muss etwas geben, das fÃŧr die **Erneuerung der HTTPS-Zertifikate** zuständig ist, es kÃļnnte sich um dieselbe Komponente handeln oder um etwas anderes. -### Beispieltools fÃŧr HTTPS +### Beispieltools fÃŧr HTTPS { #example-tools-for-https } Einige der Tools, die Sie als TLS-Terminierungsproxy verwenden kÃļnnen, sind: @@ -55,11 +55,11 @@ In den nächsten Kapiteln zeige ich Ihnen einige konkrete Beispiele. Die nächsten zu berÃŧcksichtigenden Konzepte drehen sich dann um das Programm, das Ihre eigentliche API ausfÃŧhrt (z. B. Uvicorn). -## Programm und Prozess +## Programm und Prozess { #program-and-process } Wir werden viel Ãŧber den laufenden „**Prozess**“ sprechen, daher ist es nÃŧtzlich, Klarheit darÃŧber zu haben, was das bedeutet und was der Unterschied zum Wort „**Programm**“ ist. -### Was ist ein Programm? +### Was ist ein Programm { #what-is-a-program } Das Wort **Programm** wird häufig zur Beschreibung vieler Dinge verwendet: @@ -67,7 +67,7 @@ Das Wort **Programm** wird häufig zur Beschreibung vieler Dinge verwendet: * Die **Datei**, die vom Betriebssystem **ausgefÃŧhrt** werden kann, zum Beispiel: `python`, `python.exe` oder `uvicorn`. * Ein bestimmtes Programm, während es auf dem Betriebssystem **läuft**, die CPU nutzt und Dinge im Arbeitsspeicher ablegt. Dies wird auch als **Prozess** bezeichnet. -### Was ist ein Prozess? +### Was ist ein Prozess { #what-is-a-process } Das Wort **Prozess** wird normalerweise spezifischer verwendet und bezieht sich nur auf das, was im Betriebssystem ausgefÃŧhrt wird (wie im letzten Punkt oben): @@ -88,13 +88,13 @@ Und Sie werden beispielsweise wahrscheinlich feststellen, dass mehrere Prozesse Nachdem wir nun den Unterschied zwischen den Begriffen **Prozess** und **Programm** kennen, sprechen wir weiter Ãŧber das Deployment. -## Beim Hochfahren ausfÃŧhren +## Beim Hochfahren ausfÃŧhren { #running-on-startup } Wenn Sie eine Web-API erstellen, mÃļchten Sie in den meisten Fällen, dass diese **immer läuft**, ununterbrochen, damit Ihre Clients immer darauf zugreifen kÃļnnen. Es sei denn natÃŧrlich, Sie haben einen bestimmten Grund, warum Sie mÃļchten, dass diese nur in bestimmten Situationen ausgefÃŧhrt wird. Meistens mÃļchten Sie jedoch, dass sie ständig ausgefÃŧhrt wird und **verfÃŧgbar** ist. -### Auf einem entfernten Server +### Auf einem entfernten Server { #in-a-remote-server } -Wenn Sie einen entfernten Server (einen Cloud-Server, eine virtuelle Maschine, usw.) einrichten, kÃļnnen Sie am einfachsten Uvicorn (oder ähnliches) manuell ausfÃŧhren, genau wie bei der lokalen Entwicklung. +Wenn Sie einen entfernten Server (einen Cloud-Server, eine virtuelle Maschine, usw.) einrichten, kÃļnnen Sie am einfachsten `fastapi run` (welches Uvicorn verwendet) oder etwas Ähnliches manuell ausfÃŧhren, genau wie bei der lokalen Entwicklung. Und es wird funktionieren und **während der Entwicklung** nÃŧtzlich sein. @@ -102,15 +102,15 @@ Wenn Ihre Verbindung zum Server jedoch unterbrochen wird, wird der **laufende Pr Und wenn der Server neu gestartet wird (z. B. nach Updates oder Migrationen vom Cloud-Anbieter), werden Sie das wahrscheinlich **nicht bemerken**. Und deshalb wissen Sie nicht einmal, dass Sie den Prozess manuell neu starten mÃŧssen. Ihre API bleibt also einfach tot. 😱 -### Beim Hochfahren automatisch ausfÃŧhren +### Beim Hochfahren automatisch ausfÃŧhren { #run-automatically-on-startup } Im Allgemeinen mÃļchten Sie wahrscheinlich, dass das Serverprogramm (z. B. Uvicorn) beim Hochfahren des Servers automatisch gestartet wird und kein **menschliches Eingreifen** erforderlich ist, sodass immer ein Prozess mit Ihrer API ausgefÃŧhrt wird (z. B. Uvicorn, welches Ihre FastAPI-Anwendung ausfÃŧhrt). -### Separates Programm +### Separates Programm { #separate-program } Um dies zu erreichen, haben Sie normalerweise ein **separates Programm**, welches sicherstellt, dass Ihre Anwendung beim Hochfahren ausgefÃŧhrt wird. Und in vielen Fällen wÃŧrde es auch sicherstellen, dass auch andere Komponenten oder Anwendungen ausgefÃŧhrt werden, beispielsweise eine Datenbank. -### Beispieltools zur AusfÃŧhrung beim Hochfahren +### Beispieltools zur AusfÃŧhrung beim Hochfahren { #example-tools-to-run-at-startup } Einige Beispiele fÃŧr Tools, die diese Aufgabe Ãŧbernehmen kÃļnnen, sind: @@ -125,29 +125,29 @@ Einige Beispiele fÃŧr Tools, die diese Aufgabe Ãŧbernehmen kÃļnnen, sind: In den nächsten Kapiteln werde ich Ihnen konkretere Beispiele geben. -## Neustart +## Neustart { #restarts } Ähnlich wie Sie sicherstellen mÃļchten, dass Ihre Anwendung beim Hochfahren ausgefÃŧhrt wird, mÃļchten Sie wahrscheinlich auch sicherstellen, dass diese nach Fehlern **neu gestartet** wird. -### Wir machen Fehler +### Wir machen Fehler { #we-make-mistakes } Wir, als Menschen, machen ständig **Fehler**. Software hat fast *immer* **Bugs**, die an verschiedenen Stellen versteckt sind. 🐛 Und wir als Entwickler verbessern den Code ständig, wenn wir diese Bugs finden und neue Funktionen implementieren (und mÃļglicherweise auch neue Bugs hinzufÃŧgen 😅). -### Kleine Fehler automatisch handhaben +### Kleine Fehler automatisch handhaben { #small-errors-automatically-handled } -Wenn beim Erstellen von Web-APIs mit FastAPI ein Fehler in unserem Code auftritt, wird FastAPI ihn normalerweise dem einzelnen Request zurÃŧckgeben, der den Fehler ausgelÃļst hat. 🛡 +Wenn beim Erstellen von Web-APIs mit FastAPI ein Fehler in unserem Code auftritt, wird FastAPI ihn normalerweise dem einzelnen Request zurÃŧckgeben, der den Fehler ausgelÃļst hat. 🛡 Der Client erhält fÃŧr diesen Request einen **500 Internal Server Error**, aber die Anwendung arbeitet bei den nächsten Requests weiter, anstatt einfach komplett abzustÃŧrzen. -### GrÃļßere Fehler – AbstÃŧrze +### GrÃļßere Fehler – AbstÃŧrze { #bigger-errors-crashes } Dennoch kann es vorkommen, dass wir Code schreiben, der **die gesamte Anwendung zum Absturz bringt** und so zum Absturz von Uvicorn und Python fÃŧhrt. đŸ’Ĩ Und dennoch mÃļchten Sie wahrscheinlich nicht, dass die Anwendung tot bleibt, weil an einer Stelle ein Fehler aufgetreten ist. Sie mÃļchten wahrscheinlich, dass sie zumindest fÃŧr die *Pfadoperationen*, die nicht fehlerhaft sind, **weiterläuft**. -### Neustart nach Absturz +### Neustart nach Absturz { #restart-after-crash } Aber in den Fällen mit wirklich schwerwiegenden Fehlern, die den laufenden **Prozess** zum Absturz bringen, benÃļtigen Sie eine externe Komponente, die den Prozess **neu startet**, zumindest ein paar Mal ... @@ -161,7 +161,7 @@ Konzentrieren wir uns also auf die Hauptfälle, in denen die Anwendung in bestim Sie mÃļchten wahrscheinlich, dass eine **externe Komponente** fÃŧr den Neustart Ihrer Anwendung verantwortlich ist, da zu diesem Zeitpunkt dieselbe Anwendung mit Uvicorn und Python bereits abgestÃŧrzt ist und es daher nichts im selben Code derselben Anwendung gibt, was etwas dagegen tun kann. -### Beispieltools zum automatischen Neustart +### Beispieltools zum automatischen Neustart { #example-tools-to-restart-automatically } In den meisten Fällen wird dasselbe Tool, das zum **AusfÃŧhren des Programms beim Hochfahren** verwendet wird, auch fÃŧr automatische **Neustarts** verwendet. @@ -176,19 +176,19 @@ Dies kÃļnnte zum Beispiel erledigt werden durch: * Intern von einem Cloud-Anbieter im Rahmen seiner Dienste * Andere ... -## Replikation – Prozesse und Arbeitsspeicher +## Replikation – Prozesse und Arbeitsspeicher { #replication-processes-and-memory } -Wenn Sie eine FastAPI-Anwendung verwenden und ein Serverprogramm wie Uvicorn verwenden, kann **ein einzelner Prozess** mehrere Clients gleichzeitig bedienen. +Wenn Sie eine FastAPI-Anwendung verwenden und ein Serverprogramm wie den `fastapi`-Befehl, der Uvicorn ausfÃŧhrt, kann **ein einzelner Prozess** an mehrere Clients gleichzeitig ausliefern. -In vielen Fällen mÃļchten Sie jedoch mehrere Prozesse gleichzeitig ausfÃŧhren. +In vielen Fällen mÃļchten Sie jedoch mehrere Workerprozesse gleichzeitig ausfÃŧhren. -### Mehrere Prozesse – Worker +### Mehrere Prozesse – Worker { #multiple-processes-workers } Wenn Sie mehr Clients haben, als ein einzelner Prozess verarbeiten kann (z. B. wenn die virtuelle Maschine nicht sehr groß ist) und die CPU des Servers **mehrere Kerne** hat, dann kÃļnnten **mehrere Prozesse** gleichzeitig mit derselben Anwendung laufen und alle Requests unter sich verteilen. -Wenn Sie mit **mehreren Prozessen** dasselbe API-Programm ausfÃŧhren, werden diese Ãŧblicherweise als **Worker** bezeichnet. +Wenn Sie mit **mehreren Prozessen** dasselbe API-Programm ausfÃŧhren, werden diese Ãŧblicherweise als **Worker** bezeichnet. -### Workerprozesse und Ports +### Workerprozesse und Ports { #worker-processes-and-ports } Erinnern Sie sich aus der Dokumentation [Über HTTPS](https.md){.internal-link target=_blank}, dass nur ein Prozess auf einer Kombination aus Port und IP-Adresse auf einem Server lauschen kann? @@ -196,35 +196,35 @@ Das ist immer noch wahr. Um also **mehrere Prozesse** gleichzeitig zu haben, muss es einen **einzelnen Prozess geben, der einen Port Ãŧberwacht**, welcher dann die Kommunikation auf irgendeine Weise an jeden Workerprozess Ãŧberträgt. -### Arbeitsspeicher pro Prozess +### Arbeitsspeicher pro Prozess { #memory-per-process } Wenn das Programm nun Dinge in den Arbeitsspeicher lädt, zum Beispiel ein Modell fÃŧr maschinelles Lernen in einer Variablen oder den Inhalt einer großen Datei in einer Variablen, verbraucht das alles **einen Teil des Arbeitsspeichers (RAM – Random Access Memory)** des Servers. Und mehrere Prozesse teilen sich normalerweise keinen Speicher. Das bedeutet, dass jeder laufende Prozess seine eigenen Dinge, eigenen Variablen und eigenen Speicher hat. Und wenn Sie in Ihrem Code viel Speicher verbrauchen, verbraucht **jeder Prozess** die gleiche Menge Speicher. -### Serverspeicher +### Serverspeicher { #server-memory } Wenn Ihr Code beispielsweise ein Machine-Learning-Modell mit **1 GB GrÃļße** lädt und Sie einen Prozess mit Ihrer API ausfÃŧhren, verbraucht dieser mindestens 1 GB RAM. Und wenn Sie **4 Prozesse** (4 Worker) starten, verbraucht jeder 1 GB RAM. Insgesamt verbraucht Ihre API also **4 GB RAM**. Und wenn Ihr entfernter Server oder Ihre virtuelle Maschine nur Ãŧber 3 GB RAM verfÃŧgt, fÃŧhrt der Versuch, mehr als 4 GB RAM zu laden, zu Problemen. 🚨 -### Mehrere Prozesse – Ein Beispiel +### Mehrere Prozesse – Ein Beispiel { #multiple-processes-an-example } Im folgenden Beispiel gibt es einen **Manager-Prozess**, welcher zwei **Workerprozesse** startet und steuert. Dieser Manager-Prozess wäre wahrscheinlich derjenige, welcher der IP am **Port** lauscht. Und er wÃŧrde die gesamte Kommunikation an die Workerprozesse weiterleiten. -Diese Workerprozesse wÃŧrden Ihre Anwendung ausfÃŧhren, sie wÃŧrden die Hauptberechnungen durchfÃŧhren, um einen **Request** entgegenzunehmen und eine **Response** zurÃŧckzugeben, und sie wÃŧrden alles, was Sie in Variablen einfÃŧgen, in den RAM laden. +Diese Workerprozesse wÃŧrden Ihre Anwendung ausfÃŧhren, sie wÃŧrden die Hauptberechnungen durchfÃŧhren, um einen **Request** entgegenzunehmen und eine **Response** zurÃŧckzugeben, und sie wÃŧrden alles, was Sie in Variablen einfÃŧgen, in den RAM laden. -Und natÃŧrlich wÃŧrden auf derselben Maschine neben Ihrer Anwendung wahrscheinlich auch **andere Prozesse** laufen. +Und natÃŧrlich wÃŧrden auf derselben Maschine neben Ihrer Anwendung wahrscheinlich **andere Prozesse** laufen. Ein interessantes Detail ist dabei, dass der Prozentsatz der von jedem Prozess verwendeten **CPU** im Laufe der Zeit stark **variieren** kann, der **Arbeitsspeicher (RAM)** jedoch normalerweise mehr oder weniger **stabil** bleibt. Wenn Sie eine API haben, die jedes Mal eine vergleichbare Menge an Berechnungen durchfÃŧhrt, und Sie viele Clients haben, dann wird die **CPU-Auslastung** wahrscheinlich *ebenfalls stabil sein* (anstatt ständig schnell zu steigen und zu fallen). -### Beispiele fÃŧr Replikation-Tools und -Strategien +### Beispiele fÃŧr Replikation-Tools und -Strategien { #examples-of-replication-tools-and-strategies } Es gibt mehrere Ansätze, um dies zu erreichen, und ich werde Ihnen in den nächsten Kapiteln mehr Ãŧber bestimmte Strategien erzählen, beispielsweise wenn es um Docker und Container geht. @@ -232,9 +232,7 @@ Die wichtigste zu berÃŧcksichtigende Einschränkung besteht darin, dass es eine Hier sind einige mÃļgliche Kombinationen und Strategien: -* **Gunicorn**, welches **Uvicorn-Worker** managt - * Gunicorn wäre der **Prozessmanager**, der die **IP** und den **Port** Ãŧberwacht, die Replikation wÃŧrde durch **mehrere Uvicorn-Workerprozesse** erfolgen -* **Uvicorn**, welches **Uvicorn-Worker** managt +* **Uvicorn** mit `--workers` * Ein Uvicorn-**Prozessmanager** wÃŧrde der **IP** am **Port** lauschen, und er wÃŧrde **mehrere Uvicorn-Workerprozesse** starten. * **Kubernetes** und andere verteilte **Containersysteme** * Etwas in der **Kubernetes**-Ebene wÃŧrde die **IP** und den **Port** abhÃļren. Die Replikation hätte **mehrere Container**, in jedem wird jeweils **ein Uvicorn-Prozess** ausgefÃŧhrt. @@ -249,7 +247,7 @@ Ich werde Ihnen in einem zukÃŧnftigen Kapitel mehr Ãŧber Container-Images, Docke /// -## Schritte vor dem Start +## Schritte vor dem Start { #previous-steps-before-starting } Es gibt viele Fälle, in denen Sie, **bevor Sie Ihre Anwendung starten**, einige Schritte ausfÃŧhren mÃļchten. @@ -271,7 +269,7 @@ In diesem Fall mÃŧssen Sie sich darÃŧber keine Sorgen machen. 🤷 /// -### Beispiele fÃŧr Strategien fÃŧr Vorab-Schritte +### Beispiele fÃŧr Strategien fÃŧr Vorab-Schritte { #examples-of-previous-steps-strategies } Es hängt **stark** davon ab, wie Sie **Ihr System bereitstellen**, und hängt wahrscheinlich mit der Art und Weise zusammen, wie Sie Programme starten, Neustarts durchfÃŧhren, usw. @@ -287,7 +285,7 @@ Konkretere Beispiele hierfÃŧr mit Containern gebe ich Ihnen in einem späteren K /// -## Ressourcennutzung +## Ressourcennutzung { #resource-utilization } Ihr(e) Server ist (sind) eine **Ressource**, welche Sie mit Ihren Programmen, der Rechenzeit auf den CPUs und dem verfÃŧgbaren RAM-Speicher verbrauchen oder **nutzen** kÃļnnen. @@ -303,11 +301,11 @@ In diesem Fall wäre es besser, **einen zusätzlichen Server** zu besorgen und e Es besteht auch die MÃļglichkeit, dass es aus irgendeinem Grund zu **Spitzen** in der Nutzung Ihrer API kommt. Vielleicht ist diese viral gegangen, oder vielleicht haben andere Dienste oder Bots damit begonnen, sie zu nutzen. Und vielleicht mÃļchten Sie in solchen Fällen Ãŧber zusätzliche Ressourcen verfÃŧgen, um auf der sicheren Seite zu sein. -Sie kÃļnnen eine **beliebige Zahl** festlegen, um beispielsweise eine Ressourcenauslastung zwischen **50 % und 90 %** anzustreben. Der Punkt ist, dass dies wahrscheinlich die wichtigen Dinge sind, die Sie messen und verwenden sollten, um Ihre Deployments zu optimieren. +Sie kÃļnnen eine **beliebige Zahl** festlegen, um beispielsweise eine Ressourcenauslastung zwischen **50 % und 90 %** anzustreben. Der Punkt ist, dass dies wahrscheinlich die wichtigen Dinge sind, die Sie messen und verwenden sollten, um Ihre Deployments zu optimieren. Sie kÃļnnen einfache Tools wie `htop` verwenden, um die in Ihrem Server verwendete CPU und den RAM oder die von jedem Prozess verwendete Menge anzuzeigen. Oder Sie kÃļnnen komplexere Überwachungstools verwenden, die mÃļglicherweise auf mehrere Server usw. verteilt sind. -## Zusammenfassung +## Zusammenfassung { #recap } Sie haben hier einige der wichtigsten Konzepte gelesen, die Sie wahrscheinlich berÃŧcksichtigen mÃŧssen, wenn Sie entscheiden, wie Sie Ihre Anwendung bereitstellen: diff --git a/docs/de/docs/deployment/docker.md b/docs/de/docs/deployment/docker.md index a2734e068..52ac99913 100644 --- a/docs/de/docs/deployment/docker.md +++ b/docs/de/docs/deployment/docker.md @@ -1,4 +1,4 @@ -# FastAPI in Containern – Docker +# FastAPI in Containern – Docker { #fastapi-in-containers-docker } Beim Deployment von FastAPI-Anwendungen besteht ein gängiger Ansatz darin, ein **Linux-Containerimage** zu erstellen. Normalerweise erfolgt dies mit **Docker**. Sie kÃļnnen dieses Containerimage dann auf eine von mehreren mÃļglichen Arten bereitstellen. @@ -6,11 +6,11 @@ Die Verwendung von Linux-Containern bietet mehrere Vorteile, darunter **Sicherhe /// tip | Tipp -Sie haben es eilig und kennen sich bereits aus? Springen Sie zum [`Dockerfile` unten 👇](#ein-docker-image-fur-fastapi-erstellen). +Sie haben es eilig und kennen sich bereits aus? Springen Sie zum [`Dockerfile` unten 👇](#build-a-docker-image-for-fastapi). /// -
+
Dockerfile-Vorschau 👀 ```Dockerfile @@ -24,15 +24,15 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +CMD ["fastapi", "run", "app/main.py", "--port", "80"] # Wenn Sie hinter einem Proxy wie Nginx oder Traefik sind, fÃŧgen Sie --proxy-headers hinzu -# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"] +# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"] ```
-## Was ist ein Container? +## Was ist ein Container { #what-is-a-container } Container (hauptsächlich Linux-Container) sind eine sehr **leichtgewichtige** MÃļglichkeit, Anwendungen einschließlich aller ihrer Abhängigkeiten und erforderlichen Dateien zu verpacken und sie gleichzeitig von anderen Containern (anderen Anwendungen oder Komponenten) im selben System isoliert zu halten. @@ -42,7 +42,7 @@ Auf diese Weise verbrauchen Container **wenig Ressourcen**, eine Menge vergleich Container verfÃŧgen außerdem Ãŧber ihre eigenen **isoliert** laufenden Prozesse (Ãŧblicherweise nur einen Prozess), Ãŧber ihr eigenes Dateisystem und ihr eigenes Netzwerk, was die Bereitstellung, Sicherheit, Entwicklung usw. vereinfacht. -## Was ist ein Containerimage? +## Was ist ein Containerimage { #what-is-a-container-image } Ein **Container** wird von einem **Containerimage** ausgefÃŧhrt. @@ -50,17 +50,17 @@ Ein Containerimage ist eine **statische** Version aller Dateien, Umgebungsvariab Im Gegensatz zu einem „**Containerimage**“, bei dem es sich um den gespeicherten statischen Inhalt handelt, bezieht sich ein „**Container**“ normalerweise auf die laufende Instanz, das Ding, das **ausgefÃŧhrt** wird. -Wenn der **Container** gestartet und ausgefÃŧhrt wird (gestartet von einem **Containerimage**), kann er Dateien, Umgebungsvariablen usw. erstellen oder ändern. Diese Änderungen sind nur in diesem Container vorhanden, nicht im zugrunde liegenden bestehen Containerimage (werden nicht auf der Festplatte gespeichert). +Wenn der **Container** gestartet und ausgefÃŧhrt wird (gestartet von einem **Containerimage**), kann er Dateien, Umgebungsvariablen usw. erstellen oder ändern. Diese Änderungen sind nur in diesem Container vorhanden, nicht im zugrunde liegenden Containerimage (werden nicht auf der Festplatte gespeichert). Ein Containerimage ist vergleichbar mit der **Programmdatei** und ihrem Inhalt, z. B. `python` und eine Datei `main.py`. Und der **Container** selbst (im Gegensatz zum **Containerimage**) ist die tatsächlich laufende Instanz des Images, vergleichbar mit einem **Prozess**. Tatsächlich läuft ein Container nur, wenn er einen **laufenden Prozess** hat (und normalerweise ist es nur ein einzelner Prozess). Der Container stoppt, wenn kein Prozess darin ausgefÃŧhrt wird. -## Containerimages +## Containerimages { #container-images } Docker ist eines der wichtigsten Tools zum Erstellen und Verwalten von **Containerimages** und **Containern**. -Und es gibt einen Ãļffentlichen Docker Hub mit vorgefertigten **offiziellen Containerimages** fÃŧr viele Tools, Umgebungen, Datenbanken und Anwendungen. +Und es gibt einen Ãļffentlichen Docker Hub mit vorgefertigten **offiziellen Containerimages** fÃŧr viele Tools, Umgebungen, Datenbanken und Anwendungen. Beispielsweise gibt es ein offizielles Python-Image. @@ -79,7 +79,7 @@ Sie wÃŧrden also **mehrere Container** mit unterschiedlichen Dingen ausfÃŧhren, In alle Containerverwaltungssysteme (wie Docker oder Kubernetes) sind diese Netzwerkfunktionen integriert. -## Container und Prozesse +## Container und Prozesse { #containers-and-processes } Ein **Containerimage** enthält normalerweise in seinen Metadaten das Standardprogramm oder den Standardbefehl, der ausgefÃŧhrt werden soll, wenn der **Container** gestartet wird, sowie die Parameter, die an dieses Programm Ãŧbergeben werden sollen. Sehr ähnlich zu dem, was wäre, wenn es Ãŧber die Befehlszeile gestartet werden wÃŧrde. @@ -91,7 +91,7 @@ Ein Container hat normalerweise einen **einzelnen Prozess**, aber es ist auch m Es ist jedoch nicht mÃļglich, einen laufenden Container, ohne **mindestens einen laufenden Prozess** zu haben. Wenn der Hauptprozess stoppt, stoppt der Container. -## Ein Docker-Image fÃŧr FastAPI erstellen +## Ein Docker-Image fÃŧr FastAPI erstellen { #build-a-docker-image-for-fastapi } Okay, wollen wir jetzt etwas bauen! 🚀 @@ -103,7 +103,7 @@ Das ist, was Sie in **den meisten Fällen** tun mÃļchten, zum Beispiel: * Beim Betrieb auf einem **Raspberry Pi** * Bei Verwendung eines Cloud-Dienstes, der ein Containerimage fÃŧr Sie ausfÃŧhrt, usw. -### Paketanforderungen +### Paketanforderungen { #package-requirements } Normalerweise befinden sich die **Paketanforderungen** fÃŧr Ihre Anwendung in einer Datei. @@ -116,9 +116,8 @@ Sie wÃŧrden natÃŧrlich die gleichen Ideen verwenden, die Sie in [Über FastAPI-V Ihre `requirements.txt` kÃļnnte beispielsweise so aussehen: ``` -fastapi>=0.68.0,<0.69.0 -pydantic>=1.8.0,<2.0.0 -uvicorn>=0.15.0,<0.16.0 +fastapi[standard]>=0.113.0,<0.114.0 +pydantic>=2.7.0,<3.0.0 ``` Und normalerweise wÃŧrden Sie diese Paketabhängigkeiten mit `pip` installieren, zum Beispiel: @@ -128,20 +127,18 @@ Und normalerweise wÃŧrden Sie diese Paketabhängigkeiten mit `pip` installieren, ```console $ pip install -r requirements.txt ---> 100% -Successfully installed fastapi pydantic uvicorn +Successfully installed fastapi pydantic ```
-/// info +/// info | Info Es gibt andere Formate und Tools zum Definieren und Installieren von Paketabhängigkeiten. -Ich zeige Ihnen später in einem Abschnitt unten ein Beispiel unter Verwendung von Poetry. 👇 - /// -### Den **FastAPI**-Code erstellen +### Den **FastAPI**-Code erstellen { #create-the-fastapi-code } * Erstellen Sie ein `app`-Verzeichnis und betreten Sie es. * Erstellen Sie eine leere Datei `__init__.py`. @@ -165,35 +162,35 @@ def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` -### Dockerfile +### Dockerfile { #dockerfile } Erstellen Sie nun im selben Projektverzeichnis eine Datei `Dockerfile` mit: ```{ .dockerfile .annotate } -# (1) +# (1)! FROM python:3.9 -# (2) +# (2)! WORKDIR /code -# (3) +# (3)! COPY ./requirements.txt /code/requirements.txt -# (4) +# (4)! RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt -# (5) +# (5)! COPY ./app /code/app -# (6) -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +# (6)! +CMD ["fastapi", "run", "app/main.py", "--port", "80"] ``` 1. Beginne mit dem offiziellen Python-Basisimage. 2. Setze das aktuelle Arbeitsverzeichnis auf `/code`. - Hier plazieren wir die Datei `requirements.txt` und das Verzeichnis `app`. + Hier platzieren wir die Datei `requirements.txt` und das Verzeichnis `app`. 3. Kopiere die Datei mit den Paketanforderungen in das Verzeichnis `/code`. @@ -223,20 +220,50 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] Daher ist es wichtig, dies **nahe dem Ende** des `Dockerfile`s zu platzieren, um die Erstellungszeiten des Containerimages zu optimieren. -6. Lege den **Befehl** fest, um den `uvicorn`-Server zu starten. +6. Lege den **Befehl** fest, um `fastapi run` zu nutzen, welches Uvicorn darunter verwendet. `CMD` nimmt eine Liste von Zeichenfolgen entgegen. Jede dieser Zeichenfolgen entspricht dem, was Sie durch Leerzeichen getrennt in die Befehlszeile eingeben wÃŧrden. Dieser Befehl wird aus dem **aktuellen Arbeitsverzeichnis** ausgefÃŧhrt, dem gleichen `/code`-Verzeichnis, das Sie oben mit `WORKDIR /code` festgelegt haben. - Da das Programm unter `/code` gestartet wird und sich darin das Verzeichnis `./app` mit Ihrem Code befindet, kann **Uvicorn** `app` sehen und aus `app.main` **importieren**. - /// tip | Tipp Lernen Sie, was jede Zeile bewirkt, indem Sie auf die Zahlenblasen im Code klicken. 👆 /// +/// warning | Achtung + +Stellen Sie sicher, dass Sie **immer** die **exec form** der Anweisung `CMD` verwenden, wie unten erläutert. + +/// + +#### `CMD` – Exec Form verwenden { #use-cmd-exec-form } + +Die `CMD` Docker-Anweisung kann in zwei Formen geschrieben werden: + +✅ **Exec** form: + +```Dockerfile +# ✅ Tun Sie das +CMD ["fastapi", "run", "app/main.py", "--port", "80"] +``` + +â›”ī¸ **Shell** form: + +```Dockerfile +# â›”ī¸ Tun Sie das nicht +CMD fastapi run app/main.py --port 80 +``` + +Achten Sie darauf, stets die **exec** form zu verwenden, um sicherzustellen, dass FastAPI ordnungsgemäß heruntergefahren wird und [Lifespan-Events](../advanced/events.md){.internal-link target=_blank} ausgelÃļst werden. + +Sie kÃļnnen mehr darÃŧber in der Docker-Dokumentation fÃŧr Shell und Exec Form lesen. + +Dies kann insbesondere bei der Verwendung von `docker compose` deutlich spÃŧrbar sein. Sehen Sie sich diesen Abschnitt in der Docker Compose-FAQ fÃŧr technische Details an: Warum benÃļtigen meine Dienste 10 Sekunden, um neu erstellt oder gestoppt zu werden?. + +#### Verzeichnisstruktur { #directory-structure } + Sie sollten jetzt eine Verzeichnisstruktur wie diese haben: ``` @@ -248,15 +275,15 @@ Sie sollten jetzt eine Verzeichnisstruktur wie diese haben: └── requirements.txt ``` -#### Hinter einem TLS-Terminierungsproxy +#### Hinter einem TLS-Terminierungsproxy { #behind-a-tls-termination-proxy } -Wenn Sie Ihren Container hinter einem TLS-Terminierungsproxy (Load Balancer) wie Nginx oder Traefik ausfÃŧhren, fÃŧgen Sie die Option `--proxy-headers` hinzu. Das sagt Uvicorn, den von diesem Proxy gesendeten Headern zu vertrauen und dass die Anwendung hinter HTTPS ausgefÃŧhrt wird, usw. +Wenn Sie Ihren Container hinter einem TLS-Terminierungsproxy (Load Balancer) wie Nginx oder Traefik ausfÃŧhren, fÃŧgen Sie die Option `--proxy-headers` hinzu. Das sagt Uvicorn (durch das FastAPI CLI), den von diesem Proxy gesendeten Headern zu vertrauen und dass die Anwendung hinter HTTPS ausgefÃŧhrt wird, usw. ```Dockerfile -CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] +CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"] ``` -#### Docker-Cache +#### Docker-Cache { #docker-cache } In diesem `Dockerfile` gibt es einen wichtigen Trick: Wir kopieren zuerst die **Datei nur mit den Abhängigkeiten**, nicht den Rest des Codes. Lassen Sie mich Ihnen erklären, warum. @@ -288,7 +315,7 @@ Dann, gegen Ende des `Dockerfile`s, kopieren wir den gesamten Code. Da sich der COPY ./app /code/app ``` -### Das Docker-Image erstellen +### Das Docker-Image erstellen { #build-the-docker-image } Nachdem nun alle Dateien vorhanden sind, erstellen wir das Containerimage. @@ -313,7 +340,7 @@ In diesem Fall handelt es sich um dasselbe aktuelle Verzeichnis (`.`). /// -### Den Docker-Container starten +### Den Docker-Container starten { #start-the-docker-container } * FÃŧhren Sie einen Container basierend auf Ihrem Image aus: @@ -325,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
-## Es ÃŧberprÃŧfen +## Es testen { #check-it } Sie sollten es in der URL Ihres Docker-Containers ÃŧberprÃŧfen kÃļnnen, zum Beispiel: http://192.168.99.100/items/5?q=somequery oder http://127.0.0.1/items/5?q=somequery (oder gleichwertig, unter Verwendung Ihres Docker-Hosts). @@ -335,7 +362,7 @@ Sie werden etwas sehen wie: {"item_id": 5, "q": "somequery"} ``` -## Interaktive API-Dokumentation +## Interaktive API-Dokumentation { #interactive-api-docs } Jetzt kÃļnnen Sie auf http://192.168.99.100/docs oder http://127.0.0.1/docs gehen (oder ähnlich, unter Verwendung Ihres Docker-Hosts). @@ -343,7 +370,7 @@ Sie sehen die automatische interaktive API-Dokumentation (bereitgestellt von http://192.168.99.100/redoc oder http://127.0.0.1/redoc gehen (oder ähnlich, unter Verwendung Ihres Docker-Hosts). @@ -351,7 +378,7 @@ Sie sehen die alternative automatische Dokumentation (bereitgestellt von Cluster von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, mÃļchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Gunicorn mit Workern) zu verwenden. +Wenn Sie einen Cluster von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, mÃļchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden. -Diese verteilten Containerverwaltungssysteme wie Kubernetes verfÃŧgen normalerweise Ãŧber eine integrierte MÃļglichkeit, die **Replikation von Containern** zu handhaben und gleichzeitig **Load Balancing** fÃŧr die eingehenden Requests zu unterstÃŧtzen. Alles auf **Cluster-Ebene**. +Diese verteilten Containerverwaltungssysteme wie Kubernetes verfÃŧgen normalerweise Ãŧber eine integrierte MÃļglichkeit, die **Replikation von Containern** zu handhaben und gleichzeitig **Load Balancing** fÃŧr die eingehenden Requests zu unterstÃŧtzen. Alles auf **Cluster-Ebene**. -In diesen Fällen mÃļchten Sie wahrscheinlich ein **Docker-Image von Grund auf** erstellen, wie [oben erklärt](#dockerfile), Ihre Abhängigkeiten installieren und **einen einzelnen Uvicorn-Prozess** ausfÃŧhren, anstatt etwas wie Gunicorn mit Uvicorn-Workern auszufÃŧhren. +In diesen Fällen mÃļchten Sie wahrscheinlich ein **Docker-Image von Grund auf** erstellen, wie [oben erklärt](#dockerfile), Ihre Abhängigkeiten installieren und **einen einzelnen Uvicorn-Prozess** ausfÃŧhren, anstatt mehrere Uvicorn-Worker zu verwenden. -### Load Balancer +### Load Balancer { #load-balancer } Bei der Verwendung von Containern ist normalerweise eine Komponente vorhanden, **die am Hauptport lauscht**. Es kÃļnnte sich um einen anderen Container handeln, der auch ein **TLS-Terminierungsproxy** ist, um **HTTPS** zu verarbeiten, oder ein ähnliches Tool. -Da diese Komponente die **Last** an Requests aufnehmen und diese (hoffentlich) **ausgewogen** auf die Worker verteilen wÃŧrde, wird sie Ãŧblicherweise auch **Load Balancer** – Lastverteiler – genannt. +Da diese Komponente die **Last** an Requests aufnehmen und diese (hoffentlich) **ausgewogen** auf die Worker verteilen wÃŧrde, wird sie Ãŧblicherweise auch **Load Balancer** genannt. /// tip | Tipp @@ -449,7 +476,7 @@ Die gleiche **TLS-Terminierungsproxy**-Komponente, die fÃŧr HTTPS verwendet wird Und wenn Sie mit Containern arbeiten, verfÃŧgt das gleiche System, mit dem Sie diese starten und verwalten, bereits Ãŧber interne Tools, um die **Netzwerkkommunikation** (z. B. HTTP-Requests) von diesem **Load Balancer** (das kÃļnnte auch ein **TLS-Terminierungsproxy** sein) zu den Containern mit Ihrer Anwendung weiterzuleiten. -### Ein Load Balancer – mehrere Workercontainer +### Ein Load Balancer – mehrere Workercontainer { #one-load-balancer-multiple-worker-containers } Bei der Arbeit mit **Kubernetes** oder ähnlichen verteilten Containerverwaltungssystemen wÃŧrde die Verwendung ihrer internen Netzwerkmechanismen es dem einzelnen **Load Balancer**, der den Haupt-**Port** Ãŧberwacht, ermÃļglichen, Kommunikation (Requests) an mÃļglicherweise **mehrere Container** weiterzuleiten, in denen Ihre Anwendung ausgefÃŧhrt wird. @@ -459,42 +486,49 @@ Und das verteilte Containersystem mit dem **Load Balancer** wÃŧrde **die Request Und normalerweise wäre dieser **Load Balancer** in der Lage, Requests zu verarbeiten, die an *andere* Anwendungen in Ihrem Cluster gerichtet sind (z. B. eine andere Domain oder unter einem anderen URL-Pfad-Präfix), und wÃŧrde diese Kommunikation an die richtigen Container weiterleiten fÃŧr *diese andere* Anwendung, die in Ihrem Cluster ausgefÃŧhrt wird. -### Ein Prozess pro Container +### Ein Prozess pro Container { #one-process-per-container } -In einem solchen Szenario mÃļchten Sie wahrscheinlich **einen einzelnen (Uvicorn-)Prozess pro Container** haben, da Sie die Replikation bereits auf Cluster ebene durchfÃŧhren wÃŧrden. +In einem solchen Szenario mÃļchten Sie wahrscheinlich **einen einzelnen (Uvicorn-)Prozess pro Container** haben, da Sie die Replikation bereits auf Cluster-Ebene durchfÃŧhren wÃŧrden. -In diesem Fall mÃļchten Sie also **nicht** einen Prozessmanager wie Gunicorn mit Uvicorn-Workern oder Uvicorn mit seinen eigenen Uvicorn-Workern haben. Sie mÃļchten nur einen **einzelnen Uvicorn-Prozess** pro Container haben (wahrscheinlich aber mehrere Container). +In diesem Fall mÃļchten Sie also **nicht** mehrere Worker im Container haben, z. B. mit der `--workers` Befehlszeilenoption. Sie mÃļchten nur einen **einzelnen Uvicorn-Prozess** pro Container haben (wahrscheinlich aber mehrere Container). -Ein weiterer Prozessmanager im Container (wie es bei Gunicorn oder Uvicorn der Fall wäre, welche Uvicorn-Worker verwalten) wÃŧrde nur **unnÃļtige Komplexität** hinzufÃŧgen, um welche Sie sich hÃļchstwahrscheinlich bereits mit Ihrem Clustersystem kÃŧmmern. +Ein weiterer Prozessmanager im Container (wie es bei mehreren Workern der Fall wäre) wÃŧrde nur **unnÃļtige Komplexität** hinzufÃŧgen, um welche Sie sich hÃļchstwahrscheinlich bereits mit Ihrem Clustersystem kÃŧmmern. -### Container mit mehreren Prozessen und Sonderfälle +### Container mit mehreren Prozessen und Sonderfälle { #containers-with-multiple-processes-and-special-cases } -NatÃŧrlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit einem **Gunicorn-Prozessmanager** haben mÃļchten, welcher mehrere **Uvicorn-Workerprozesse** darin startet. +NatÃŧrlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit mehreren **Uvicorn-Workerprozessen** haben mÃļchten. -In diesen Fällen kÃļnnen Sie das **offizielle Docker-Image** verwenden, welches **Gunicorn** als Prozessmanager enthält, welcher mehrere **Uvicorn-Workerprozesse** ausfÃŧhrt, sowie einige Standardeinstellungen, um die Anzahl der Worker basierend auf den verfÃŧgbaren CPU-Kernen automatisch anzupassen. Ich erzähle Ihnen weiter unten in [Offizielles Docker-Image mit Gunicorn – Uvicorn](#offizielles-docker-image-mit-gunicorn-uvicorn) mehr darÃŧber. +In diesen Fällen kÃļnnen Sie die `--workers` Befehlszeilenoption verwenden, um die Anzahl der zu startenden Worker festzulegen: + +```{ .dockerfile .annotate } +FROM python:3.9 + +WORKDIR /code + +COPY ./requirements.txt /code/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +COPY ./app /code/app + +# (1)! +CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"] +``` + +1. Hier verwenden wir die `--workers` Befehlszeilenoption, um die Anzahl der Worker auf 4 festzulegen. Hier sind einige Beispiele, wann das sinnvoll sein kÃļnnte: -#### Eine einfache Anwendung +#### Eine einfache Anwendung { #a-simple-app } -Sie kÃļnnten einen Prozessmanager im Container haben wollen, wenn Ihre Anwendung **einfach genug** ist, sodass Sie die Anzahl der Prozesse nicht (zumindest noch nicht) zu stark tunen mÃŧssen und Sie einfach einen automatisierten Standard verwenden kÃļnnen (mit dem offiziellen Docker-Image), und Sie fÃŧhren es auf einem **einzelnen Server** aus, nicht auf einem Cluster. +Sie kÃļnnten einen Prozessmanager im Container haben wollen, wenn Ihre Anwendung **einfach genug** ist, sodass Sie es auf einem **einzelnen Server** ausfÃŧhren kÃļnnen, nicht auf einem Cluster. -#### Docker Compose +#### Docker Compose { #docker-compose } Sie kÃļnnten das Deployment auf einem **einzelnen Server** (kein Cluster) mit **Docker Compose** durchfÃŧhren, sodass Sie keine einfache MÃļglichkeit hätten, die Replikation von Containern (mit Docker Compose) zu verwalten und gleichzeitig das gemeinsame Netzwerk mit **Load Balancing** zu haben. Dann mÃļchten Sie vielleicht **einen einzelnen Container** mit einem **Prozessmanager** haben, der darin **mehrere Workerprozesse** startet. -#### Prometheus und andere GrÃŧnde - -Sie kÃļnnten auch **andere GrÃŧnde** haben, die es einfacher machen wÃŧrden, einen **einzelnen Container** mit **mehreren Prozessen** zu haben, anstatt **mehrere Container** mit **einem einzelnen Prozess** in jedem von ihnen. - -Beispielsweise kÃļnnten Sie (abhängig von Ihrem Setup) ein Tool wie einen Prometheus-Exporter im selben Container haben, welcher Zugriff auf **jeden der eingehenden Requests** haben sollte. - -Wenn Sie in hier **mehrere Container** hätten, wÃŧrde Prometheus beim **Lesen der Metriken** standardmäßig jedes Mal diejenigen fÃŧr **einen einzelnen Container** abrufen (fÃŧr den Container, der den spezifischen Request verarbeitet hat), anstatt die **akkumulierten Metriken** fÃŧr alle replizierten Container abzurufen. - -In diesem Fall kÃļnnte einfacher sein, **einen Container** mit **mehreren Prozessen** und ein lokales Tool (z. B. einen Prometheus-Exporter) in demselben Container zu haben, welches Prometheus-Metriken fÃŧr alle internen Prozesse sammelt und diese Metriken fÃŧr diesen einzelnen Container offenlegt. - --- Der Hauptpunkt ist, dass **keine** dieser Regeln **in Stein gemeißelt** ist, der man blind folgen muss. Sie kÃļnnen diese Ideen verwenden, um **Ihren eigenen Anwendungsfall zu evaluieren**, zu entscheiden, welcher Ansatz fÃŧr Ihr System am besten geeignet ist und herauszufinden, wie Sie folgende Konzepte verwalten: @@ -506,25 +540,25 @@ Der Hauptpunkt ist, dass **keine** dieser Regeln **in Stein gemeißelt** ist, de * Arbeitsspeicher * Schritte vor dem Start -## Arbeitsspeicher +## Arbeitsspeicher { #memory } Wenn Sie **einen einzelnen Prozess pro Container** ausfÃŧhren, wird von jedem dieser Container (mehr als einer, wenn sie repliziert werden) eine mehr oder weniger klar definierte, stabile und begrenzte Menge an Arbeitsspeicher verbraucht. -Und dann kÃļnnen Sie dieselben Speichergrenzen und -anforderungen in Ihren Konfigurationen fÃŧr Ihr Container-Management-System festlegen (z. B. in **Kubernetes**). Auf diese Weise ist es in der Lage, die Container auf den **verfÃŧgbaren Maschinen** zu replizieren, wobei die von denen benÃļtigte Speichermenge und die auf den Maschinen im Cluster verfÃŧgbare Menge berÃŧcksichtigt werden. +Und dann kÃļnnen Sie dieselben Speichergrenzen und -anforderungen in Ihren Konfigurationen fÃŧr Ihr Container-Management-System festlegen (z. B. in **Kubernetes**). Auf diese Weise ist es in der Lage, die Container auf den **verfÃŧgbaren Maschinen** zu replizieren, wobei die von diesen benÃļtigte Speichermenge und die auf den Maschinen im Cluster verfÃŧgbare Menge berÃŧcksichtigt werden. -Wenn Ihre Anwendung **einfach** ist, wird dies wahrscheinlich **kein Problem darstellen** und Sie mÃŧssen mÃļglicherweise keine festen Speichergrenzen angeben. Wenn Sie jedoch **viel Speicher verbrauchen** (z. B. bei **Modellen fÃŧr maschinelles Lernen**), sollten Sie ÃŧberprÃŧfen, wie viel Speicher Sie verbrauchen, und die **Anzahl der Container** anpassen, die in **jeder Maschine** ausgefÃŧhrt werden. (und mÃļglicherweise weitere Maschinen zu Ihrem Cluster hinzufÃŧgen). +Wenn Ihre Anwendung **einfach** ist, wird dies wahrscheinlich **kein Problem darstellen** und Sie mÃŧssen mÃļglicherweise keine festen Speichergrenzen angeben. Wenn Sie jedoch **viel Speicher verbrauchen** (z. B. bei **Modellen fÃŧr maschinelles Lernen**), sollten Sie ÃŧberprÃŧfen, wie viel Speicher Sie verbrauchen, und die **Anzahl der Container** anpassen, die in **jeder Maschine** ausgefÃŧhrt werden (und mÃļglicherweise weitere Maschinen zu Ihrem Cluster hinzufÃŧgen). -Wenn Sie **mehrere Prozesse pro Container** ausfÃŧhren (zum Beispiel mit dem offiziellen Docker-Image), mÃŧssen Sie sicherstellen, dass die Anzahl der gestarteten Prozesse nicht **mehr Speicher verbraucht** als verfÃŧgbar ist. +Wenn Sie **mehrere Prozesse pro Container** ausfÃŧhren, mÃŧssen Sie sicherstellen, dass die Anzahl der gestarteten Prozesse nicht **mehr Speicher verbraucht** als verfÃŧgbar ist. -## Schritte vor dem Start und Container +## Schritte vor dem Start und Container { #previous-steps-before-starting-and-containers } Wenn Sie Container (z. B. Docker, Kubernetes) verwenden, kÃļnnen Sie hauptsächlich zwei Ansätze verwenden. -### Mehrere Container +### Mehrere Container { #multiple-containers } -Wenn Sie **mehrere Container** haben, von denen wahrscheinlich jeder einen **einzelnen Prozess** ausfÃŧhrt (z. B. in einem **Kubernetes**-Cluster), dann mÃļchten Sie wahrscheinlich einen **separaten Container** haben, welcher die Arbeit der **Vorab-Schritte** in einem einzelnen Container, mit einem einzelnenen Prozess ausfÃŧhrt, **bevor** die replizierten Workercontainer ausgefÃŧhrt werden. +Wenn Sie **mehrere Container** haben, von denen wahrscheinlich jeder einen **einzelnen Prozess** ausfÃŧhrt (z. B. in einem **Kubernetes**-Cluster), dann mÃļchten Sie wahrscheinlich einen **separaten Container** haben, welcher die Arbeit der **Vorab-Schritte** in einem einzelnen Container, mit einem einzelnen Prozess ausfÃŧhrt, **bevor** die replizierten Workercontainer ausgefÃŧhrt werden. -/// info +/// info | Info Wenn Sie Kubernetes verwenden, wäre dies wahrscheinlich ein Init-Container. @@ -532,83 +566,29 @@ Wenn Sie Kubernetes verwenden, wäre dies wahrscheinlich ein tiangolo/uvicorn-gunicorn-fastapi. Dieses ist jedoch jetzt veraltet. â›”ī¸ -Dieses Image wäre vor allem in den oben beschriebenen Situationen nÃŧtzlich: [Container mit mehreren Prozessen und Sonderfälle](#container-mit-mehreren-prozessen-und-sonderfalle). +Sie sollten wahrscheinlich **nicht** dieses Basis-Docker-Image (oder ein anderes ähnliches) verwenden. -* tiangolo/uvicorn-gunicorn-fastapi. +Wenn Sie **Kubernetes** (oder andere) verwenden und bereits **Replikation** auf Cluster-Ebene mit mehreren **Containern** eingerichtet haben. In diesen Fällen ist es besser, **ein Image von Grund auf neu zu erstellen**, wie oben beschrieben: [Ein Docker-Image fÃŧr FastAPI erstellen](#build-a-docker-image-for-fastapi). -/// warning | Achtung +Und wenn Sie mehrere Worker benÃļtigen, kÃļnnen Sie einfach die `--workers` Befehlszeilenoption verwenden. -Es besteht eine hohe Wahrscheinlichkeit, dass Sie dieses oder ein ähnliches Basisimage **nicht** benÃļtigen und es besser wäre, wenn Sie das Image von Grund auf neu erstellen wÃŧrden, wie [oben beschrieben in: Ein Docker-Image fÃŧr FastAPI erstellen](#ein-docker-image-fur-fastapi-erstellen). +/// note | Technische Details + +Das Docker-Image wurde erstellt, als Uvicorn das Verwalten und Neustarten von ausgefallenen Workern noch nicht unterstÃŧtzte, weshalb es notwendig war, Gunicorn mit Uvicorn zu verwenden, was zu einer erheblichen Komplexität fÃŧhrte, nur damit Gunicorn die Uvicorn-Workerprozesse verwaltet und neu startet. + +Aber jetzt, da Uvicorn (und der `fastapi`-Befehl) die Verwendung von `--workers` unterstÃŧtzen, gibt es keinen Grund, ein Basis-Docker-Image an Stelle eines eigenen (das praktisch denselben Code enthält 😅) zu verwenden. /// -Dieses Image verfÃŧgt Ãŧber einen **Auto-Tuning**-Mechanismus, um die **Anzahl der Arbeitsprozesse** basierend auf den verfÃŧgbaren CPU-Kernen festzulegen. - -Es verfÃŧgt Ãŧber **vernÃŧnftige Standardeinstellungen**, aber Sie kÃļnnen trotzdem alle Konfigurationen mit **Umgebungsvariablen** oder Konfigurationsdateien ändern und aktualisieren. - -Es unterstÃŧtzt auch die AusfÃŧhrung von **Vorab-Schritten vor dem Start** mit einem Skript. - -/// tip | Tipp - -Um alle Konfigurationen und Optionen anzuzeigen, gehen Sie zur Docker-Image-Seite: tiangolo/uvicorn-gunicorn-fastapi. - -/// - -### Anzahl der Prozesse auf dem offiziellen Docker-Image - -Die **Anzahl der Prozesse** auf diesem Image wird **automatisch** anhand der verfÃŧgbaren CPU-**Kerne** berechnet. - -Das bedeutet, dass versucht wird, so viel **Leistung** wie mÃļglich aus der CPU herauszuquetschen. - -Sie kÃļnnen das auch in der Konfiguration anpassen, indem Sie **Umgebungsvariablen**, usw. verwenden. - -Das bedeutet aber auch, da die Anzahl der Prozesse von der CPU abhängt, welche der Container ausfÃŧhrt, dass die **Menge des verbrauchten Speichers** ebenfalls davon abhängt. - -Wenn Ihre Anwendung also viel Speicher verbraucht (z. B. bei Modellen fÃŧr maschinelles Lernen) und Ihr Server Ãŧber viele CPU-Kerne, **aber wenig Speicher** verfÃŧgt, kÃļnnte Ihr Container am Ende versuchen, mehr Speicher als vorhanden zu verwenden, was zu erheblichen Leistungseinbußen (oder sogar zum Absturz) fÃŧhren kann. 🚨 - -### Ein `Dockerfile` erstellen - -So wÃŧrden Sie ein `Dockerfile` basierend auf diesem Image erstellen: - -```Dockerfile -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt - -COPY ./app /app -``` - -### GrÃļßere Anwendungen - -Wenn Sie dem Abschnitt zum Erstellen von [grÃļßeren Anwendungen mit mehreren Dateien](../tutorial/bigger-applications.md){.internal-link target=_blank} gefolgt sind, kÃļnnte Ihr `Dockerfile` stattdessen wie folgt aussehen: - -```Dockerfile hl_lines="7" -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt - -COPY ./app /app/app -``` - -### Wann verwenden - -Sie sollten dieses offizielle Basisimage (oder ein ähnliches) wahrscheinlich **nicht** benutzen, wenn Sie **Kubernetes** (oder andere) verwenden und Sie bereits **Replikation** auf Cluster ebene mit mehreren **Containern** eingerichtet haben. In diesen Fällen ist es besser, **ein Image von Grund auf zu erstellen**, wie oben beschrieben: [Ein Docker-Image fÃŧr FastAPI erstellen](#ein-docker-image-fur-fastapi-erstellen). - -Dieses Image wäre vor allem in den oben in [Container mit mehreren Prozessen und Sonderfälle](#container-mit-mehreren-prozessen-und-sonderfalle) beschriebenen Sonderfällen nÃŧtzlich. Wenn Ihre Anwendung beispielsweise **einfach genug** ist, dass das Festlegen einer Standardanzahl von Prozessen basierend auf der CPU gut funktioniert, mÃļchten Sie sich nicht mit der manuellen Konfiguration der Replikation auf Cluster ebene herumschlagen und fÃŧhren nicht mehr als einen Container mit Ihrer Anwendung aus. Oder wenn Sie das Deployment mit **Docker Compose** durchfÃŧhren und auf einem einzelnen Server laufen, usw. - -## Deployment des Containerimages +## Deployment des Containerimages { #deploy-the-container-image } Nachdem Sie ein Containerimage (Docker) haben, gibt es mehrere MÃļglichkeiten, es bereitzustellen. @@ -620,100 +600,11 @@ Zum Beispiel: * Mit einem anderen Tool wie Nomad * Mit einem Cloud-Dienst, der Ihr Containerimage nimmt und es bereitstellt -## Docker-Image mit Poetry +## Docker-Image mit `uv` { #docker-image-with-uv } -Wenn Sie Poetry verwenden, um die Abhängigkeiten Ihres Projekts zu verwalten, kÃļnnen Sie Dockers mehrphasige Builds verwenden: +Wenn Sie uv verwenden, um Ihr Projekt zu installieren und zu verwalten, kÃļnnen Sie deren uv-Docker-Leitfaden befolgen. -```{ .dockerfile .annotate } -# (1) -FROM python:3.9 as requirements-stage - -# (2) -WORKDIR /tmp - -# (3) -RUN pip install poetry - -# (4) -COPY ./pyproject.toml ./poetry.lock* /tmp/ - -# (5) -RUN poetry export -f requirements.txt --output requirements.txt --without-hashes - -# (6) -FROM python:3.9 - -# (7) -WORKDIR /code - -# (8) -COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt - -# (9) -RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt - -# (10) -COPY ./app /code/app - -# (11) -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] -``` - -1. Dies ist die erste Phase, genannt `requirements-stage` – „Anforderungsphase“. - -2. Setze `/tmp` als aktuelles Arbeitsverzeichnis. - - Hier werden wir die Datei `requirements.txt` generieren. - -3. Installiere Poetry in dieser Docker-Phase. - -4. Kopiere die Dateien `pyproject.toml` und `poetry.lock` in das Verzeichnis `/tmp`. - - Da es `./poetry.lock*` verwendet (endet mit einem `*`), stÃŧrzt es nicht ab, wenn diese Datei noch nicht verfÃŧgbar ist. - -5. Generiere die Datei `requirements.txt`. - -6. Dies ist die letzte Phase. Alles hier bleibt im endgÃŧltigen Containerimage erhalten. - -7. Setze das aktuelle Arbeitsverzeichnis auf `/code`. - -8. Kopiere die Datei `requirements.txt` in das Verzeichnis `/code`. - - Diese Datei existiert nur in der vorherigen Docker-Phase, deshalb verwenden wir `--from-requirements-stage`, um sie zu kopieren. - -9. Installiere die Paketabhängigkeiten von der generierten Datei `requirements.txt`. - -10. Kopiere das Verzeichnis `app` in das Verzeichnis `/code`. - -11. FÃŧhre den Befehl `uvicorn` aus und weise ihn an, das aus `app.main` importierte `app`-Objekt zu verwenden. - -/// tip | Tipp - -Klicken Sie auf die Zahlenblasen, um zu sehen, was jede Zeile bewirkt. - -/// - -Eine **Docker-Phase** ist ein Teil eines `Dockerfile`s, welcher als **temporäres Containerimage** fungiert und nur zum Generieren einiger Dateien fÃŧr die spätere Verwendung verwendet wird. - -Die erste Phase wird nur zur **Installation von Poetry** und zur **Generierung der `requirements.txt`** mit deren Projektabhängigkeiten aus der Datei `pyproject.toml` von Poetry verwendet. - -Diese `requirements.txt`-Datei wird später in der **nächsten Phase** mit `pip` verwendet. - -Im endgÃŧltigen Containerimage bleibt **nur die letzte Stufe** erhalten. Die vorherigen Stufen werden verworfen. - -Bei der Verwendung von Poetry wäre es sinnvoll, **mehrstufige Docker-Builds** zu verwenden, da Poetry und seine Abhängigkeiten nicht wirklich im endgÃŧltigen Containerimage installiert sein mÃŧssen, sondern Sie brauchen **nur** die Datei `requirements.txt`, um Ihre Projektabhängigkeiten zu installieren. - -Dann wÃŧrden Sie im nächsten (und letzten) Schritt das Image mehr oder weniger auf die gleiche Weise wie zuvor beschrieben erstellen. - -### Hinter einem TLS-Terminierungsproxy – Poetry - -Auch hier gilt: Wenn Sie Ihren Container hinter einem TLS-Terminierungsproxy (Load Balancer) wie Nginx oder Traefik ausfÃŧhren, fÃŧgen Sie dem Befehl die Option `--proxy-headers` hinzu: - -```Dockerfile -CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] -``` - -## Zusammenfassung +## Zusammenfassung { #recap } Mithilfe von Containersystemen (z. B. mit **Docker** und **Kubernetes**) ist es ziemlich einfach, alle **Deployment-Konzepte** zu handhaben: @@ -727,5 +618,3 @@ Mithilfe von Containersystemen (z. B. mit **Docker** und **Kubernetes**) ist es In den meisten Fällen mÃļchten Sie wahrscheinlich kein Basisimage verwenden und stattdessen **ein Containerimage von Grund auf erstellen**, eines basierend auf dem offiziellen Python-Docker-Image. Indem Sie auf die **Reihenfolge** der Anweisungen im `Dockerfile` und den **Docker-Cache** achten, kÃļnnen Sie **die Build-Zeiten minimieren**, um Ihre Produktivität zu erhÃļhen (und Langeweile zu vermeiden). 😎 - -In bestimmten Sonderfällen mÃļchten Sie mÃļglicherweise das offizielle Docker-Image fÃŧr FastAPI verwenden. 🤓 diff --git a/docs/de/docs/deployment/https.md b/docs/de/docs/deployment/https.md index a216f44af..1c4ce6b44 100644 --- a/docs/de/docs/deployment/https.md +++ b/docs/de/docs/deployment/https.md @@ -1,4 +1,4 @@ -# Über HTTPS +# Über HTTPS { #about-https } Es ist leicht anzunehmen, dass HTTPS etwas ist, was einfach nur „aktiviert“ wird oder nicht. @@ -22,19 +22,19 @@ Aus **Sicht des Entwicklers** sollten Sie beim Nachdenken Ãŧber HTTPS Folgendes * Die VerschlÃŧsselung der Verbindung erfolgt auf **TCP-Ebene**. * Das ist eine Schicht **unter HTTP**. * Die Handhabung von **Zertifikaten und VerschlÃŧsselung** erfolgt also **vor HTTP**. -* **TCP weiß nichts Ãŧber „Domains“**. Nur Ãŧber IP-Adressen. +* **TCP weiß nichts Ãŧber „Domains“**. Nur Ãŧber IP-Adressen. * Die Informationen Ãŧber die angeforderte **spezifische Domain** befinden sich in den **HTTP-Daten**. * Die **HTTPS-Zertifikate** „zertifizieren“ eine **bestimmte Domain**, aber das Protokoll und die VerschlÃŧsselung erfolgen auf TCP-Ebene, **ohne zu wissen**, um welche Domain es sich handelt. * **Standardmäßig** bedeutet das, dass Sie nur **ein HTTPS-Zertifikat pro IP-Adresse** haben kÃļnnen. * Ganz gleich, wie groß Ihr Server ist oder wie klein die einzelnen Anwendungen darauf sind. * HierfÃŧr gibt es jedoch eine **LÃļsung**. -* Es gibt eine **Erweiterung** zum **TLS**-Protokoll (dasjenige, das die VerschlÃŧsselung auf TCP-Ebene, vor HTTP, verwaltet) namens **SNI**. - * Mit dieser SNI-Erweiterung kann ein einzelner Server (mit einer **einzelnen IP-Adresse**) Ãŧber **mehrere HTTPS-Zertifikate** verfÃŧgen und **mehrere HTTPS-Domains/Anwendungen** bedienen. +* Es gibt eine **Erweiterung** zum **TLS**-Protokoll (dasjenige, das die VerschlÃŧsselung auf TCP-Ebene, vor HTTP, verwaltet) namens **SNI**. + * Mit dieser SNI-Erweiterung kann ein einzelner Server (mit einer **einzelnen IP-Adresse**) Ãŧber **mehrere HTTPS-Zertifikate** verfÃŧgen und **mehrere HTTPS-Domains/Anwendungen bereitstellen**. * Damit das funktioniert, muss eine **einzelne** Komponente (Programm), die auf dem Server ausgefÃŧhrt wird und welche die **Ãļffentliche IP-Adresse** Ãŧberwacht, **alle HTTPS-Zertifikate** des Servers haben. * **Nachdem** eine sichere Verbindung hergestellt wurde, ist das Kommunikationsprotokoll **immer noch HTTP**. * Die Inhalte sind **verschlÃŧsselt**, auch wenn sie mit dem **HTTP-Protokoll** gesendet werden. -Es ist eine gängige Praxis, **ein Programm/HTTP-Server** auf dem Server (der Maschine, dem Host usw.) laufen zu lassen, welches **alle HTTPS-Aspekte verwaltet**: Empfangen der **verschlÃŧsselten HTTPS-Requests**, Senden der **entschlÃŧsselten HTTP-Requests** an die eigentliche HTTP-Anwendung die auf demselben Server läuft (in diesem Fall die **FastAPI**-Anwendung), entgegennehmen der **HTTP-Response** von der Anwendung, **verschlÃŧsseln derselben** mithilfe des entsprechenden **HTTPS-Zertifikats** und ZurÃŧcksenden zum Client Ãŧber **HTTPS**. Dieser Server wird oft als **TLS-Terminierungsproxy** bezeichnet. +Es ist eine gängige Praxis, **ein Programm/HTTP-Server** auf dem Server (der Maschine, dem Host usw.) laufen zu lassen, welches **alle HTTPS-Aspekte verwaltet**: Empfangen der **verschlÃŧsselten HTTPS-Requests**, Senden der **entschlÃŧsselten HTTP-Requests** an die eigentliche HTTP-Anwendung die auf demselben Server läuft (in diesem Fall die **FastAPI**-Anwendung), entgegennehmen der **HTTP-Response** von der Anwendung, **verschlÃŧsseln derselben** mithilfe des entsprechenden **HTTPS-Zertifikats** und ZurÃŧcksenden zum Client Ãŧber **HTTPS**. Dieser Server wird oft als **TLS-Terminierungsproxy** bezeichnet. Einige der Optionen, die Sie als TLS-Terminierungsproxy verwenden kÃļnnen, sind: @@ -43,7 +43,7 @@ Einige der Optionen, die Sie als TLS-Terminierungsproxy verwenden kÃļnnen, sind: * Nginx * HAProxy -## Let's Encrypt +## Let's Encrypt { #lets-encrypt } Vor Let's Encrypt wurden diese **HTTPS-Zertifikate** von vertrauenswÃŧrdigen Dritten verkauft. @@ -57,13 +57,13 @@ Die Domains werden sicher verifiziert und die Zertifikate werden automatisch gen Die Idee besteht darin, den Erwerb und die Erneuerung der Zertifikate zu automatisieren, sodass Sie **sicheres HTTPS, kostenlos und fÃŧr immer** haben kÃļnnen. -## HTTPS fÃŧr Entwickler +## HTTPS fÃŧr Entwickler { #https-for-developers } Hier ist ein Beispiel, wie eine HTTPS-API aussehen kÃļnnte, Schritt fÃŧr Schritt, wobei vor allem die fÃŧr Entwickler wichtigen Ideen berÃŧcksichtigt werden. -### Domainname +### Domainname { #domain-name } -Alles beginnt wahrscheinlich damit, dass Sie einen **Domainnamen erwerben**. Anschließend konfigurieren Sie ihn in einem DNS-Server (wahrscheinlich beim selben Cloud-Anbieter). +Alles beginnt wahrscheinlich damit, dass Sie einen **Domainnamen erwerben**. Anschließend konfigurieren Sie ihn in einem DNS-Server (wahrscheinlich beim selben Cloudanbieter). Sie wÃŧrden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine feste **Ãļffentliche IP-Adresse**. @@ -77,17 +77,17 @@ Dieser Domainnamen-Aspekt liegt weit vor HTTPS, aber da alles von der Domain und /// -### DNS +### DNS { #dns } Konzentrieren wir uns nun auf alle tatsächlichen HTTPS-Aspekte. -Zuerst wÃŧrde der Browser mithilfe der **DNS-Server** herausfinden, welches die **IP fÃŧr die Domain** ist, in diesem Fall fÃŧr `someapp.example.com`. +Zuerst wÃŧrde der Browser mithilfe der **DNS-Server** herausfinden, welches die **IP fÃŧr die Domain** ist, in diesem Fall `someapp.example.com`. Die DNS-Server geben dem Browser eine bestimmte **IP-Adresse** zurÃŧck. Das wäre die von Ihrem Server verwendete Ãļffentliche IP-Adresse, die Sie in den DNS-Servern konfiguriert haben. -### TLS-Handshake-Start +### TLS-Handshake-Start { #tls-handshake-start } Der Browser kommuniziert dann mit dieser IP-Adresse Ãŧber **Port 443** (den HTTPS-Port). @@ -97,7 +97,7 @@ Der erste Teil der Kommunikation besteht lediglich darin, die Verbindung zwische Diese Interaktion zwischen dem Client und dem Server zum Aufbau der TLS-Verbindung wird als **TLS-Handshake** bezeichnet. -### TLS mit SNI-Erweiterung +### TLS mit SNI-Erweiterung { #tls-with-sni-extension } **Nur ein Prozess** im Server kann an einem bestimmten **Port** einer bestimmten **IP-Adresse** lauschen. MÃļglicherweise gibt es andere Prozesse, die an anderen Ports dieselbe IP-Adresse abhÃļren, jedoch nur einen fÃŧr jede Kombination aus IP-Adresse und Port. @@ -127,7 +127,7 @@ Beachten Sie, dass die VerschlÃŧsselung der Kommunikation auf der **TCP-Ebene** /// -### HTTPS-Request +### HTTPS-Request { #https-request } Da Client und Server (sprich, der Browser und der TLS-Terminierungsproxy) nun Ãŧber eine **verschlÃŧsselte TCP-Verbindung** verfÃŧgen, kÃļnnen sie die **HTTP-Kommunikation** starten. @@ -135,19 +135,19 @@ Der Client sendet also einen **HTTPS-Request**. Das ist einfach ein HTTP-Request -### Den Request entschlÃŧsseln +### Den Request entschlÃŧsseln { #decrypt-the-request } Der TLS-Terminierungsproxy wÃŧrde die vereinbarte VerschlÃŧsselung zum **EntschlÃŧsseln des Requests** verwenden und den **einfachen (entschlÃŧsselten) HTTP-Request** an den Prozess weiterleiten, der die Anwendung ausfÃŧhrt (z. B. einen Prozess, bei dem Uvicorn die FastAPI-Anwendung ausfÃŧhrt). -### HTTP-Response +### HTTP-Response { #http-response } Die Anwendung wÃŧrde den Request verarbeiten und eine **einfache (unverschlÃŧsselte) HTTP-Response** an den TLS-Terminierungsproxy senden. -### HTTPS-Response +### HTTPS-Response { #https-response } Der TLS-Terminierungsproxy wÃŧrde dann die Response mithilfe der zuvor vereinbarten Kryptografie (als das Zertifikat fÃŧr `someapp.example.com` verhandelt wurde) **verschlÃŧsseln** und sie an den Browser zurÃŧcksenden. @@ -157,7 +157,7 @@ Als Nächstes ÃŧberprÃŧft der Browser, ob die Response gÃŧltig und mit dem richt Der Client (Browser) weiß, dass die Response vom richtigen Server kommt, da dieser die Kryptografie verwendet, die zuvor mit dem **HTTPS-Zertifikat** vereinbart wurde. -### Mehrere Anwendungen +### Mehrere Anwendungen { #multiple-applications } Auf demselben Server (oder denselben Servern) kÃļnnten sich **mehrere Anwendungen** befinden, beispielsweise andere API-Programme oder eine Datenbank. @@ -167,7 +167,7 @@ Nur ein Prozess kann diese spezifische IP und den Port verarbeiten (in unserem B Auf diese Weise kÃļnnte der TLS-Terminierungsproxy HTTPS und Zertifikate fÃŧr **mehrere Domains**, fÃŧr mehrere Anwendungen, verarbeiten und die Requests dann jeweils an die richtige Anwendung weiterleiten. -### Verlängerung des Zertifikats +### Verlängerung des Zertifikats { #certificate-renewal } Irgendwann in der Zukunft wÃŧrde jedes Zertifikat **ablaufen** (etwa 3 Monate nach dem Erwerb). @@ -190,7 +190,39 @@ Um dies zu erreichen und den unterschiedlichen Anwendungsanforderungen gerecht z Dieser ganze Erneuerungsprozess, während die Anwendung weiterhin bereitgestellt wird, ist einer der HauptgrÃŧnde, warum Sie ein **separates System zur Verarbeitung von HTTPS** mit einem TLS-Terminierungsproxy haben mÃļchten, anstatt einfach die TLS-Zertifikate direkt mit dem Anwendungsserver zu verwenden (z. B. Uvicorn). -## Zusammenfassung +## Proxy-Forwarded-Header { #proxy-forwarded-headers } + +Wenn Sie einen Proxy zur Verarbeitung von HTTPS verwenden, weiß Ihr **Anwendungsserver** (z. B. Uvicorn Ãŧber das FastAPI CLI) nichts Ãŧber den HTTPS-Prozess, er kommuniziert per einfachem HTTP mit dem **TLS-Terminierungsproxy**. + +Dieser **Proxy** wÃŧrde normalerweise unmittelbar vor dem Übermitteln der Anfrage an den **Anwendungsserver** einige HTTP-Header dynamisch setzen, um dem Anwendungsserver mitzuteilen, dass der Request vom Proxy **weitergeleitet** wird. + +/// note | Technische Details + +Die Proxy-Header sind: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +Trotzdem, da der **Anwendungsserver** nicht weiß, dass er sich hinter einem vertrauenswÃŧrdigen **Proxy** befindet, wÃŧrde er diesen Headern standardmäßig nicht vertrauen. + +Sie kÃļnnen den **Anwendungsserver** jedoch so konfigurieren, dass er den vom **Proxy** gesendeten *Forwarded*-Headern vertraut. Wenn Sie das FastAPI CLI verwenden, kÃļnnen Sie die *CLI-Option* `--forwarded-allow-ips` nutzen, um anzugeben, von welchen IPs er diesen *Forwarded*-Headern vertrauen soll. + +Wenn der **Anwendungsserver** beispielsweise nur Kommunikation vom vertrauenswÃŧrdigen **Proxy** empfängt, kÃļnnen Sie `--forwarded-allow-ips="*"` setzen, um allen eingehenden IPs zu vertrauen, da er nur Requests von der vom **Proxy** verwendeten IP erhalten wird. + +Auf diese Weise kann die Anwendung ihre eigene Ãļffentliche URL, ob sie HTTPS verwendet, die Domain, usw. erkennen. + +Das ist z. B. nÃŧtzlich, um Redirects korrekt zu handhaben. + +/// tip | Tipp + +Mehr dazu finden Sie in der Dokumentation zu [Hinter einem Proxy – Proxy-Forwarded-Header aktivieren](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} + +/// + +## Zusammenfassung { #recap } **HTTPS** zu haben ist sehr wichtig und in den meisten Fällen eine **kritische Anforderung**. Die meiste Arbeit, die Sie als Entwickler in Bezug auf HTTPS aufwenden mÃŧssen, besteht lediglich darin, **diese Konzepte zu verstehen** und wie sie funktionieren. diff --git a/docs/de/docs/deployment/index.md b/docs/de/docs/deployment/index.md index 1aa131097..65c76edce 100644 --- a/docs/de/docs/deployment/index.md +++ b/docs/de/docs/deployment/index.md @@ -1,18 +1,18 @@ -# Deployment +# Deployment { #deployment } Das Deployment einer **FastAPI**-Anwendung ist relativ einfach. -## Was bedeutet Deployment? +## Was bedeutet Deployment { #what-does-deployment-mean } -**Deployment** (Deutsch etwa: **Bereitstellen der Anwendung**) bedeutet, die notwendigen Schritte durchzufÃŧhren, um die Anwendung **fÃŧr die Endbenutzer verfÃŧgbar** zu machen. +**Deployment** bedeutet, die notwendigen Schritte durchzufÃŧhren, um die Anwendung **fÃŧr die Endbenutzer verfÃŧgbar** zu machen. Bei einer **Web-API** bedeutet das normalerweise, diese auf einem **entfernten Rechner** zu platzieren, mit einem **Serverprogramm**, welches gute Leistung, Stabilität, usw. bietet, damit Ihre **Benutzer** auf die Anwendung effizient und ohne Unterbrechungen oder Probleme **zugreifen** kÃļnnen. Das steht im Gegensatz zu den **Entwicklungsphasen**, in denen Sie ständig den Code ändern, kaputt machen, reparieren, den Entwicklungsserver stoppen und neu starten, usw. -## Deployment-Strategien +## Deployment-Strategien { #deployment-strategies } -Abhängig von Ihrem spezifischen Anwendungsfall und den von Ihnen verwendeten Tools gibt es mehrere MÃļglichkeiten, das zu tun. +Es gibt mehrere MÃļglichkeiten, dies zu tun, abhängig von Ihrem spezifischen Anwendungsfall und den von Ihnen verwendeten Tools. Sie kÃļnnten mithilfe einer Kombination von Tools selbst **einen Server bereitstellen**, Sie kÃļnnten einen **Cloud-Dienst** nutzen, der einen Teil der Arbeit fÃŧr Sie erledigt, oder andere mÃļgliche Optionen. diff --git a/docs/de/docs/deployment/manually.md b/docs/de/docs/deployment/manually.md index fdb33f7fe..6393f8ebc 100644 --- a/docs/de/docs/deployment/manually.md +++ b/docs/de/docs/deployment/manually.md @@ -1,30 +1,82 @@ -# Einen Server manuell ausfÃŧhren – Uvicorn +# Einen Server manuell ausfÃŧhren { #run-a-server-manually } -Das Wichtigste, was Sie zum AusfÃŧhren einer **FastAPI**-Anwendung auf einer entfernten Servermaschine benÃļtigen, ist ein ASGI-Serverprogramm, wie **Uvicorn**. +## Den `fastapi run` Befehl verwenden { #use-the-fastapi-run-command } -Es gibt 3 Hauptalternativen: +Kurz gesagt, nutzen Sie `fastapi run`, um Ihre FastAPI-Anwendung bereitzustellen: + +
+ +```console +$ fastapi run main.py + + FastAPI Starting production server 🚀 + + Searching for package file structure from directories + with __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with + the following code: + + from main import app + + app Using import string: main:app + + server Server started at http://0.0.0.0:8000 + server Documentation at http://0.0.0.0:8000/docs + + Logs: + + INFO Started server process [2306215] + INFO Waiting for application startup. + INFO Application startup complete. + INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C + to quit) +``` + +
+ +Das wÃŧrde in den meisten Fällen funktionieren. 😎 + +Sie kÃļnnten diesen Befehl beispielsweise verwenden, um Ihre **FastAPI**-App in einem Container, auf einem Server usw. zu starten. + +## ASGI-Server { #asgi-servers } + +Lassen Sie uns ein wenig tiefer in die Details eintauchen. + +FastAPI verwendet einen Standard zum Erstellen von Python-Webframeworks und -Servern, der als ASGI bekannt ist. FastAPI ist ein ASGI-Webframework. + +Das Wichtigste, was Sie benÃļtigen, um eine **FastAPI**-Anwendung (oder eine andere ASGI-Anwendung) auf einer entfernten Servermaschine auszufÃŧhren, ist ein ASGI-Serverprogramm wie **Uvicorn**, der standardmäßig im `fastapi`-Kommando enthalten ist. + +Es gibt mehrere Alternativen, einschließlich: * Uvicorn: ein hochperformanter ASGI-Server. -* Hypercorn: ein ASGI-Server, der unter anderem mit HTTP/2 und Trio kompatibel ist. -* Daphne: Der fÃŧr Django Channels entwickelte ASGI-Server. +* Hypercorn: ein ASGI-Server, der unter anderem kompatibel mit HTTP/2 und Trio ist. +* Daphne: der fÃŧr Django Channels entwickelte ASGI-Server. +* Granian: Ein Rust HTTP-Server fÃŧr Python-Anwendungen. +* NGINX Unit: NGINX Unit ist eine leichte und vielseitige Laufzeitumgebung fÃŧr Webanwendungen. -## Servermaschine und Serverprogramm +## Servermaschine und Serverprogramm { #server-machine-and-server-program } -Bei den Benennungen gibt es ein kleines Detail, das Sie beachten sollten. 💡 +Es gibt ein kleines Detail bei den Namen, das Sie beachten sollten. 💡 -Das Wort „**Server**“ bezieht sich häufig sowohl auf den entfernten-/Cloud-Computer (die physische oder virtuelle Maschine) als auch auf das Programm, das auf dieser Maschine ausgefÃŧhrt wird (z. B. Uvicorn). +Das Wort „**Server**“ wird häufig verwendet, um sowohl den entfernten/Cloud-Computer (die physische oder virtuelle Maschine) als auch das Programm zu bezeichnen, das auf dieser Maschine läuft (z. B. Uvicorn). -Denken Sie einfach daran, wenn Sie „Server“ im Allgemeinen lesen, dass es sich auf eines dieser beiden Dinge beziehen kann. +Denken Sie einfach daran, dass sich „Server“ im Allgemeinen auf eines dieser beiden Dinge beziehen kann. Wenn man sich auf die entfernte Maschine bezieht, wird sie Ãŧblicherweise als **Server**, aber auch als **Maschine**, **VM** (virtuelle Maschine) oder **Knoten** bezeichnet. Diese Begriffe beziehen sich auf irgendeine Art von entfernten Rechner, normalerweise unter Linux, auf dem Sie Programme ausfÃŧhren. -## Das Serverprogramm installieren +## Das Serverprogramm installieren { #install-the-server-program } -Sie kÃļnnen einen ASGI-kompatiblen Server installieren mit: +Wenn Sie FastAPI installieren, wird es mit einem Produktionsserver, Uvicorn, geliefert, und Sie kÃļnnen ihn mit dem `fastapi run` Befehl starten. -//// tab | Uvicorn +Aber Sie kÃļnnen auch ein ASGI-Serverprogramm manuell installieren. -* Uvicorn, ein blitzschneller ASGI-Server, basierend auf uvloop und httptools. +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und dann die Serveranwendung installieren. + +Zum Beispiel, um Uvicorn zu installieren:
@@ -36,39 +88,21 @@ $ pip install "uvicorn[standard]"
+Ein ähnlicher Prozess wÃŧrde fÃŧr jedes andere ASGI-Serverprogramm gelten. + /// tip | Tipp Durch das HinzufÃŧgen von `standard` installiert und verwendet Uvicorn einige empfohlene zusätzliche Abhängigkeiten. -Inklusive `uvloop`, einen hochperformanten Drop-in-Ersatz fÃŧr `asyncio`, welcher fÃŧr einen großen Leistungsschub bei der Nebenläufigkeit sorgt. +Dazu gehÃļrt `uvloop`, der hochperformante Drop-in-Ersatz fÃŧr `asyncio`, der den großen Nebenläufigkeits-Performanz-Schub bietet. + +Wenn Sie FastAPI mit etwas wie `pip install "fastapi[standard]"` installieren, erhalten Sie auch `uvicorn[standard]`. /// -//// +## Das Serverprogramm ausfÃŧhren { #run-the-server-program } -//// tab | Hypercorn - -* Hypercorn, ein ASGI-Server, der auch mit HTTP/2 kompatibel ist. - -
- -```console -$ pip install hypercorn - ----> 100% -``` - -
- -... oder jeden anderen ASGI-Server. - -//// - -## Das Serverprogramm ausfÃŧhren - -Anschließend kÃļnnen Sie Ihre Anwendung auf die gleiche Weise ausfÃŧhren, wie Sie es in den Tutorials getan haben, jedoch ohne die Option `--reload`, z. B.: - -//// tab | Uvicorn +Wenn Sie einen ASGI-Server manuell installiert haben, mÃŧssen Sie normalerweise einen Importstring in einem speziellen Format Ãŧbergeben, damit er Ihre FastAPI-Anwendung importiert:
@@ -80,72 +114,36 @@ $ uvicorn main:app --host 0.0.0.0 --port 80
-//// +/// note | Hinweis -//// tab | Hypercorn +Der Befehl `uvicorn main:app` bezieht sich auf: -
+* `main`: die Datei `main.py` (das Python-„Modul“). +* `app`: das Objekt, das innerhalb von `main.py` mit der Zeile `app = FastAPI()` erstellt wurde. -```console -$ hypercorn main:app --bind 0.0.0.0:80 +Es ist äquivalent zu: -Running on 0.0.0.0:8080 over http (CTRL + C to quit) +```Python +from main import app ``` -
- -//// - -/// warning | Achtung - -Denken Sie daran, die Option `--reload` zu entfernen, wenn Sie diese verwendet haben. - -Die Option `--reload` verbraucht viel mehr Ressourcen, ist instabiler, usw. - -Sie hilft sehr während der **Entwicklung**, aber Sie sollten sie **nicht** in der **Produktion** verwenden. - /// -## Hypercorn mit Trio +Jedes alternative ASGI-Serverprogramm hätte einen ähnlichen Befehl, Sie kÃļnnen in deren jeweiligen Dokumentationen mehr lesen. -Starlette und **FastAPI** basieren auf AnyIO, welches diese sowohl mit der Python-Standardbibliothek asyncio, als auch mit Trio kompatibel macht. +/// warning | Achtung -Dennoch ist Uvicorn derzeit nur mit asyncio kompatibel und verwendet normalerweise `uvloop`, den leistungsstarken Drop-in-Ersatz fÃŧr `asyncio`. +Uvicorn und andere Server unterstÃŧtzen eine `--reload`-Option, die während der Entwicklung nÃŧtzlich ist. -Wenn Sie jedoch **Trio** direkt verwenden mÃļchten, kÃļnnen Sie **Hypercorn** verwenden, da dieses es unterstÃŧtzt. ✨ +Die `--reload`-Option verbraucht viel mehr Ressourcen, ist instabiler, usw. -### Hypercorn mit Trio installieren +Sie hilft während der **Entwicklung**, Sie sollten sie jedoch **nicht** in der **Produktion** verwenden. -Zuerst mÃŧssen Sie Hypercorn mit Trio-UnterstÃŧtzung installieren: +/// -
+## Deployment-Konzepte { #deployment-concepts } -```console -$ pip install "hypercorn[trio]" ----> 100% -``` - -
- -### Mit Trio ausfÃŧhren - -Dann kÃļnnen Sie die Befehlszeilenoption `--worker-class` mit dem Wert `trio` Ãŧbergeben: - -
- -```console -$ hypercorn main:app --worker-class trio -``` - -
- -Und das startet Hypercorn mit Ihrer Anwendung und verwendet Trio als Backend. - -Jetzt kÃļnnen Sie Trio intern in Ihrer Anwendung verwenden. Oder noch besser: Sie kÃļnnen AnyIO verwenden, sodass Ihr Code sowohl mit Trio als auch asyncio kompatibel ist. 🎉 - -## Konzepte des Deployments - -Obige Beispiele fÃŧhren das Serverprogramm (z. B. Uvicorn) aus, starten **einen einzelnen Prozess** und Ãŧberwachen alle IPs (`0.0.0.0`) an einem vordefinierten Port (z. B. `80`). +Diese Beispiele fÃŧhren das Serverprogramm (z. B. Uvicorn) aus, starten **einen einzelnen Prozess** und Ãŧberwachen alle IPs (`0.0.0.0`) an einem vordefinierten Port (z. B. `80`). Das ist die Grundidee. Aber Sie mÃļchten sich wahrscheinlich um einige zusätzliche Dinge kÃŧmmern, wie zum Beispiel: @@ -153,7 +151,7 @@ Das ist die Grundidee. Aber Sie mÃļchten sich wahrscheinlich um einige zusätzli * Beim Hochfahren ausfÃŧhren * Neustarts * Replikation (die Anzahl der laufenden Prozesse) -* Arbeitsspeicher +* Speicher * Schritte vor dem Start In den nächsten Kapiteln erzähle ich Ihnen mehr Ãŧber jedes dieser Konzepte, wie Sie Ãŧber diese nachdenken, und gebe Ihnen einige konkrete Beispiele mit Strategien fÃŧr den Umgang damit. 🚀 diff --git a/docs/de/docs/deployment/server-workers.md b/docs/de/docs/deployment/server-workers.md index 5cd282b4b..169ed822b 100644 --- a/docs/de/docs/deployment/server-workers.md +++ b/docs/de/docs/deployment/server-workers.md @@ -1,4 +1,4 @@ -# Serverworker – Gunicorn mit Uvicorn +# Serverworker – Uvicorn mit Workern { #server-workers-uvicorn-with-workers } Schauen wir uns die Deployment-Konzepte von frÃŧher noch einmal an: @@ -9,123 +9,79 @@ Schauen wir uns die Deployment-Konzepte von frÃŧher noch einmal an: * Arbeitsspeicher * Schritte vor dem Start -Bis zu diesem Punkt, in allen Tutorials in der Dokumentation, haben Sie wahrscheinlich ein **Serverprogramm** wie Uvicorn ausgefÃŧhrt, in einem **einzelnen Prozess**. +Bis zu diesem Punkt, in allen Tutorials in der Dokumentation, haben Sie wahrscheinlich ein **Serverprogramm** ausgefÃŧhrt, zum Beispiel mit dem `fastapi`-Befehl, der Uvicorn startet, und einen **einzelnen Prozess** ausfÃŧhrt. -Wenn Sie Anwendungen bereitstellen, mÃļchten Sie wahrscheinlich eine gewisse **Replikation von Prozessen**, um **mehrere CPU-Kerne** zu nutzen und mehr Requests bearbeiten zu kÃļnnen. +Wenn Sie Anwendungen bereitstellen, mÃļchten Sie wahrscheinlich eine gewisse **Replikation von Prozessen**, um **mehrere Kerne** zu nutzen und mehr Requests bearbeiten zu kÃļnnen. Wie Sie im vorherigen Kapitel Ãŧber [Deployment-Konzepte](concepts.md){.internal-link target=_blank} gesehen haben, gibt es mehrere Strategien, die Sie anwenden kÃļnnen. -Hier zeige ich Ihnen, wie Sie **Gunicorn** mit **Uvicorn Workerprozessen** verwenden. +Hier zeige ich Ihnen, wie Sie **Uvicorn** mit **Workerprozessen** verwenden, indem Sie den `fastapi`-Befehl oder den `uvicorn`-Befehl direkt verwenden. -/// info +/// info | Info Wenn Sie Container verwenden, beispielsweise mit Docker oder Kubernetes, erzähle ich Ihnen mehr darÃŧber im nächsten Kapitel: [FastAPI in Containern – Docker](docker.md){.internal-link target=_blank}. -Insbesondere wenn die Anwendung auf **Kubernetes** läuft, werden Sie Gunicorn wahrscheinlich **nicht** verwenden wollen und stattdessen **einen einzelnen Uvicorn-Prozess pro Container** ausfÃŧhren wollen, aber ich werde Ihnen später in diesem Kapitel mehr darÃŧber erzählen. +Insbesondere wenn die Anwendung auf **Kubernetes** läuft, werden Sie wahrscheinlich **keine** Worker verwenden wollen, und stattdessen **einen einzelnen Uvicorn-Prozess pro Container** ausfÃŧhren wollen, aber ich werde Ihnen später in diesem Kapitel mehr darÃŧber erzählen. /// -## Gunicorn mit Uvicorn-Workern +## Mehrere Worker { #multiple-workers } -**Gunicorn** ist hauptsächlich ein Anwendungsserver, der den **WSGI-Standard** verwendet. Das bedeutet, dass Gunicorn Anwendungen wie Flask und Django ausliefern kann. Gunicorn selbst ist nicht mit **FastAPI** kompatibel, da FastAPI den neuesten **ASGI-Standard** verwendet. +Sie kÃļnnen mehrere Worker mit der `--workers`-Befehlszeilenoption starten: -Aber Gunicorn kann als **Prozessmanager** arbeiten und Benutzer kÃļnnen ihm mitteilen, welche bestimmte **Workerprozessklasse** verwendet werden soll. Dann wÃŧrde Gunicorn einen oder mehrere **Workerprozesse** starten, diese Klasse verwendend. +//// tab | `fastapi` -Und **Uvicorn** hat eine **Gunicorn-kompatible Workerklasse**. - -Mit dieser Kombination wÃŧrde Gunicorn als **Prozessmanager** fungieren und den **Port** und die **IP** abhÃļren. Und er wÃŧrde die Kommunikation an die Workerprozesse **weiterleiten**, welche die **Uvicorn-Klasse** ausfÃŧhren. - -Und dann wäre die Gunicorn-kompatible **Uvicorn-Worker**-Klasse dafÃŧr verantwortlich, die von Gunicorn gesendeten Daten in den ASGI-Standard zu konvertieren, damit FastAPI diese verwenden kann. - -## Gunicorn und Uvicorn installieren +Wenn Sie den `fastapi`-Befehl verwenden:
```console -$ pip install "uvicorn[standard]" gunicorn +$ fastapi run --workers 4 main.py ----> 100% + FastAPI Starting production server 🚀 + + Searching for package file structure from directories with + __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with the + following code: + + from main import app + + app Using import string: main:app + + server Server started at http://0.0.0.0:8000 + server Documentation at http://0.0.0.0:8000/docs + + Logs: + + INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to + quit) + INFO Started parent process [27365] + INFO Started server process [27368] + INFO Started server process [27369] + INFO Started server process [27370] + INFO Started server process [27367] + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Application startup complete. + INFO Application startup complete. + INFO Application startup complete. + INFO Application startup complete. ```
-Dadurch wird sowohl Uvicorn mit zusätzlichen `standard`-Packages (um eine hohe Leistung zu erzielen) als auch Gunicorn installiert. +//// -## Gunicorn mit Uvicorn-Workern ausfÃŧhren +//// tab | `uvicorn` -Dann kÃļnnen Sie Gunicorn ausfÃŧhren mit: - -
- -```console -$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80 - -[19499] [INFO] Starting gunicorn 20.1.0 -[19499] [INFO] Listening at: http://0.0.0.0:80 (19499) -[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker -[19511] [INFO] Booting worker with pid: 19511 -[19513] [INFO] Booting worker with pid: 19513 -[19514] [INFO] Booting worker with pid: 19514 -[19515] [INFO] Booting worker with pid: 19515 -[19511] [INFO] Started server process [19511] -[19511] [INFO] Waiting for application startup. -[19511] [INFO] Application startup complete. -[19513] [INFO] Started server process [19513] -[19513] [INFO] Waiting for application startup. -[19513] [INFO] Application startup complete. -[19514] [INFO] Started server process [19514] -[19514] [INFO] Waiting for application startup. -[19514] [INFO] Application startup complete. -[19515] [INFO] Started server process [19515] -[19515] [INFO] Waiting for application startup. -[19515] [INFO] Application startup complete. -``` - -
- -Sehen wir uns an, was jede dieser Optionen bedeutet: - -* `main:app`: Das ist die gleiche Syntax, die auch von Uvicorn verwendet wird. `main` bedeutet das Python-Modul mit dem Namen `main`, also eine Datei `main.py`. Und `app` ist der Name der Variable, welche die **FastAPI**-Anwendung ist. - * Stellen Sie sich einfach vor, dass `main:app` einer Python-`import`-Anweisung wie der folgenden entspricht: - - ```Python - from main import app - ``` - - * Der Doppelpunkt in `main:app` entspricht also dem Python-`import`-Teil in `from main import app`. - -* `--workers`: Die Anzahl der zu verwendenden Workerprozesse, jeder fÃŧhrt einen Uvicorn-Worker aus, in diesem Fall 4 Worker. - -* `--worker-class`: Die Gunicorn-kompatible Workerklasse zur Verwendung in den Workerprozessen. - * Hier Ãŧbergeben wir die Klasse, die Gunicorn etwa so importiert und verwendet: - - ```Python - import uvicorn.workers.UvicornWorker - ``` - -* `--bind`: Das teilt Gunicorn die IP und den Port mit, welche abgehÃļrt werden sollen, wobei ein Doppelpunkt (`:`) verwendet wird, um die IP und den Port zu trennen. - * Wenn Sie Uvicorn direkt ausfÃŧhren wÃŧrden, wÃŧrden Sie anstelle von `--bind 0.0.0.0:80` (die Gunicorn-Option) stattdessen `--host 0.0.0.0` und `--port 80` verwenden. - -In der Ausgabe kÃļnnen Sie sehen, dass die **PID** (Prozess-ID) jedes Prozesses angezeigt wird (es ist nur eine Zahl). - -Sie kÃļnnen sehen, dass: - -* Der Gunicorn **Prozessmanager** beginnt, mit der PID `19499` (in Ihrem Fall ist es eine andere Nummer). -* Dann beginnt er zu lauschen: `Listening at: http://0.0.0.0:80`. -* Dann erkennt er, dass er die Workerklasse `uvicorn.workers.UvicornWorker` verwenden muss. -* Und dann werden **4 Worker** gestartet, jeder mit seiner eigenen PID: `19511`, `19513`, `19514` und `19515`. - -Gunicorn wÃŧrde sich bei Bedarf auch um die Verwaltung **beendeter Prozesse** und den **Neustart** von Prozessen kÃŧmmern, um die Anzahl der Worker aufrechtzuerhalten. Das hilft also teilweise beim **Neustarts**-Konzept aus der obigen Liste. - -Dennoch mÃļchten Sie wahrscheinlich auch etwas außerhalb haben, um sicherzustellen, dass Gunicorn bei Bedarf **neu gestartet wird**, und er auch **beim Hochfahren ausgefÃŧhrt wird**, usw. - -## Uvicorn mit Workern - -Uvicorn bietet ebenfalls die MÃļglichkeit, mehrere **Workerprozesse** zu starten und auszufÃŧhren. - -Dennoch sind die Fähigkeiten von Uvicorn zur Abwicklung von Workerprozessen derzeit eingeschränkter als die von Gunicorn. Wenn Sie also einen Prozessmanager auf dieser Ebene (auf der Python-Ebene) haben mÃļchten, ist es vermutlich besser, es mit Gunicorn als Prozessmanager zu versuchen. - -Wie auch immer, Sie wÃŧrden es so ausfÃŧhren: +Wenn Sie den `uvicorn`-Befehl direkt verwenden mÃļchten:
@@ -149,15 +105,17 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
+//// + Die einzige neue Option hier ist `--workers`, die Uvicorn anweist, 4 Workerprozesse zu starten. Sie kÃļnnen auch sehen, dass die **PID** jedes Prozesses angezeigt wird, `27365` fÃŧr den Ãŧbergeordneten Prozess (dies ist der **Prozessmanager**) und eine fÃŧr jeden Workerprozess: `27368`, `27369`, `27370` und `27367`. -## Deployment-Konzepte +## Deployment-Konzepte { #deployment-concepts } -Hier haben Sie gesehen, wie Sie mit **Gunicorn** (oder Uvicorn) **Uvicorn-Workerprozesse** verwalten, um die AusfÃŧhrung der Anwendung zu **parallelisieren**, **mehrere Kerne** der CPU zu nutzen und in der Lage zu sein, **mehr Requests** zu bedienen. +Hier haben Sie gesehen, wie Sie mehrere **Worker** verwenden, um die AusfÃŧhrung der Anwendung zu **parallelisieren**, **mehrere Kerne** der CPU zu nutzen und in der Lage zu sein, **mehr Requests** zu bearbeiten. -In der Liste der Deployment-Konzepte von oben wÃŧrde die Verwendung von Workern hauptsächlich beim **Replikation**-Teil und ein wenig bei **Neustarts** helfen, aber Sie mÃŧssen sich trotzdem um die anderen kÃŧmmern: +In der Liste der Deployment-Konzepte von oben wÃŧrde die Verwendung von Workern hauptsächlich bei der **Replikation** und ein wenig bei **Neustarts** helfen, aber Sie mÃŧssen sich trotzdem um die anderen kÃŧmmern: * **Sicherheit – HTTPS** * **Beim Hochfahren ausfÃŧhren** @@ -166,18 +124,16 @@ In der Liste der Deployment-Konzepte von oben wÃŧrde die Verwendung von Workern * **Arbeitsspeicher** * **Schritte vor dem Start** -## Container und Docker +## Container und Docker { #containers-and-docker } Im nächsten Kapitel Ãŧber [FastAPI in Containern – Docker](docker.md){.internal-link target=_blank} werde ich einige Strategien erläutern, die Sie fÃŧr den Umgang mit den anderen **Deployment-Konzepten** verwenden kÃļnnen. -Ich zeige Ihnen auch das **offizielle Docker-Image**, welches **Gunicorn mit Uvicorn-Workern** und einige Standardkonfigurationen enthält, die fÃŧr einfache Fälle nÃŧtzlich sein kÃļnnen. +Ich zeige Ihnen, wie Sie **Ihr eigenes Image von Grund auf erstellen**, um einen einzelnen Uvicorn-Prozess auszufÃŧhren. Es ist ein einfacher Vorgang und wahrscheinlich das, was Sie tun mÃļchten, wenn Sie ein verteiltes Containerverwaltungssystem wie **Kubernetes** verwenden. -Dort zeige ich Ihnen auch, wie Sie **Ihr eigenes Image von Grund auf erstellen**, um einen einzelnen Uvicorn-Prozess (ohne Gunicorn) auszufÃŧhren. Es ist ein einfacher Vorgang und wahrscheinlich das, was Sie tun mÃļchten, wenn Sie ein verteiltes Containerverwaltungssystem wie **Kubernetes** verwenden. +## Zusammenfassung { #recap } -## Zusammenfassung +Sie kÃļnnen mehrere Workerprozesse mit der `--workers`-CLI-Option Ãŧber die `fastapi`- oder `uvicorn`-Befehle nutzen, um **Multikern-CPUs** auszunutzen und **mehrere Prozesse parallel** auszufÃŧhren. -Sie kÃļnnen **Gunicorn** (oder auch Uvicorn) als Prozessmanager mit Uvicorn-Workern verwenden, um **Multikern-CPUs** zu nutzen und **mehrere Prozesse parallel** auszufÃŧhren. - -Sie kÃļnnen diese Tools und Ideen nutzen, wenn Sie **Ihr eigenes Deployment-System** einrichten und sich dabei selbst um die anderen Deployment-Konzepte kÃŧmmern. +Sie kÃļnnten diese Tools und Ideen nutzen, wenn Sie **Ihr eigenes Deployment-System** einrichten und sich dabei selbst um die anderen Deployment-Konzepte kÃŧmmern. Schauen Sie sich das nächste Kapitel an, um mehr Ãŧber **FastAPI** mit Containern (z. B. Docker und Kubernetes) zu erfahren. Sie werden sehen, dass diese Tools auch einfache MÃļglichkeiten bieten, die anderen **Deployment-Konzepte** zu lÃļsen. ✨ diff --git a/docs/de/docs/deployment/versions.md b/docs/de/docs/deployment/versions.md index 5b8c69754..d7ecb762e 100644 --- a/docs/de/docs/deployment/versions.md +++ b/docs/de/docs/deployment/versions.md @@ -1,4 +1,4 @@ -# Über FastAPI-Versionen +# Über FastAPI-Versionen { #about-fastapi-versions } **FastAPI** wird bereits in vielen Anwendungen und Systemen produktiv eingesetzt. Und die Testabdeckung wird bei 100 % gehalten. Aber seine Entwicklung geht immer noch schnell voran. @@ -8,35 +8,35 @@ Aus diesem Grund sind die aktuellen Versionen immer noch `0.x.x`, was darauf hin Sie kÃļnnen jetzt Produktionsanwendungen mit **FastAPI** erstellen (und das tun Sie wahrscheinlich schon seit einiger Zeit), Sie mÃŧssen nur sicherstellen, dass Sie eine Version verwenden, die korrekt mit dem Rest Ihres Codes funktioniert. -## `fastapi`-Version pinnen +## Ihre `fastapi`-Version pinnen { #pin-your-fastapi-version } Als Erstes sollten Sie die Version von **FastAPI**, die Sie verwenden, an die hÃļchste Version „pinnen“, von der Sie wissen, dass sie fÃŧr Ihre Anwendung korrekt funktioniert. -Angenommen, Sie verwenden in Ihrer Anwendung die Version `0.45.0`. +Angenommen, Sie verwenden in Ihrer App die Version `0.112.0`. Wenn Sie eine `requirements.txt`-Datei verwenden, kÃļnnen Sie die Version wie folgt angeben: ```txt -fastapi==0.45.0 +fastapi[standard]==0.112.0 ``` -Das wÃŧrde bedeuten, dass Sie genau die Version `0.45.0` verwenden. +Das wÃŧrde bedeuten, dass Sie genau die Version `0.112.0` verwenden. Oder Sie kÃļnnen sie auch anpinnen mit: ```txt -fastapi>=0.45.0,<0.46.0 +fastapi[standard]>=0.112.0,<0.113.0 ``` -Das wÃŧrde bedeuten, dass Sie eine Version `0.45.0` oder hÃļher verwenden wÃŧrden, aber kleiner als `0.46.0`, beispielsweise wÃŧrde eine Version `0.45.2` immer noch akzeptiert. +Das wÃŧrde bedeuten, dass Sie eine Version `0.112.0` oder hÃļher verwenden wÃŧrden, aber kleiner als `0.113.0`, beispielsweise wÃŧrde eine Version `0.112.2` immer noch akzeptiert. -Wenn Sie zum Verwalten Ihrer Installationen andere Tools wie Poetry, Pipenv oder andere verwenden, sie verfÃŧgen alle Ãŧber eine MÃļglichkeit, bestimmte Versionen fÃŧr Ihre Packages zu definieren. +Wenn Sie zum Verwalten Ihrer Installationen andere Tools wie `uv`, Poetry, Pipenv oder andere verwenden, sie verfÃŧgen alle Ãŧber eine MÃļglichkeit, bestimmte Versionen fÃŧr Ihre Packages zu definieren. -## VerfÃŧgbare Versionen +## VerfÃŧgbare Versionen { #available-versions } -Die verfÃŧgbaren Versionen kÃļnnen Sie in den [Release Notes](../release-notes.md){.internal-link target=_blank} einsehen (z. B. um zu ÃŧberprÃŧfen, welches die neueste Version ist). +Die verfÃŧgbaren Versionen kÃļnnen Sie in den [Versionshinweisen](../release-notes.md){.internal-link target=_blank} einsehen (z. B. um zu ÃŧberprÃŧfen, welches die neueste Version ist). -## Über Versionen +## Über Versionen { #about-versions } Gemäß den Konventionen zur semantischen Versionierung kÃļnnte jede Version unter `1.0.0` potenziell nicht abwärtskompatible Änderungen hinzufÃŧgen. @@ -62,9 +62,9 @@ Nicht abwärtskompatible Änderungen und neue Funktionen werden in „MINOR“-V /// -## Upgrade der FastAPI-Versionen +## Upgrade der FastAPI-Versionen { #upgrading-the-fastapi-versions } -Sie sollten Tests fÃŧr Ihre Anwendung hinzufÃŧgen. +Sie sollten Tests fÃŧr Ihre App hinzufÃŧgen. Mit **FastAPI** ist das sehr einfach (dank Starlette), schauen Sie sich die Dokumentation an: [Testen](../tutorial/testing.md){.internal-link target=_blank} @@ -72,7 +72,7 @@ Nachdem Sie Tests erstellt haben, kÃļnnen Sie die **FastAPI**-Version auf eine n Wenn alles funktioniert oder nachdem Sie die erforderlichen Änderungen vorgenommen haben und alle Ihre Tests bestehen, kÃļnnen Sie Ihr `fastapi` an die neue aktuelle Version pinnen. -## Über Starlette +## Über Starlette { #about-starlette } Sie sollten die Version von `starlette` nicht pinnen. @@ -80,13 +80,14 @@ Verschiedene Versionen von **FastAPI** verwenden eine bestimmte neuere Version v Sie kÃļnnen **FastAPI** also einfach die korrekte Starlette-Version verwenden lassen. -## Über Pydantic +## Über Pydantic { #about-pydantic } Pydantic integriert die Tests fÃŧr **FastAPI** in seine eigenen Tests, sodass neue Versionen von Pydantic (Ãŧber `1.0.0`) immer mit FastAPI kompatibel sind. -Sie kÃļnnen Pydantic an jede fÃŧr Sie geeignete Version Ãŧber `1.0.0` und unter `2.0.0` anpinnen. +Sie kÃļnnen Pydantic an jede fÃŧr Sie geeignete Version Ãŧber `1.0.0` anpinnen. Zum Beispiel: + ```txt -pydantic>=1.2.0,<2.0.0 +pydantic>=2.7.0,<3.0.0 ``` diff --git a/docs/de/docs/environment-variables.md b/docs/de/docs/environment-variables.md new file mode 100644 index 000000000..9d8c9f75c --- /dev/null +++ b/docs/de/docs/environment-variables.md @@ -0,0 +1,298 @@ +# Umgebungsvariablen { #environment-variables } + +/// tip | Tipp + +Wenn Sie bereits wissen, was „Umgebungsvariablen“ sind und wie man sie verwendet, kÃļnnen Sie dies Ãŧberspringen. + +/// + +Eine Umgebungsvariable (auch bekannt als „**env var**“) ist eine Variable, die **außerhalb** des Python-Codes im **Betriebssystem** lebt und von Ihrem Python-Code (oder auch von anderen Programmen) gelesen werden kann. + +Umgebungsvariablen kÃļnnen nÃŧtzlich sein, um **Einstellungen** der Anwendung zu handhaben, als Teil der **Installation** von Python usw. + +## Umgebungsvariablen erstellen und verwenden { #create-and-use-env-vars } + +Sie kÃļnnen Umgebungsvariablen in der **Shell (Terminal)** erstellen und verwenden, ohne Python zu benÃļtigen: + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +// Sie kÃļnnen eine Umgebungsvariable MY_NAME erstellen mit +$ export MY_NAME="Wade Wilson" + +// Dann kÃļnnen Sie sie mit anderen Programmen verwenden, etwa +$ echo "Hello $MY_NAME" + +Hello Wade Wilson +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +// Erstellen Sie eine Umgebungsvariable MY_NAME +$ $Env:MY_NAME = "Wade Wilson" + +// Verwenden Sie sie mit anderen Programmen, etwa +$ echo "Hello $Env:MY_NAME" + +Hello Wade Wilson +``` + +
+ +//// + +## Umgebungsvariablen in Python lesen { #read-env-vars-in-python } + +Sie kÃļnnen auch Umgebungsvariablen **außerhalb** von Python erstellen, im Terminal (oder mit jeder anderen Methode) und sie dann **in Python** lesen. + +Zum Beispiel kÃļnnten Sie eine Datei `main.py` haben mit: + +```Python hl_lines="3" +import os + +name = os.getenv("MY_NAME", "World") +print(f"Hello {name} from Python") +``` + +/// tip | Tipp + +Das zweite Argument von `os.getenv()` ist der Defaultwert, der zurÃŧckgegeben wird. + +Wenn er nicht angegeben wird, ist er standardmäßig `None`. Hier geben wir `"World"` als den zu verwendenden Defaultwert an. + +/// + +Dann kÃļnnten Sie das Python-Programm aufrufen: + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +// Hier setzen wir die Umgebungsvariable noch nicht +$ python main.py + +// Da wir die Umgebungsvariable nicht gesetzt haben, erhalten wir den Defaultwert + +Hello World from Python + +// Aber wenn wir zuerst eine Umgebungsvariable erstellen +$ export MY_NAME="Wade Wilson" + +// Und dann das Programm erneut aufrufen +$ python main.py + +// Jetzt kann es die Umgebungsvariable lesen + +Hello Wade Wilson from Python +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +// Hier setzen wir die Umgebungsvariable noch nicht +$ python main.py + +// Da wir die Umgebungsvariable nicht gesetzt haben, erhalten wir den Defaultwert + +Hello World from Python + +// Aber wenn wir zuerst eine Umgebungsvariable erstellen +$ $Env:MY_NAME = "Wade Wilson" + +// Und dann das Programm erneut aufrufen +$ python main.py + +// Jetzt kann es die Umgebungsvariable lesen + +Hello Wade Wilson from Python +``` + +
+ +//// + +Da Umgebungsvariablen außerhalb des Codes gesetzt werden kÃļnnen, aber vom Code gelesen werden kÃļnnen und nicht mit den restlichen Dateien gespeichert (in `git` committet) werden mÃŧssen, werden sie häufig fÃŧr Konfigurationen oder **Einstellungen** verwendet. + +Sie kÃļnnen auch eine Umgebungsvariable nur fÃŧr einen **spezifischen Programmaufruf** erstellen, die nur fÃŧr dieses Programm und nur fÃŧr dessen Dauer verfÃŧgbar ist. + +Um dies zu tun, erstellen Sie sie direkt vor dem Programmaufruf, in derselben Zeile: + +
+ +```console +// Erstellen Sie eine Umgebungsvariable MY_NAME in der Zeile fÃŧr diesen Programmaufruf +$ MY_NAME="Wade Wilson" python main.py + +// Jetzt kann es die Umgebungsvariable lesen + +Hello Wade Wilson from Python + +// Die Umgebungsvariable existiert danach nicht mehr +$ python main.py + +Hello World from Python +``` + +
+ +/// tip | Tipp + +Sie kÃļnnen mehr darÃŧber lesen auf The Twelve-Factor App: Config. + +/// + +## Typen und Validierung { #types-and-validation } + +Diese Umgebungsvariablen kÃļnnen nur **Textstrings** handhaben, da sie extern zu Python sind und kompatibel mit anderen Programmen und dem Rest des Systems (und sogar mit verschiedenen Betriebssystemen, wie Linux, Windows, macOS) sein mÃŧssen. + +Das bedeutet, dass **jeder Wert**, der in Python von einer Umgebungsvariable gelesen wird, **ein `str` sein wird**, und jede Konvertierung in einen anderen Typ oder jede Validierung muss im Code vorgenommen werden. + +Sie werden mehr darÃŧber lernen, wie man Umgebungsvariablen zur Handhabung von **Anwendungseinstellungen** verwendet, im [Handbuch fÃŧr fortgeschrittene Benutzer – Einstellungen und Umgebungsvariablen](./advanced/settings.md){.internal-link target=_blank}. + +## `PATH`-Umgebungsvariable { #path-environment-variable } + +Es gibt eine **spezielle** Umgebungsvariable namens **`PATH`**, die von den Betriebssystemen (Linux, macOS, Windows) verwendet wird, um Programme zu finden, die ausgefÃŧhrt werden sollen. + +Der Wert der Variable `PATH` ist ein langer String, der aus Verzeichnissen besteht, die auf Linux und macOS durch einen Doppelpunkt `:` und auf Windows durch ein Semikolon `;` getrennt sind. + +Zum Beispiel kÃļnnte die `PATH`-Umgebungsvariable so aussehen: + +//// tab | Linux, macOS + +```plaintext +/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin +``` + +Das bedeutet, dass das System nach Programmen in den Verzeichnissen suchen sollte: + +* `/usr/local/bin` +* `/usr/bin` +* `/bin` +* `/usr/sbin` +* `/sbin` + +//// + +//// tab | Windows + +```plaintext +C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 +``` + +Das bedeutet, dass das System nach Programmen in den Verzeichnissen suchen sollte: + +* `C:\Program Files\Python312\Scripts` +* `C:\Program Files\Python312` +* `C:\Windows\System32` + +//// + +Wenn Sie einen **Befehl** im Terminal eingeben, **sucht** das Betriebssystem nach dem Programm in **jedem dieser Verzeichnisse**, die in der `PATH`-Umgebungsvariablen aufgefÃŧhrt sind. + +Zum Beispiel, wenn Sie `python` im Terminal eingeben, sucht das Betriebssystem nach einem Programm namens `python` im **ersten Verzeichnis** in dieser Liste. + +Wenn es es findet, wird es **benutzt**. Andernfalls sucht es weiter in den **anderen Verzeichnissen**. + +### Python installieren und den `PATH` aktualisieren { #installing-python-and-updating-the-path } + +Wenn Sie Python installieren, kÃļnnten Sie gefragt werden, ob Sie die `PATH`-Umgebungsvariable aktualisieren mÃļchten. + +//// tab | Linux, macOS + +Angenommen, Sie installieren Python und es landet in einem Verzeichnis `/opt/custompython/bin`. + +Wenn Sie erlauben, die `PATH`-Umgebungsvariable zu aktualisieren, fÃŧgt der Installer `/opt/custompython/bin` zur `PATH`-Umgebungsvariable hinzu. + +Das kÃļnnte so aussehen: + +```plaintext +/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin +``` + +Auf diese Weise, wenn Sie `python` im Terminal eingeben, findet das System das Python-Programm in `/opt/custompython/bin` (das letzte Verzeichnis) und verwendet dieses. + +//// + +//// tab | Windows + +Angenommen, Sie installieren Python und es landet in einem Verzeichnis `C:\opt\custompython\bin`. + +Wenn Sie erlauben, die `PATH`-Umgebungsvariable zu aktualisieren, fÃŧgt der Installer `C:\opt\custompython\bin` zur `PATH`-Umgebungsvariable hinzu. + +```plaintext +C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin +``` + +Auf diese Weise, wenn Sie `python` im Terminal eingeben, findet das System das Python-Programm in `C:\opt\custompython\bin` (das letzte Verzeichnis) und verwendet dieses. + +//// + +Also, wenn Sie tippen: + +
+ +```console +$ python +``` + +
+ +//// tab | Linux, macOS + +Das System wird das `python` Programm in `/opt/custompython/bin` **finden** und es ausfÃŧhren. + +Es wäre ungefähr gleichbedeutend mit der Eingabe von: + +
+ +```console +$ /opt/custompython/bin/python +``` + +
+ +//// + +//// tab | Windows + +Das System wird das `python` Programm in `C:\opt\custompython\bin\python` **finden** und es ausfÃŧhren. + +Es wäre ungefähr gleichbedeutend mit der Eingabe von: + +
+ +```console +$ C:\opt\custompython\bin\python +``` + +
+ +//// + +Diese Informationen werden nÃŧtzlich sein, wenn Sie Ãŧber [Virtuelle Umgebungen](virtual-environments.md){.internal-link target=_blank} lernen. + +## Fazit { #conclusion } + +Mit diesem Wissen sollten Sie ein grundlegendes Verständnis davon haben, was **Umgebungsvariablen** sind und wie man sie in Python verwendet. + +Sie kÃļnnen auch mehr darÃŧber in der Wikipedia zu Umgebungsvariablen lesen. + +In vielen Fällen ist es nicht sehr offensichtlich, wie Umgebungsvariablen nÃŧtzlich und sofort anwendbar sein kÃļnnten. Aber sie tauchen immer wieder in vielen verschiedenen Szenarien auf, wenn Sie entwickeln, deshalb ist es gut, darÃŧber Bescheid zu wissen. + +Zum Beispiel werden Sie diese Informationen im nächsten Abschnitt Ãŧber [Virtuelle Umgebungen](virtual-environments.md) benÃļtigen. diff --git a/docs/de/docs/fastapi-cli.md b/docs/de/docs/fastapi-cli.md new file mode 100644 index 000000000..d41ed598e --- /dev/null +++ b/docs/de/docs/fastapi-cli.md @@ -0,0 +1,75 @@ +# FastAPI CLI { #fastapi-cli } + +**FastAPI CLI** ist ein Kommandozeilenprogramm, mit dem Sie Ihre FastAPI-App bereitstellen, Ihr FastAPI-Projekt verwalten und mehr. + +Wenn Sie FastAPI installieren (z. B. mit `pip install "fastapi[standard]"`), wird ein Package namens `fastapi-cli` mitgeliefert, das den Befehl `fastapi` im Terminal bereitstellt. + +Um Ihre FastAPI-App fÃŧr die Entwicklung auszufÃŧhren, kÃļnnen Sie den Befehl `fastapi dev` verwenden: + +
+ +```console +$ fastapi dev main.py + + FastAPI Starting development server 🚀 + + Searching for package file structure from directories with + __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with the + following code: + + from main import app + + app Using import string: main:app + + server Server started at http://127.0.0.1:8000 + server Documentation at http://127.0.0.1:8000/docs + + tip Running in development mode, for production use: + fastapi run + + Logs: + + INFO Will watch for changes in these directories: + ['/home/user/code/awesomeapp'] + INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to + quit) + INFO Started reloader process [383138] using WatchFiles + INFO Started server process [383153] + INFO Waiting for application startup. + INFO Application startup complete. +``` + +
+ +Das Kommandozeilenprogramm namens `fastapi` ist das **FastAPI CLI**. + +FastAPI CLI nimmt den Pfad zu Ihrem Python-Programm (z. B. `main.py`), erkennt automatisch die `FastAPI`-Instanz (häufig `app` genannt), bestimmt den korrekten Importprozess und stellt sie dann bereit. + +FÃŧr die Produktion wÃŧrden Sie stattdessen `fastapi run` verwenden. 🚀 + +Intern verwendet das **FastAPI CLI** Uvicorn, einen leistungsstarken, produktionsreifen, ASGI-Server. 😎 + +## `fastapi dev` { #fastapi-dev } + +Das AusfÃŧhren von `fastapi dev` startet den Entwicklermodus. + +Standardmäßig ist **Autoreload** aktiviert, das den Server automatisch neu lädt, wenn Sie Änderungen an Ihrem Code vornehmen. Dies ist ressourcenintensiv und kÃļnnte weniger stabil sein als wenn es deaktiviert ist. Sie sollten es nur fÃŧr die Entwicklung verwenden. Es horcht auch auf der IP-Adresse `127.0.0.1`, die die IP fÃŧr Ihre Maschine ist, um nur mit sich selbst zu kommunizieren (`localhost`). + +## `fastapi run` { #fastapi-run } + +Das AusfÃŧhren von `fastapi run` startet FastAPI standardmäßig im Produktionsmodus. + +Standardmäßig ist **Autoreload** deaktiviert. Es horcht auch auf der IP-Adresse `0.0.0.0`, was alle verfÃŧgbaren IP-Adressen bedeutet, so wird es Ãļffentlich zugänglich fÃŧr jeden, der mit der Maschine kommunizieren kann. So wÃŧrden Sie es normalerweise in der Produktion ausfÃŧhren, beispielsweise in einem Container. + +In den meisten Fällen wÃŧrden (und sollten) Sie einen „Terminierungsproxy“ haben, der HTTPS fÃŧr Sie verwaltet. Dies hängt davon ab, wie Sie Ihre Anwendung bereitstellen. Ihr Anbieter kÃļnnte dies fÃŧr Sie erledigen, oder Sie mÃŧssen es selbst einrichten. + +/// tip | Tipp + +Sie kÃļnnen mehr darÃŧber in der [Deployment-Dokumentation](deployment/index.md){.internal-link target=_blank} erfahren. + +/// diff --git a/docs/de/docs/features.md b/docs/de/docs/features.md index 8fdf42622..c52f6733e 100644 --- a/docs/de/docs/features.md +++ b/docs/de/docs/features.md @@ -1,21 +1,21 @@ -# Merkmale +# Merkmale { #features } -## FastAPI Merkmale +## FastAPI Merkmale { #fastapi-features } **FastAPI** ermÃļglicht Ihnen Folgendes: -### Basiert auf offenen Standards +### Basiert auf offenen Standards { #based-on-open-standards } -* OpenAPI fÃŧr die Erstellung von APIs, inklusive Deklarationen von Pfad-Operationen, Parametern, Requestbodys, Sicherheit, usw. +* OpenAPI fÃŧr die Erstellung von APIs, inklusive Deklarationen von Pfad-Operationen, Parametern, Requestbodys, Sicherheit, usw. * Automatische Dokumentation der Datenmodelle mit JSON Schema (da OpenAPI selbst auf JSON Schema basiert). * Um diese Standards herum entworfen, nach sorgfältigem Studium. Statt einer nachträglichen Schicht darÃŧber. * Dies ermÃļglicht auch automatische **Client-Code-Generierung** in vielen Sprachen. -### Automatische Dokumentation +### Automatische Dokumentation { #automatic-docs } Interaktive API-Dokumentation und erkundbare Web-Benutzeroberflächen. Da das Framework auf OpenAPI basiert, gibt es mehrere Optionen, zwei sind standardmäßig vorhanden. -* Swagger UI, bietet interaktive Erkundung, testen und rufen Sie ihre API direkt im Webbrowser auf. +* Swagger UI, bietet interaktive Erkundung, testen und rufen Sie Ihre API direkt im Webbrowser auf. ![Swagger UI Interaktion](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) @@ -23,22 +23,21 @@ Interaktive API-Dokumentation und erkundbare Web-Benutzeroberflächen. Da das Fr ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### Nur modernes Python +### Nur modernes Python { #just-modern-python } -Alles basiert auf **Python 3.8 Typ**-Deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden, nur standardisiertes modernes Python. +Alles basiert auf Standard-**Python-Typ**deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden, nur standardisiertes modernes Python. Wenn Sie eine zweiminÃŧtige Auffrischung benÃļtigen, wie man Python-Typen verwendet (auch wenn Sie FastAPI nicht benutzen), schauen Sie sich das kurze Tutorial an: [EinfÃŧhrung in Python-Typen](python-types.md){.internal-link target=_blank}. Sie schreiben Standard-Python mit Typen: ```Python -from typing import List, Dict from datetime import date from pydantic import BaseModel -# Deklarieren Sie eine Variable als ein `str` -# und bekommen Sie Editor-UnterstÃŧtung innerhalb der Funktion +# Deklarieren Sie eine Variable als ein str +# und bekommen Sie Editor-UnterstÃŧtzung innerhalb der Funktion def main(user_id: str): return user_id @@ -64,25 +63,25 @@ second_user_data = { my_second_user: User = User(**second_user_data) ``` -/// info +/// info | Info `**second_user_data` bedeutet: -Nimm die SchlÃŧssel-Wert-Paare des `second_user_data` Dicts und Ãŧbergib sie direkt als SchlÃŧsselwort-Argumente. Äquivalent zu: `User(id=4, name="Mary", joined="2018-11-30")`. +Nimm die SchlÃŧssel-Wert-Paare des `second_user_data` Dicts und Ãŧbergebe sie direkt als SchlÃŧsselwort-Argumente. Äquivalent zu: `User(id=4, name="Mary", joined="2018-11-30")` /// -### Editor UnterstÃŧtzung +### Editor UnterstÃŧtzung { #editor-support } Das ganze Framework wurde so entworfen, dass es einfach und intuitiv zu benutzen ist; alle Entscheidungen wurden auf mehreren Editoren getestet, sogar vor der Implementierung, um die bestmÃļgliche Entwicklererfahrung zu gewährleisten. -In der letzten Python-Entwickler-Umfrage wurde klar, dass die meist genutzte Funktion die „Autovervollständigung“ ist. +In den Python-Entwickler-Umfragen wird klar, dass die meist genutzte Funktion die „Autovervollständigung“ ist. Das gesamte **FastAPI**-Framework ist darauf ausgelegt, das zu erfÃŧllen. Autovervollständigung funktioniert Ãŧberall. Sie werden selten noch mal in der Dokumentation nachschauen mÃŧssen. -So kann ihr Editor Sie unterstÃŧtzen: +So kann Ihr Editor Sie unterstÃŧtzen: * in Visual Studio Code: @@ -92,23 +91,23 @@ So kann ihr Editor Sie unterstÃŧtzen: ![Editor UnterstÃŧtzung](https://fastapi.tiangolo.com/img/pycharm-completion.png) -Sie bekommen sogar Autovervollständigung an Stellen, an denen Sie dies vorher nicht fÃŧr mÃļglich gehalten hätten. Zum Beispiel der `price` SchlÃŧssel in einem JSON Datensatz (dieser kÃļnnte auch verschachtelt sein), der aus einer Anfrage kommt. +Sie bekommen sogar Autovervollständigung an Stellen, an denen Sie dies vorher nicht fÃŧr mÃļglich gehalten hätten. Zum Beispiel der `price` SchlÃŧssel in einem JSON Datensatz (dieser kÃļnnte auch verschachtelt sein), der aus einem Request kommt. Nie wieder falsche SchlÃŧsselnamen tippen, Hin und HerhÃŧpfen zwischen der Dokumentation, Hoch- und Runterscrollen, um herauszufinden, ob es `username` oder `user_name` war. -### Kompakt +### Kompakt { #short } Es gibt fÃŧr alles sensible **Defaultwerte**, mit optionaler Konfiguration Ãŧberall. Alle Parameter kÃļnnen feinjustiert werden, damit sie tun, was Sie benÃļtigen, und die API definieren, die Sie brauchen. Aber standardmäßig **„funktioniert einfach alles“**. -### Validierung +### Validierung { #validation } * Validierung fÃŧr die meisten (oder alle?) Python-**Datentypen**, hierzu gehÃļren: * JSON Objekte (`dict`). * JSON Listen (`list`), die den Typ ihrer Elemente definieren. * Strings (`str`) mit definierter minimaler und maximaler Länge. - * Zahlen (`int`, `float`) mit Mindest- und Maximal-Werten, usw. + * Zahlen (`int`, `float`) mit Mindest- und Maximalwerten, usw. * Validierung fÃŧr mehr exotische Typen, wie: * URL. @@ -118,47 +117,47 @@ Aber standardmäßig **„funktioniert einfach alles“**. Die gesamte Validierung Ãŧbernimmt das gut etablierte und robuste **Pydantic**. -### Sicherheit und Authentifizierung +### Sicherheit und Authentifizierung { #security-and-authentication } -Sicherheit und Authentifizierung ist integriert. Ohne Kompromisse bei Datenbanken oder Datenmodellen. +Sicherheit und Authentifizierung sind integriert. Ohne Kompromisse bei Datenbanken oder Datenmodellen. Alle in OpenAPI definierten Sicherheitsschemas, inklusive: -* HTTP Basic Authentifizierung. +* HTTP Basic. * **OAuth2** (auch mit **JWT Tokens**). Siehe dazu das Tutorial zu [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. * API SchlÃŧssel in: - * Header-Feldern. - * Anfrageparametern. + * Headern. + * Query-Parametern. * Cookies, usw. Zusätzlich alle Sicherheitsfunktionen von Starlette (inklusive **Session Cookies**). -Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in ihre Systeme, Datenspeicher, relationalen und nicht-relationalen Datenbanken, usw., integriert werden kÃļnnen. +Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in Ihre Systeme, Datenspeicher, relationale und nicht-relationale Datenbanken, usw., integriert werden kÃļnnen. -### Einbringen von Abhängigkeiten (Dependency Injection) +### Dependency Injection { #dependency-injection } -FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges Dependency Injection System. +FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges Dependency Injection System. * Selbst Abhängigkeiten kÃļnnen Abhängigkeiten haben, woraus eine Hierarchie oder ein **„Graph“ von Abhängigkeiten** entsteht. * Alles **automatisch gehandhabt** durch das Framework. -* Alle Abhängigkeiten kÃļnnen Daten von Anfragen anfordern und das Verhalten von **Pfadoperationen** und der automatisierten Dokumentation **modifizieren**. +* Alle Abhängigkeiten kÃļnnen Daten von Requests anfordern und das Verhalten von **Pfadoperationen** und der automatisierten Dokumentation **modifizieren**. * **Automatische Validierung** selbst fÃŧr solche Parameter von *Pfadoperationen*, welche in Abhängigkeiten definiert sind. * UnterstÃŧtzung fÃŧr komplexe Authentifizierungssysteme, **Datenbankverbindungen**, usw. * **Keine Kompromisse** bei Datenbanken, Frontends, usw., sondern einfache Integration mit allen. -### Unbegrenzte Erweiterungen +### Unbegrenzte Erweiterungen { #unlimited-plug-ins } Oder mit anderen Worten, sie werden nicht benÃļtigt. Importieren und nutzen Sie den Code, den Sie brauchen. Jede Integration wurde so entworfen, dass sie so einfach zu nutzen ist (mit Abhängigkeiten), dass Sie eine Erweiterung fÃŧr Ihre Anwendung mit nur zwei Zeilen Code erstellen kÃļnnen. Hierbei nutzen Sie die gleiche Struktur und Syntax, wie bei *Pfadoperationen*. -### Getestet +### Getestet { #tested } * 100 % Testabdeckung. -* 100 % Typen annotiert. +* 100 % Typen annotiert. * Verwendet in Produktionsanwendungen. -## Starlette's Merkmale +## Starlette Merkmale { #starlette-features } **FastAPI** ist vollkommen kompatibel (und basiert auf) Starlette. Das bedeutet, wenn Sie eigenen Starlette Quellcode haben, funktioniert der. @@ -168,31 +167,31 @@ Mit **FastAPI** bekommen Sie alles von **Starlette** (da FastAPI nur Starlette a * Schwer beeindruckende Performanz. Es ist eines der schnellsten Python-Frameworks, auf AugenhÃļhe mit **NodeJS** und **Go**. * **WebSocket**-UnterstÃŧtzung. -* Hintergrundaufgaben im selben Prozess. -* Ereignisse beim Starten und Herunterfahren. -* Testclient baut auf HTTPX auf. +* Hintergrundtasks im selben Prozess. +* Startup- und Shutdown-Events. +* Testclient basierend auf HTTPX. * **CORS**, GZip, statische Dateien, Responses streamen. * **Sitzungs- und Cookie**-UnterstÃŧtzung. * 100 % Testabdeckung. * 100 % Typen annotierte Codebasis. -## Pydantic's Merkmale +## Pydantic Merkmale { #pydantic-features } **FastAPI** ist vollkommen kompatibel (und basiert auf) Pydantic. Das bedeutet, wenn Sie eigenen Pydantic Quellcode haben, funktioniert der. -Inklusive externer Bibliotheken, die auf Pydantic basieren, wie ORMs, ODMs fÃŧr Datenbanken. +Inklusive externer Bibliotheken, die auf Pydantic basieren, wie ORMs, ODMs fÃŧr Datenbanken. -Daher kÃļnnen Sie in vielen Fällen das Objekt einer Anfrage **direkt zur Datenbank** schicken, weil alles automatisch validiert wird. +Daher kÃļnnen Sie in vielen Fällen das Objekt eines Requests **direkt zur Datenbank** schicken, weil alles automatisch validiert wird. -Das gleiche gilt auch fÃŧr die andere Richtung: Sie kÃļnnen in vielen Fällen das Objekt aus der Datenbank **direkt zum Client** schicken. +Das gleiche gilt auch fÃŧr die andere Richtung: Sie kÃļnnen in vielen Fällen das Objekt aus der Datenbank **direkt zum Client** senden. Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI fÃŧr die gesamte Datenverarbeitung Pydantic nutzt): * **Kein Kopfzerbrechen**: * Keine neue Schemadefinition-Mikrosprache zu lernen. * Wenn Sie Pythons Typen kennen, wissen Sie, wie man Pydantic verwendet. -* Gutes Zusammenspiel mit Ihrer/Ihrem **IDE/Linter/Gehirn**: - * Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und ihre Intuition sollten alle einwandfrei mit ihren validierten Daten funktionieren. +* Gutes Zusammenspiel mit Ihrer/Ihrem **IDE/Linter/Gehirn**: + * Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und Ihre Intuition sollten alle einwandfrei mit Ihren validierten Daten funktionieren. * Validierung von **komplexen Strukturen**: * Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, etc. * Die Validierer erlauben es, komplexe Datenschemen klar und einfach zu definieren, ÃŧberprÃŧft und dokumentiert als JSON Schema. diff --git a/docs/de/docs/help-fastapi.md b/docs/de/docs/help-fastapi.md index 0b9c52316..6cbafca0b 100644 --- a/docs/de/docs/help-fastapi.md +++ b/docs/de/docs/help-fastapi.md @@ -1,74 +1,75 @@ -# FastAPI helfen – Hilfe erhalten +# FastAPI helfen – Hilfe erhalten { #help-fastapi-get-help } -Gefällt Ihnen **FastAPI**? +MÃļgen Sie **FastAPI**? MÃļchten Sie FastAPI, anderen Benutzern und dem Autor helfen? Oder mÃļchten Sie Hilfe zu **FastAPI** erhalten? -Es gibt sehr einfache MÃļglichkeiten zu helfen (manche erfordern nur ein oder zwei Klicks). +Es gibt sehr einfache MÃļglichkeiten zu helfen (einige erfordern nur ein oder zwei Klicks). -Und es gibt auch viele MÃļglichkeiten, Hilfe zu bekommen. +Und es gibt auch mehrere MÃļglichkeiten, Hilfe zu bekommen. -## Newsletter abonnieren +## Newsletter abonnieren { #subscribe-to-the-newsletter } -Sie kÃļnnen den (unregelmäßig erscheinenden) [**FastAPI and Friends**-Newsletter](newsletter.md){.internal-link target=_blank} abonnieren, um auf dem Laufenden zu bleiben: +Sie kÃļnnen den (unregelmäßigen) [**FastAPI and friends**-Newsletter](newsletter.md){.internal-link target=_blank} abonnieren, um Ãŧber folgende Themen informiert zu bleiben: -* Neuigkeiten Ãŧber FastAPI and Friends 🚀 +* Neuigkeiten Ãŧber FastAPI und Freunde 🚀 * Anleitungen 📝 * Funktionen ✨ * Breaking Changes 🚨 * Tipps und Tricks ✅ -## FastAPI auf Twitter folgen -Folgen Sie @fastapi auf **Twitter**, um die neuesten Nachrichten Ãŧber **FastAPI** zu erhalten. đŸĻ +## FastAPI auf X (Twitter) folgen { #follow-fastapi-on-x-twitter } -## **FastAPI** auf GitHub einen Stern geben +Folgen Sie @fastapi auf **X (Twitter)**, um die neuesten Nachrichten Ãŧber **FastAPI** zu erhalten. đŸĻ -Sie kÃļnnen FastAPI auf GitHub „starren“ (durch Klicken auf den Stern-Button oben rechts): https://github.com/fastapi/fastapi. â­ī¸ +## **FastAPI** auf GitHub einen Stern geben { #star-fastapi-in-github } + +Sie kÃļnnen FastAPI auf GitHub „starren“ (klicken Sie auf den Stern-Button oben rechts): https://github.com/fastapi/fastapi. â­ī¸ Durch das HinzufÃŧgen eines Sterns kÃļnnen andere Benutzer es leichter finden und sehen, dass es fÃŧr andere bereits nÃŧtzlich war. -## Das GitHub-Repository auf Releases beobachten +## Das GitHub-Repository auf Releases Ãŧberwachen { #watch-the-github-repository-for-releases } -Sie kÃļnnen FastAPI in GitHub beobachten (Klicken Sie oben rechts auf den Button „watch“): https://github.com/fastapi/fastapi. 👀 +Sie kÃļnnen FastAPI auf GitHub „beobachten“ (klicken Sie auf den „watch“-Button oben rechts): https://github.com/fastapi/fastapi. 👀 Dort kÃļnnen Sie „Releases only“ auswählen. -Auf diese Weise erhalten Sie Benachrichtigungen (per E-Mail), wenn es einen neuen Release (eine neue Version) von **FastAPI** mit Fehlerbehebungen und neuen Funktionen gibt. +Auf diese Weise erhalten Sie Benachrichtigungen (per E-Mail), wenn es ein neues Release (eine neue Version) von **FastAPI** mit Bugfixes und neuen Funktionen gibt. -## Mit dem Autor vernetzen +## Mit dem Autor vernetzen { #connect-with-the-author } -Sie kÃļnnen sich mit mir (SebastiÃĄn Ramírez / `tiangolo`), dem Autor, verbinden. +Sie kÃļnnen sich mit mir (SebastiÃĄn Ramírez / `tiangolo`), dem Autor, vernetzen. -Insbesondere: +Sie kÃļnnen: -* Folgen Sie mir auf **GitHub**. - * Finden Sie andere Open-Source-Projekte, die ich erstellt habe und die Ihnen helfen kÃļnnten. - * Folgen Sie mir, um mitzubekommen, wenn ich ein neues Open-Source-Projekt erstelle. -* Folgen Sie mir auf **Twitter** oder Mastodon. - * Berichten Sie mir, wie Sie FastAPI verwenden (das hÃļre ich gerne). - * Bekommen Sie mit, wenn ich AnkÃŧndigungen mache oder neue Tools verÃļffentliche. - * Sie kÃļnnen auch @fastapi auf Twitter folgen (ein separates Konto). -* Folgen Sie mir auf **LinkedIn**. - * Bekommen Sie mit, wenn ich AnkÃŧndigungen mache oder neue Tools verÃļffentliche (obwohl ich Twitter häufiger verwende 🤷‍♂). -* Lesen Sie, was ich schreibe (oder folgen Sie mir) auf **Dev.to** oder **Medium**. - * Lesen Sie andere Ideen, Artikel, und erfahren Sie mehr Ãŧber die von mir erstellten Tools. - * Folgen Sie mir, um zu lesen, wenn ich etwas Neues verÃļffentliche. +* Mir auf **GitHub** folgen. + * Andere Open-Source-Projekte sehen, die ich erstellt habe und die Ihnen helfen kÃļnnten. + * Mir folgen, um zu sehen, wenn ich ein neues Open-Source-Projekt erstelle. +* Mir auf **X (Twitter)** folgen oder Mastodon. + * Mir mitteilen, wie Sie FastAPI verwenden (ich hÃļre das gerne). + * Mitbekommen, wenn ich AnkÃŧndigungen mache oder neue Tools verÃļffentliche. + * Sie kÃļnnen auch @fastapi auf X (Twitter) folgen (ein separates Konto). +* Mir auf **LinkedIn** folgen. + * Mitbekommen, wenn ich AnkÃŧndigungen mache oder neue Tools verÃļffentliche (obwohl ich X (Twitter) häufiger verwende 🤷‍♂). +* Lesen, was ich schreibe (oder mir folgen) auf **Dev.to** oder **Medium**. + * Andere Ideen, Artikel lesen und mehr Ãŧber die von mir erstellten Tools erfahren. + * Mir folgen, um zu lesen, wenn ich etwas Neues verÃļffentliche. -## Über **FastAPI** tweeten +## Über **FastAPI** tweeten { #tweet-about-fastapi } -Tweeten Sie Ãŧber **FastAPI** und teilen Sie mir und anderen mit, warum es Ihnen gefällt. 🎉 +Tweeten Sie Ãŧber **FastAPI** und teilen Sie mir und anderen mit, warum es Ihnen gefällt. 🎉 Ich hÃļre gerne, wie **FastAPI** verwendet wird, was Ihnen daran gefallen hat, in welchem Projekt/Unternehmen Sie es verwenden, usw. -## FÃŧr FastAPI abstimmen +## FÃŧr FastAPI abstimmen { #vote-for-fastapi } -* Stimmen Sie fÃŧr **FastAPI** auf Slant. +* Stimmen Sie fÃŧr **FastAPI** auf Slant. * Stimmen Sie fÃŧr **FastAPI** auf AlternativeTo. -* Berichten Sie auf StackShare, dass Sie **FastAPI** verwenden. +* Sagen Sie auf StackShare, dass Sie **FastAPI** verwenden. -## Anderen bei Fragen auf GitHub helfen +## Anderen bei Fragen auf GitHub helfen { #help-others-with-questions-in-github } Sie kÃļnnen versuchen, anderen bei ihren Fragen zu helfen: @@ -77,19 +78,19 @@ Sie kÃļnnen versuchen, anderen bei ihren Fragen zu helfen: In vielen Fällen kennen Sie mÃļglicherweise bereits die Antwort auf diese Fragen. 🤓 -Wenn Sie vielen Menschen bei ihren Fragen helfen, werden Sie offizieller [FastAPI-Experte](fastapi-people.md#experten){.internal-link target=_blank}. 🎉 +Wenn Sie vielen Menschen bei ihren Fragen helfen, werden Sie offizieller [FastAPI-Experte](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. 🎉 -Denken Sie aber daran, der wichtigste Punkt ist: Versuchen Sie, freundlich zu sein. Die Leute bringen ihre Frustrationen mit und fragen in vielen Fällen nicht auf die beste Art und Weise, aber versuchen Sie dennoch so gut wie mÃļglich, freundlich zu sein. 🤗 +Denken Sie daran, der wichtigste Punkt ist: Versuchen Sie, freundlich zu sein. Die Leute bringen ihre Frustrationen mit und fragen in vielen Fällen nicht auf die beste Art und Weise, aber versuchen Sie dennoch so gut wie mÃļglich, freundlich zu sein. 🤗 -Die **FastAPI**-Community soll freundlich und einladend sein. Und auch kein Mobbing oder respektloses Verhalten gegenÃŧber anderen akzeptieren. Wir mÃŧssen uns umeinander kÃŧmmern. +Die **FastAPI**-Community soll freundlich und einladend sein. Akzeptieren Sie gleichzeitig kein Mobbing oder respektloses Verhalten gegenÃŧber anderen. Wir mÃŧssen uns umeinander kÃŧmmern. --- -So helfen Sie anderen bei Fragen (in Diskussionen oder Problemen): +So helfen Sie anderen bei Fragen (in Diskussionen oder Issues): -### Die Frage verstehen +### Die Frage verstehen { #understand-the-question } -* Fragen Sie sich, ob Sie verstehen, was das **Ziel** und der Anwendungsfall der fragenden Person ist. +* PrÃŧfen Sie, ob Sie verstehen kÃļnnen, was der **Zweck** und der Anwendungsfall der fragenden Person ist. * ÜberprÃŧfen Sie dann, ob die Frage (die Ãŧberwiegende Mehrheit sind Fragen) **klar** ist. @@ -97,23 +98,23 @@ So helfen Sie anderen bei Fragen (in Diskussionen oder Problemen): * Wenn Sie die Frage nicht verstehen kÃļnnen, fragen Sie nach weiteren **Details**. -### Das Problem reproduzieren +### Das Problem reproduzieren { #reproduce-the-problem } -In den meisten Fällen und bei den meisten Fragen ist etwas mit dem von der Person erstellten **eigenen Quellcode** los. +In den meisten Fällen und bei den meisten Fragen gibt es etwas in Bezug auf den **originalen Code** der Person. In vielen Fällen wird nur ein Fragment des Codes gepostet, aber das reicht nicht aus, um **das Problem zu reproduzieren**. -* Sie kÃļnnen die Person darum bitten, ein minimales, reproduzierbares Beispiel bereitzustellen, welches Sie **kopieren, einfÃŧgen** und lokal ausfÃŧhren kÃļnnen, um den gleichen Fehler oder das gleiche Verhalten zu sehen, das die Person sieht, oder um ihren Anwendungsfall besser zu verstehen. +* Sie kÃļnnen die Person bitten, ein minimales, reproduzierbares Beispiel bereitzustellen, welches Sie **kopieren, einfÃŧgen** und lokal ausfÃŧhren kÃļnnen, um den gleichen Fehler oder das gleiche Verhalten zu sehen, das die Person sieht, oder um ihren Anwendungsfall besser zu verstehen. -* Wenn Sie in Geberlaune sind, kÃļnnen Sie versuchen, selbst ein solches Beispiel zu erstellen, nur basierend auf der Beschreibung des Problems. Denken Sie jedoch daran, dass dies viel Zeit in Anspruch nehmen kann und dass es besser sein kann, zunächst um eine Klärung des Problems zu bitten. +* Wenn Sie in Geberlaune sind, kÃļnnen Sie ein solches Beispiel selbst erstellen, nur basierend auf der Beschreibung des Problems. Denken Sie jedoch daran, dass dies viel Zeit in Anspruch nehmen kann und dass es besser sein kann, zunächst um eine Klärung des Problems zu bitten. -### LÃļsungen vorschlagen +### LÃļsungen vorschlagen { #suggest-solutions } * Nachdem Sie die Frage verstanden haben, kÃļnnen Sie eine mÃļgliche **Antwort** geben. * In vielen Fällen ist es besser, das **zugrunde liegende Problem oder den Anwendungsfall** zu verstehen, da es mÃļglicherweise einen besseren Weg zur LÃļsung gibt als das, was die Person versucht. -### Um Schließung bitten +### Um Schließung bitten { #ask-to-close } Wenn die Person antwortet, besteht eine hohe Chance, dass Sie ihr Problem gelÃļst haben. Herzlichen GlÃŧckwunsch, **Sie sind ein Held**! đŸĻ¸ @@ -122,15 +123,15 @@ Wenn die Person antwortet, besteht eine hohe Chance, dass Sie ihr Problem gelÃļs * In GitHub-Diskussionen: den Kommentar als **Antwort** zu markieren. * In GitHub-Issues: Das Issue zu **schließen**. -## Das GitHub-Repository beobachten +## Das GitHub-Repository beobachten { #watch-the-github-repository } -Sie kÃļnnen FastAPI auf GitHub „beobachten“ (Klicken Sie oben rechts auf die Schaltfläche „watch“): https://github.com/fastapi/fastapi. 👀 +Sie kÃļnnen FastAPI auf GitHub „beobachten“ (klicken Sie auf den „watch“-Button oben rechts): https://github.com/fastapi/fastapi. 👀 -Wenn Sie dann „Watching“ statt „Releases only“ auswählen, erhalten Sie Benachrichtigungen, wenn jemand ein neues Issue erÃļffnet oder eine neue Frage stellt. Sie kÃļnnen auch spezifizieren, dass Sie nur Ãŧber neue Issues, Diskussionen, PRs, usw. benachrichtigt werden mÃļchten. +Wenn Sie dann „Watching“ statt „Releases only“ auswählen, erhalten Sie Benachrichtigungen, wenn jemand ein neues Issue erÃļffnet oder eine neue Frage stellt. Sie kÃļnnen auch spezifizieren, dass Sie nur Ãŧber neue Issues, Diskussionen, PRs usw. benachrichtigt werden mÃļchten. Dann kÃļnnen Sie versuchen, bei der LÃļsung solcher Fragen zu helfen. -## Fragen stellen +## Fragen stellen { #ask-questions } Sie kÃļnnen im GitHub-Repository eine neue Frage erstellen, zum Beispiel: @@ -139,9 +140,9 @@ Sie kÃļnnen im GitHub-Repository diese Datei bearbeiten. * Stellen Sie sicher, dass Sie Ihren Link am Anfang des entsprechenden Abschnitts einfÃŧgen. -* Um zu helfen, [die Dokumentation in Ihre Sprache zu Ãŧbersetzen](contributing.md#ubersetzungen){.internal-link target=_blank}. +* Um zu helfen, [die Dokumentation in Ihre Sprache zu Ãŧbersetzen](contributing.md#translations){.internal-link target=_blank}. * Sie kÃļnnen auch dabei helfen, die von anderen erstellten Übersetzungen zu ÃŧberprÃŧfen (Review). * Um neue Dokumentationsabschnitte vorzuschlagen. -* Um ein bestehendes Problem / einen bestehenden Bug zu beheben. +* Um ein bestehendes Problem/Bug zu beheben. * Stellen Sie sicher, dass Sie Tests hinzufÃŧgen. * Um eine neue Funktionalität hinzuzufÃŧgen. * Stellen Sie sicher, dass Sie Tests hinzufÃŧgen. * Stellen Sie sicher, dass Sie Dokumentation hinzufÃŧgen, falls das notwendig ist. -## FastAPI pflegen +## FastAPI pflegen { #help-maintain-fastapi } -Helfen Sie mir, **FastAPI** instand zu halten! 🤓 +Helfen Sie mir, **FastAPI** zu pflegen! 🤓 Es gibt viel zu tun, und das meiste davon kÃļnnen **SIE** tun. Die Hauptaufgaben, die Sie jetzt erledigen kÃļnnen, sind: -* [Helfen Sie anderen bei Fragen auf GitHub](#anderen-bei-fragen-auf-github-helfen){.internal-link target=_blank} (siehe Abschnitt oben). -* [PrÃŧfen Sie Pull Requests](#pull-requests-prufen){.internal-link target=_blank} (siehe Abschnitt oben). +* [Anderen bei Fragen auf GitHub helfen](#help-others-with-questions-in-github){.internal-link target=_blank} (siehe Abschnitt oben). +* [Pull Requests prÃŧfen](#review-pull-requests){.internal-link target=_blank} (siehe Abschnitt oben). -Diese beiden Dinge sind es, die **die meiste Zeit in Anspruch nehmen**. Das ist die Hauptarbeit bei der Wartung von FastAPI. +Diese beiden Aufgaben sind die Dinge, die **am meisten Zeit verbrauchen**. Das ist die Hauptarbeit bei der Wartung von FastAPI. -Wenn Sie mir dabei helfen kÃļnnen, **helfen Sie mir, FastAPI am Laufen zu erhalten** und sorgen dafÃŧr, dass es weiterhin **schneller und besser voranschreitet**. 🚀 +Wenn Sie mir dabei helfen kÃļnnen, **helfen Sie mir, FastAPI zu pflegen** und Sie stellen sicher, dass es weiterhin **schneller und besser voranschreitet**. 🚀 -## Beim Chat mitmachen +## Am Chat teilnehmen { #join-the-chat } Treten Sie dem đŸ‘Ĩ Discord-Chatserver đŸ‘Ĩ bei und treffen Sie sich mit anderen Mitgliedern der FastAPI-Community. /// tip | Tipp -Wenn Sie Fragen haben, stellen Sie sie bei GitHub Diskussionen, es besteht eine viel bessere Chance, dass Sie hier Hilfe von den [FastAPI-Experten](fastapi-people.md#experten){.internal-link target=_blank} erhalten. +Bei Fragen stellen Sie sie in GitHub-Diskussionen, dort besteht eine viel grÃļßere Chance, dass Sie Hilfe von den [FastAPI-Experten](fastapi-people.md#fastapi-experts){.internal-link target=_blank} erhalten. Nutzen Sie den Chat nur fÃŧr andere allgemeine Gespräche. /// -### Den Chat nicht fÃŧr Fragen verwenden +### Den Chat nicht fÃŧr Fragen verwenden { #dont-use-the-chat-for-questions } -Bedenken Sie, da Chats mehr „freie Konversation“ ermÃļglichen, dass es verlockend ist, Fragen zu stellen, die zu allgemein und schwierig zu beantworten sind, sodass Sie mÃļglicherweise keine Antworten erhalten. +Bedenken Sie, dass Sie in Chats, die „freie Konversation“ erlauben, leicht Fragen stellen kÃļnnen, die zu allgemein und schwer zu beantworten sind, sodass Sie mÃļglicherweise keine Antworten erhalten. -Auf GitHub hilft Ihnen die Vorlage dabei, die richtige Frage zu schreiben, sodass Sie leichter eine gute Antwort erhalten oder das Problem sogar selbst lÃļsen kÃļnnen, noch bevor Sie fragen. Und auf GitHub kann ich sicherstellen, dass ich immer alles beantworte, auch wenn es einige Zeit dauert. Ich persÃļnlich kann das mit den Chat-Systemen nicht machen. 😅 +Auf GitHub hilft Ihnen die Vorlage dabei, die richtige Frage zu stellen, sodass Sie leichter eine gute Antwort erhalten kÃļnnen, oder sogar das Problem selbst lÃļsen, bevor Sie Ãŧberhaupt fragen. Und auf GitHub kann ich sicherstellen, dass ich immer alles beantworte, auch wenn es einige Zeit dauert. PersÃļnlich kann ich das mit den Chat-Systemen nicht machen. 😅 -Unterhaltungen in den Chat-Systemen sind außerdem nicht so leicht durchsuchbar wie auf GitHub, sodass Fragen und Antworten mÃļglicherweise im Gespräch verloren gehen. Und nur die auf GitHub machen einen [FastAPI-Experten](fastapi-people.md#experten){.internal-link target=_blank}, Sie werden also hÃļchstwahrscheinlich mehr Aufmerksamkeit auf GitHub erhalten. +Unterhaltungen in den Chat-Systemen sind auch nicht so leicht durchsuchbar wie auf GitHub, sodass Fragen und Antworten mÃļglicherweise im Gespräch verloren gehen. Und nur die auf GitHub machen einen [FastAPI-Experten](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, Sie werden also hÃļchstwahrscheinlich mehr Aufmerksamkeit auf GitHub erhalten. Auf der anderen Seite gibt es Tausende von Benutzern in den Chat-Systemen, sodass die Wahrscheinlichkeit hoch ist, dass Sie dort fast immer jemanden zum Reden finden. 😄 -## Den Autor sponsern +## Den Autor sponsern { #sponsor-the-author } -Sie kÃļnnen den Autor (mich) auch Ãŧber GitHub-Sponsoren finanziell unterstÃŧtzen. - -Dort kÃļnnten Sie mir als DankeschÃļn einen Kaffee spendieren â˜•ī¸. 😄 - -Und Sie kÃļnnen auch Silber- oder Gold-Sponsor fÃŧr FastAPI werden. 🏅🎉 - -## Die Tools sponsern, die FastAPI unterstÃŧtzen - -Wie Sie in der Dokumentation gesehen haben, steht FastAPI auf den Schultern von Giganten, Starlette und Pydantic. - -Sie kÃļnnen auch sponsern: - -* Samuel Colvin (Pydantic) -* Encode (Starlette, Uvicorn) +Wenn Ihr **Produkt/Firma** auf **FastAPI** angewiesen ist oder in Zusammenhang steht und Sie seine Benutzer erreichen mÃļchten, kÃļnnen Sie den Autor (mich) Ãŧber GitHub-Sponsoren unterstÃŧtzen. Je nach Stufe kÃļnnen Sie einige zusätzliche Vorteile erhalten, wie z. B. ein Abzeichen in der Dokumentation. 🎁 --- diff --git a/docs/de/docs/history-design-future.md b/docs/de/docs/history-design-future.md index ee917608e..40a7a8286 100644 --- a/docs/de/docs/history-design-future.md +++ b/docs/de/docs/history-design-future.md @@ -1,12 +1,12 @@ -# Geschichte, Design und Zukunft +# Geschichte, Design und Zukunft { #history-design-and-future } Vor einiger Zeit fragte ein **FastAPI**-Benutzer: -> Was ist die Geschichte dieses Projekts? Es scheint, als wäre es in ein paar Wochen aus dem Nichts zu etwas Großartigem geworden [...] +> Was ist die Geschichte dieses Projekts? Es scheint aus dem Nichts in ein paar Wochen zu etwas Großartigem geworden zu sein [...] Hier ist ein wenig Ãŧber diese Geschichte. -## Alternativen +## Alternativen { #alternatives } Ich habe seit mehreren Jahren APIs mit komplexen Anforderungen (maschinelles Lernen, verteilte Systeme, asynchrone Jobs, NoSQL-Datenbanken, usw.) erstellt und leitete mehrere Entwicklerteams. @@ -28,7 +28,7 @@ Aber irgendwann gab es keine andere MÃļglichkeit, als etwas zu schaffen, das all -## Investigation +## Untersuchung { #investigation } Durch die Nutzung all dieser vorherigen Alternativen hatte ich die MÃļglichkeit, von allen zu lernen, Ideen aufzunehmen und sie auf die beste Weise zu kombinieren, die ich fÃŧr mich und die Entwicklerteams, mit denen ich zusammengearbeitet habe, finden konnte. @@ -38,13 +38,13 @@ Der beste Ansatz bestand außerdem darin, bereits bestehende Standards zu nutzen Bevor ich also Ãŧberhaupt angefangen habe, **FastAPI** zu schreiben, habe ich mehrere Monate damit verbracht, die Spezifikationen fÃŧr OpenAPI, JSON Schema, OAuth2, usw. zu studieren und deren Beziehungen, Überschneidungen und Unterschiede zu verstehen. -## Design +## Design { #design } Dann habe ich einige Zeit damit verbracht, die Entwickler-„API“ zu entwerfen, die ich als Benutzer haben wollte (als Entwickler, welcher FastAPI verwendet). Ich habe mehrere Ideen in den beliebtesten Python-Editoren getestet: PyCharm, VS Code, Jedi-basierte Editoren. -Laut der letzten Python-Entwickler-Umfrage, deckt das etwa 80 % der Benutzer ab. +Laut der letzten Python-Entwickler-Umfrage deckt das etwa 80 % der Benutzer ab. Das bedeutet, dass **FastAPI** speziell mit den Editoren getestet wurde, die von 80 % der Python-Entwickler verwendet werden. Und da die meisten anderen Editoren in der Regel ähnlich funktionieren, sollten alle diese Vorteile fÃŧr praktisch alle Editoren funktionieren. @@ -52,19 +52,19 @@ Auf diese Weise konnte ich die besten MÃļglichkeiten finden, die Codeverdoppelun Alles auf eine Weise, die allen Entwicklern das beste Entwicklungserlebnis bot. -## Anforderungen +## Anforderungen { #requirements } -Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich **Pydantic** wegen seiner Vorteile verwenden wÃŧrde. +Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich **Pydantic** wegen seiner Vorteile verwenden wÃŧrde. Dann habe ich zu dessen Code beigetragen, um es vollständig mit JSON Schema kompatibel zu machen, und so verschiedene MÃļglichkeiten zum Definieren von einschränkenden Deklarationen (Constraints) zu unterstÃŧtzen, und die EditorunterstÃŧtzung (TypprÃŧfungen, Codevervollständigung) zu verbessern, basierend auf den Tests in mehreren Editoren. Während der Entwicklung habe ich auch zu **Starlette** beigetragen, der anderen SchlÃŧsselanforderung. -## Entwicklung +## Entwicklung { #development } Als ich mit der Erstellung von **FastAPI** selbst begann, waren die meisten Teile bereits vorhanden, das Design definiert, die Anforderungen und Tools bereit und das Wissen Ãŧber die Standards und Spezifikationen klar und frisch. -## Zukunft +## Zukunft { #future } Zu diesem Zeitpunkt ist bereits klar, dass **FastAPI** mit seinen Ideen fÃŧr viele Menschen nÃŧtzlich ist. diff --git a/docs/de/docs/how-to/conditional-openapi.md b/docs/de/docs/how-to/conditional-openapi.md index 50ae11f90..0f0b2d297 100644 --- a/docs/de/docs/how-to/conditional-openapi.md +++ b/docs/de/docs/how-to/conditional-openapi.md @@ -1,8 +1,8 @@ -# Bedingte OpenAPI +# Bedingte OpenAPI { #conditional-openapi } Bei Bedarf kÃļnnen Sie OpenAPI mithilfe von Einstellungen und Umgebungsvariablen abhängig von der Umgebung bedingt konfigurieren und sogar vollständig deaktivieren. -## Über Sicherheit, APIs und Dokumentation +## Über Sicherheit, APIs und Dokumentation { #about-security-apis-and-docs } Das Verstecken Ihrer Dokumentationsoberflächen in der Produktion *sollte nicht* die Methode sein, Ihre API zu schÃŧtzen. @@ -10,11 +10,11 @@ Dadurch wird Ihrer API keine zusätzliche Sicherheit hinzugefÃŧgt, die *Pfadoper Wenn Ihr Code eine SicherheitslÃŧcke aufweist, ist diese weiterhin vorhanden. -Das Verstecken der Dokumentation macht es nur schwieriger zu verstehen, wie mit Ihrer API interagiert werden kann, und kÃļnnte es auch schwieriger machen, diese in der Produktion zu debuggen. Man kÃļnnte es einfach als eine Form von Security through obscurity betrachten. +Das Verstecken der Dokumentation macht es nur schwieriger zu verstehen, wie mit Ihrer API interagiert werden kann, und kÃļnnte es auch schwieriger machen, diese in der Produktion zu debuggen. Man kÃļnnte es einfach als eine Form von Sicherheit durch Verschleierung betrachten. Wenn Sie Ihre API sichern mÃļchten, gibt es mehrere bessere Dinge, die Sie tun kÃļnnen, zum Beispiel: -* Stellen Sie sicher, dass Sie Ãŧber gut definierte Pydantic-Modelle fÃŧr Ihre Requestbodys und Responses verfÃŧgen. +* Stellen Sie sicher, dass Sie Ãŧber gut definierte Pydantic-Modelle fÃŧr Ihre Requestbodys und Responses verfÃŧgen. * Konfigurieren Sie alle erforderlichen Berechtigungen und Rollen mithilfe von Abhängigkeiten. * Speichern Sie niemals Klartext-PasswÃļrter, sondern nur Passwort-Hashes. * Implementieren und verwenden Sie gängige kryptografische Tools wie Passlib und JWT-Tokens, usw. @@ -23,7 +23,7 @@ Wenn Sie Ihre API sichern mÃļchten, gibt es mehrere bessere Dinge, die Sie tun k Dennoch kann es sein, dass Sie einen ganz bestimmten Anwendungsfall haben, bei dem Sie die API-Dokumentation fÃŧr eine bestimmte Umgebung (z. B. fÃŧr die Produktion) oder abhängig von Konfigurationen aus Umgebungsvariablen wirklich deaktivieren mÃŧssen. -## Bedingte OpenAPI aus Einstellungen und Umgebungsvariablen +## Bedingte OpenAPI aus Einstellungen und Umgebungsvariablen { #conditional-openapi-from-settings-and-env-vars } Sie kÃļnnen problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre generierte OpenAPI und die Dokumentationsoberflächen zu konfigurieren. @@ -33,7 +33,7 @@ Zum Beispiel: Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`. -Und dann verwenden wir das beim Erstellen der `FastAPI`-App. +Und dann verwenden wir es beim Erstellen der `FastAPI`-App. Dann kÃļnnten Sie OpenAPI (einschließlich der Dokumentationsoberflächen) deaktivieren, indem Sie die Umgebungsvariable `OPENAPI_URL` auf einen leeren String setzen, wie zum Beispiel: diff --git a/docs/de/docs/how-to/configure-swagger-ui.md b/docs/de/docs/how-to/configure-swagger-ui.md index 1ee72d205..351cb996c 100644 --- a/docs/de/docs/how-to/configure-swagger-ui.md +++ b/docs/de/docs/how-to/configure-swagger-ui.md @@ -1,14 +1,14 @@ -# Swagger-Oberfläche konfigurieren +# Swagger-Oberfläche konfigurieren { #configure-swagger-ui } Sie kÃļnnen einige zusätzliche Parameter der Swagger-Oberfläche konfigurieren. Um diese zu konfigurieren, Ãŧbergeben Sie das Argument `swagger_ui_parameters` beim Erstellen des `FastAPI()`-App-Objekts oder an die Funktion `get_swagger_ui_html()`. -`swagger_ui_parameters` empfängt ein Dict mit den Konfigurationen, die direkt an die Swagger-Oberfläche Ãŧbergeben werden. +`swagger_ui_parameters` empfängt ein Dictionary mit den Konfigurationen, die direkt an die Swagger-Oberfläche Ãŧbergeben werden. FastAPI konvertiert die Konfigurationen nach **JSON**, um diese mit JavaScript kompatibel zu machen, da die Swagger-Oberfläche das benÃļtigt. -## Syntaxhervorhebung deaktivieren +## Syntaxhervorhebung deaktivieren { #disable-syntax-highlighting } Sie kÃļnnten beispielsweise die Syntaxhervorhebung in der Swagger-Oberfläche deaktivieren. @@ -24,9 +24,9 @@ Sie kÃļnnen sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` set -## Das Theme ändern +## Das Theme ändern { #change-the-theme } -Auf die gleiche Weise kÃļnnten Sie das Theme der Syntaxhervorhebung mit dem SchlÃŧssel `syntaxHighlight.theme` festlegen (beachten Sie, dass er einen Punkt in der Mitte hat): +Auf die gleiche Weise kÃļnnten Sie das Theme der Syntaxhervorhebung mit dem SchlÃŧssel `"syntaxHighlight.theme"` festlegen (beachten Sie, dass er einen Punkt in der Mitte hat): {* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *} @@ -34,13 +34,13 @@ Obige Konfiguration wÃŧrde das Theme fÃŧr die Farbe der Syntaxhervorhebung ände -## Defaultparameter der Swagger-Oberfläche ändern +## Defaultparameter der Swagger-Oberfläche ändern { #change-default-swagger-ui-parameters } FastAPI enthält einige Defaultkonfigurationsparameter, die fÃŧr die meisten Anwendungsfälle geeignet sind. Es umfasst die folgenden Defaultkonfigurationen: -{* ../../fastapi/openapi/docs.py ln[7:23] *} +{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *} Sie kÃļnnen jede davon Ãŧberschreiben, indem Sie im Argument `swagger_ui_parameters` einen anderen Wert festlegen. @@ -48,13 +48,13 @@ Um beispielsweise `deepLinking` zu deaktivieren, kÃļnnten Sie folgende Einstellu {* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *} -## Andere Parameter der Swagger-Oberfläche +## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters } Um alle anderen mÃļglichen Konfigurationen zu sehen, die Sie verwenden kÃļnnen, lesen Sie die offizielle Dokumentation fÃŧr die Parameter der Swagger-Oberfläche. -## JavaScript-basierte Einstellungen +## Nur-JavaScript-Einstellungen { #javascript-only-settings } -Die Swagger-Oberfläche erlaubt, dass andere Konfigurationen auch **JavaScript**-Objekte sein kÃļnnen (z. B. JavaScript-Funktionen). +Die Swagger-Oberfläche erlaubt, dass andere Konfigurationen auch **Nur-JavaScript**-Objekte sein kÃļnnen (z. B. JavaScript-Funktionen). FastAPI umfasst auch diese Nur-JavaScript-`presets`-Einstellungen: diff --git a/docs/de/docs/how-to/custom-docs-ui-assets.md b/docs/de/docs/how-to/custom-docs-ui-assets.md index f68902b99..6b8b1a176 100644 --- a/docs/de/docs/how-to/custom-docs-ui-assets.md +++ b/docs/de/docs/how-to/custom-docs-ui-assets.md @@ -1,18 +1,18 @@ -# Statische Assets der Dokumentationsoberfläche (selbst hosten) +# Statische Assets der Dokumentationsoberfläche (Selbst-Hosting) { #custom-docs-ui-static-assets-self-hosting } Die API-Dokumentation verwendet **Swagger UI** und **ReDoc**, und jede dieser Dokumentationen benÃļtigt einige JavaScript- und CSS-Dateien. -Standardmäßig werden diese Dateien von einem CDN bereitgestellt. +Standardmäßig werden diese Dateien von einem CDN bereitgestellt. Es ist jedoch mÃļglich, das anzupassen, ein bestimmtes CDN festzulegen oder die Dateien selbst bereitzustellen. -## Benutzerdefiniertes CDN fÃŧr JavaScript und CSS +## Benutzerdefiniertes CDN fÃŧr JavaScript und CSS { #custom-cdn-for-javascript-and-css } -Nehmen wir an, Sie mÃļchten ein anderes CDN verwenden, zum Beispiel mÃļchten Sie `https://unpkg.com/` verwenden. +Nehmen wir an, Sie mÃļchten ein anderes CDN verwenden, zum Beispiel mÃļchten Sie `https://unpkg.com/` verwenden. Das kann nÃŧtzlich sein, wenn Sie beispielsweise in einem Land leben, in dem bestimmte URLs eingeschränkt sind. -### Die automatischen Dokumentationen deaktivieren +### Die automatischen Dokumentationen deaktivieren { #disable-the-automatic-docs } Der erste Schritt besteht darin, die automatischen Dokumentationen zu deaktivieren, da diese standardmäßig das Standard-CDN verwenden. @@ -20,7 +20,7 @@ Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-A {* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *} -### Die benutzerdefinierten Dokumentationen hinzufÃŧgen +### Die benutzerdefinierten Dokumentationen hinzufÃŧgen { #include-the-custom-docs } Jetzt kÃļnnen Sie die *Pfadoperationen* fÃŧr die benutzerdefinierten Dokumentationen erstellen. @@ -32,7 +32,7 @@ Sie kÃļnnen die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei * `swagger_js_url`: die URL, unter welcher der HTML-Code fÃŧr Ihre Swagger-UI-Dokumentation die **JavaScript**-Datei abrufen kann. Dies ist die benutzerdefinierte CDN-URL. * `swagger_css_url`: die URL, unter welcher der HTML-Code fÃŧr Ihre Swagger-UI-Dokumentation die **CSS**-Datei abrufen kann. Dies ist die benutzerdefinierte CDN-URL. -Und genau so fÃŧr ReDoc ... +Und ähnlich fÃŧr ReDoc ... {* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *} @@ -46,23 +46,23 @@ Swagger UI erledigt das hinter den Kulissen fÃŧr Sie, benÃļtigt aber diesen „U /// -### Eine *Pfadoperation* erstellen, um es zu testen +### Eine *Pfadoperation* erstellen, um es zu testen { #create-a-path-operation-to-test-it } Um nun testen zu kÃļnnen, ob alles funktioniert, erstellen Sie eine *Pfadoperation*: {* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *} -### Es ausprobieren +### Es testen { #test-it } -Jetzt sollten Sie in der Lage sein, zu Ihrer Dokumentation auf http://127.0.0.1:8000/docs zu gehen und die Seite neu zuladen, die Assets werden nun vom neuen CDN geladen. +Jetzt sollten Sie in der Lage sein, zu Ihrer Dokumentation auf http://127.0.0.1:8000/docs zu gehen und die Seite neu zu laden, die Assets werden nun vom neuen CDN geladen. -## JavaScript und CSS fÃŧr die Dokumentation selbst hosten +## JavaScript und CSS fÃŧr die Dokumentation selbst hosten { #self-hosting-javascript-and-css-for-docs } -Das Selbst Hosten von JavaScript und CSS kann nÃŧtzlich sein, wenn Sie beispielsweise mÃļchten, dass Ihre Anwendung auch offline, ohne bestehenden Internetzugang oder in einem lokalen Netzwerk weiter funktioniert. +Das Selbst-Hosting von JavaScript und CSS kann nÃŧtzlich sein, wenn Sie beispielsweise mÃļchten, dass Ihre Anwendung auch offline, ohne bestehenden Internetzugang oder in einem lokalen Netzwerk weiter funktioniert. Hier erfahren Sie, wie Sie diese Dateien selbst in derselben FastAPI-App bereitstellen und die Dokumentation fÃŧr deren Verwendung konfigurieren. -### Projektdateistruktur +### Projektdateistruktur { #project-file-structure } Nehmen wir an, die Dateistruktur Ihres Projekts sieht folgendermaßen aus: @@ -85,11 +85,11 @@ Ihre neue Dateistruktur kÃļnnte so aussehen: └── static/ ``` -### Die Dateien herunterladen +### Die Dateien herunterladen { #download-the-files } Laden Sie die fÃŧr die Dokumentation benÃļtigten statischen Dateien herunter und legen Sie diese im Verzeichnis `static/` ab. -Sie kÃļnnen wahrscheinlich mit der rechten Maustaste auf jeden Link klicken und eine Option wie etwa `Link speichern unter...` auswählen. +Sie kÃļnnen wahrscheinlich mit der rechten Maustaste auf jeden Link klicken und eine Option wie etwa „Link speichern unter ...“ auswählen. **Swagger UI** verwendet folgende Dateien: @@ -113,14 +113,14 @@ Danach kÃļnnte Ihre Dateistruktur wie folgt aussehen: └── swagger-ui.css ``` -### Die statischen Dateien bereitstellen +### Die statischen Dateien bereitstellen { #serve-the-static-files } * Importieren Sie `StaticFiles`. * „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad. {* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *} -### Die statischen Dateien testen +### Die statischen Dateien testen { #test-the-static-files } Starten Sie Ihre Anwendung und gehen Sie auf http://127.0.0.1:8000/static/redoc.standalone.js. @@ -138,19 +138,19 @@ Das zeigt, dass Sie statische Dateien aus Ihrer Anwendung bereitstellen kÃļnnen Jetzt kÃļnnen wir die Anwendung so konfigurieren, dass sie diese statischen Dateien fÃŧr die Dokumentation verwendet. -### Die automatischen Dokumentationen deaktivieren, fÃŧr statische Dateien +### Die automatischen Dokumentationen fÃŧr statische Dateien deaktivieren { #disable-the-automatic-docs-for-static-files } Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt darin, die automatischen Dokumentationen zu deaktivieren, da diese standardmäßig das CDN verwenden. -Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`: +Um sie zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`: {* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *} -### Die benutzerdefinierten Dokumentationen, mit statischen Dateien, hinzufÃŧgen +### Die benutzerdefinierten Dokumentationen fÃŧr statische Dateien hinzufÃŧgen { #include-the-custom-docs-for-static-files } Und genau wie bei einem benutzerdefinierten CDN kÃļnnen Sie jetzt die *Pfadoperationen* fÃŧr die benutzerdefinierten Dokumentationen erstellen. -Auch hier kÃļnnen Sie die internen Funktionen von FastAPI wiederverwenden, um die HTML-Seiten fÃŧr die Dokumentationen zu erstellen, und diesen die erforderlichen Argumente Ãŧbergeben: +Auch hier kÃļnnen Sie die internen Funktionen von FastAPI wiederverwenden, um die HTML-Seiten fÃŧr die Dokumentationen zu erstellen und ihnen die erforderlichen Argumente zu Ãŧbergeben: * `openapi_url`: die URL, unter der die HTML-Seite fÃŧr die Dokumentation das OpenAPI-Schema fÃŧr Ihre API abrufen kann. Sie kÃļnnen hier das Attribut `app.openapi_url` verwenden. * `title`: der Titel Ihrer API. @@ -158,7 +158,7 @@ Auch hier kÃļnnen Sie die internen Funktionen von FastAPI wiederverwenden, um di * `swagger_js_url`: die URL, unter welcher der HTML-Code fÃŧr Ihre Swagger-UI-Dokumentation die **JavaScript**-Datei abrufen kann. **Das ist die, welche jetzt von Ihrer eigenen Anwendung bereitgestellt wird**. * `swagger_css_url`: die URL, unter welcher der HTML-Code fÃŧr Ihre Swagger-UI-Dokumentation die **CSS**-Datei abrufen kann. **Das ist die, welche jetzt von Ihrer eigenen Anwendung bereitgestellt wird**. -Und genau so fÃŧr ReDoc ... +Und ähnlich fÃŧr ReDoc ... {* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *} @@ -172,14 +172,14 @@ Swagger UI erledigt das hinter den Kulissen fÃŧr Sie, benÃļtigt aber diesen „U /// -### Eine *Pfadoperation* erstellen, um statische Dateien zu testen +### Eine *Pfadoperation* erstellen, um statische Dateien zu testen { #create-a-path-operation-to-test-static-files } Um nun testen zu kÃļnnen, ob alles funktioniert, erstellen Sie eine *Pfadoperation*: {* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *} -### Benutzeroberfläche, mit statischen Dateien, testen +### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui } Jetzt sollten Sie in der Lage sein, Ihr WLAN zu trennen, gehen Sie zu Ihrer Dokumentation unter http://127.0.0.1:8000/docs und laden Sie die Seite neu. -Und selbst ohne Internet kÃļnnten Sie die Dokumentation fÃŧr Ihre API sehen und damit interagieren. +Und selbst ohne Internet kÃļnnen Sie die Dokumentation fÃŧr Ihre API sehen und mit ihr interagieren. diff --git a/docs/de/docs/how-to/custom-request-and-route.md b/docs/de/docs/how-to/custom-request-and-route.md index 3e6f709b6..41a85f832 100644 --- a/docs/de/docs/how-to/custom-request-and-route.md +++ b/docs/de/docs/how-to/custom-request-and-route.md @@ -1,10 +1,10 @@ -# Benutzerdefinierte Request- und APIRoute-Klasse +# Benutzerdefinierte Request- und APIRoute-Klasse { #custom-request-and-apiroute-class } In einigen Fällen mÃļchten Sie mÃļglicherweise die von den Klassen `Request` und `APIRoute` verwendete Logik Ãŧberschreiben. Das kann insbesondere eine gute Alternative zur Logik in einer Middleware sein. -Wenn Sie beispielsweise den Requestbody lesen oder manipulieren mÃļchten, bevor er von Ihrer Anwendung verarbeitet wird. +Wenn Sie beispielsweise den Requestbody lesen oder manipulieren mÃļchten, bevor er von Ihrer Anwendung verarbeitet wird. /// danger | Gefahr @@ -14,7 +14,7 @@ Wenn Sie gerade erst mit **FastAPI** beginnen, mÃļchten Sie diesen Abschnitt vie /// -## Anwendungsfälle +## Anwendungsfälle { #use-cases } Einige Anwendungsfälle sind: @@ -22,13 +22,13 @@ Einige Anwendungsfälle sind: * Dekomprimierung gzip-komprimierter Requestbodys. * Automatisches Loggen aller Requestbodys. -## Handhaben von benutzerdefinierten Requestbody-Kodierungen +## Handhaben von benutzerdefinierten Requestbody-Kodierungen { #handling-custom-request-body-encodings } Sehen wir uns an, wie Sie eine benutzerdefinierte `Request`-Unterklasse verwenden, um gzip-Requests zu dekomprimieren. Und eine `APIRoute`-Unterklasse zur Verwendung dieser benutzerdefinierten Requestklasse. -### Eine benutzerdefinierte `GzipRequest`-Klasse erstellen +### Eine benutzerdefinierte `GzipRequest`-Klasse erstellen { #create-a-custom-gziprequest-class } /// tip | Tipp @@ -44,13 +44,13 @@ Auf diese Weise kann dieselbe Routenklasse gzip-komprimierte oder unkomprimierte {* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *} -### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen +### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen { #create-a-custom-gziproute-class } Als Nächstes erstellen wir eine benutzerdefinierte Unterklasse von `fastapi.routing.APIRoute`, welche `GzipRequest` nutzt. Dieses Mal wird die Methode `APIRoute.get_route_handler()` Ãŧberschrieben. -Diese Methode gibt eine Funktion zurÃŧck. Und diese Funktion empfängt einen Request und gibt eine Response zurÃŧck. +Diese Methode gibt eine Funktion zurÃŧck. Und diese Funktion empfängt einen Request und gibt eine Response zurÃŧck. Hier verwenden wir sie, um aus dem ursprÃŧnglichen Request einen `GzipRequest` zu erstellen. @@ -58,9 +58,9 @@ Hier verwenden wir sie, um aus dem ursprÃŧnglichen Request einen `GzipRequest` z /// note | Technische Details -Ein `Request` hat ein `request.scope`-Attribut, welches einfach ein Python-`dict` ist, welches die mit dem Request verbundenen Metadaten enthält. +Ein `Request` hat ein `request.scope`-Attribut, welches einfach ein Python-`dict` ist, welches die mit dem Request verbundenen Metadaten enthält. -Ein `Request` hat auch ein `request.receive`, welches eine Funktion ist, die den Hauptteil des Requests empfängt. +Ein `Request` hat auch ein `request.receive`, welches eine Funktion ist, die den Body des Requests empfängt. Das `scope`-`dict` und die `receive`-Funktion sind beide Teil der ASGI-Spezifikation. @@ -78,11 +78,11 @@ Danach ist die gesamte Verarbeitungslogik dieselbe. Aufgrund unserer Änderungen in `GzipRequest.body` wird der Requestbody jedoch bei Bedarf automatisch dekomprimiert, wenn er von **FastAPI** geladen wird. -## Zugriff auf den Requestbody in einem Exceptionhandler +## Zugriff auf den Requestbody in einem Exceptionhandler { #accessing-the-request-body-in-an-exception-handler } /// tip | Tipp -Um dasselbe Problem zu lÃļsen, ist es wahrscheinlich viel einfacher, den `body` in einem benutzerdefinierten Handler fÃŧr `RequestValidationError` zu verwenden ([Fehlerbehandlung](../tutorial/handling-errors.md#den-requestvalidationerror-body-verwenden){.internal-link target=_blank}). +Um dasselbe Problem zu lÃļsen, ist es wahrscheinlich viel einfacher, den `body` in einem benutzerdefinierten Handler fÃŧr `RequestValidationError` zu verwenden ([Fehlerbehandlung](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}). Dieses Beispiel ist jedoch immer noch gÃŧltig und zeigt, wie mit den internen Komponenten interagiert wird. @@ -98,7 +98,7 @@ Wenn eine Exception auftritt, befindet sich die `Request`-Instanz weiterhin im G {* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *} -## Benutzerdefinierte `APIRoute`-Klasse in einem Router +## Benutzerdefinierte `APIRoute`-Klasse in einem Router { #custom-apiroute-class-in-a-router } Sie kÃļnnen auch den Parameter `route_class` eines `APIRouter` festlegen: diff --git a/docs/de/docs/how-to/extending-openapi.md b/docs/de/docs/how-to/extending-openapi.md index 3b1459364..146ee098b 100644 --- a/docs/de/docs/how-to/extending-openapi.md +++ b/docs/de/docs/how-to/extending-openapi.md @@ -1,24 +1,24 @@ -# OpenAPI erweitern +# OpenAPI erweitern { #extending-openapi } -In einigen Fällen mÃŧssen Sie mÃļglicherweise das generierte OpenAPI-Schema ändern. +Es gibt einige Fälle, in denen Sie das generierte OpenAPI-Schema ändern mÃŧssen. In diesem Abschnitt erfahren Sie, wie. -## Der normale Vorgang +## Der normale Vorgang { #the-normal-process } Der normale (Standard-)Prozess ist wie folgt. -Eine `FastAPI`-Anwendung (-Instanz) verfÃŧgt Ãŧber eine `.openapi()`-Methode, von der erwartet wird, dass sie das OpenAPI-Schema zurÃŧckgibt. +Eine `FastAPI`-Anwendung (Instanz) verfÃŧgt Ãŧber eine `.openapi()`-Methode, von der erwartet wird, dass sie das OpenAPI-Schema zurÃŧckgibt. Als Teil der Erstellung des Anwendungsobjekts wird eine *Pfadoperation* fÃŧr `/openapi.json` (oder welcher Wert fÃŧr den Parameter `openapi_url` gesetzt wurde) registriert. -Diese gibt lediglich eine JSON-Response zurÃŧck, mit dem Ergebnis der Methode `.openapi()` der Anwendung. +Diese gibt lediglich eine JSON-Response zurÃŧck, mit dem Ergebnis der Methode `.openapi()` der Anwendung. Standardmäßig ÃŧberprÃŧft die Methode `.openapi()` die Eigenschaft `.openapi_schema`, um zu sehen, ob diese Inhalt hat, und gibt diesen zurÃŧck. Ist das nicht der Fall, wird der Inhalt mithilfe der Hilfsfunktion unter `fastapi.openapi.utils.get_openapi` generiert. -Und diese Funktion `get_openapi()` erhält als Parameter: +Diese Funktion `get_openapi()` erhält als Parameter: * `title`: Der OpenAPI-Titel, der in der Dokumentation angezeigt wird. * `version`: Die Version Ihrer API, z. B. `2.5.0`. @@ -27,53 +27,53 @@ Und diese Funktion `get_openapi()` erhält als Parameter: * `description`: Die Beschreibung Ihrer API. Dies kann Markdown enthalten und wird in der Dokumentation angezeigt. * `routes`: Eine Liste von Routen, dies sind alle registrierten *Pfadoperationen*. Sie stammen von `app.routes`. -/// info +/// info | Info Der Parameter `summary` ist in OpenAPI 3.1.0 und hÃļher verfÃŧgbar und wird von FastAPI 0.99.0 und hÃļher unterstÃŧtzt. /// -## Überschreiben der Standardeinstellungen +## Überschreiben der Standardeinstellungen { #overriding-the-defaults } Mithilfe der oben genannten Informationen kÃļnnen Sie dieselbe Hilfsfunktion verwenden, um das OpenAPI-Schema zu generieren und jeden benÃļtigten Teil zu Ãŧberschreiben. -FÃŧgen wir beispielsweise ReDocs OpenAPI-Erweiterung zum Einbinden eines benutzerdefinierten Logos hinzu. +FÃŧgen wir beispielsweise ReDocs OpenAPI-Erweiterung zum Einbinden eines benutzerdefinierten Logos hinzu. -### Normales **FastAPI** +### Normales **FastAPI** { #normal-fastapi } Schreiben Sie zunächst wie gewohnt Ihre ganze **FastAPI**-Anwendung: {* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *} -### Das OpenAPI-Schema generieren +### Das OpenAPI-Schema generieren { #generate-the-openapi-schema } Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren: {* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *} -### Das OpenAPI-Schema ändern +### Das OpenAPI-Schema ändern { #modify-the-openapi-schema } Jetzt kÃļnnen Sie die ReDoc-Erweiterung hinzufÃŧgen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufÃŧgen: {* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *} -### Zwischenspeichern des OpenAPI-Schemas +### Zwischenspeichern des OpenAPI-Schemas { #cache-the-openapi-schema } Sie kÃļnnen die Eigenschaft `.openapi_schema` als „Cache“ verwenden, um Ihr generiertes Schema zu speichern. Auf diese Weise muss Ihre Anwendung das Schema nicht jedes Mal generieren, wenn ein Benutzer Ihre API-Dokumentation Ãļffnet. -Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema fÃŧr die nächsten Requests verwendet. +Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema fÃŧr die nächsten Requests verwendet. {* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *} -### Die Methode Ãŧberschreiben +### Die Methode Ãŧberschreiben { #override-the-method } Jetzt kÃļnnen Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen. {* ../../docs_src/extending_openapi/tutorial001.py hl[29] *} -### Testen +### Es testen { #check-it } Sobald Sie auf http://127.0.0.1:8000/redoc gehen, werden Sie sehen, dass Ihr benutzerdefiniertes Logo verwendet wird (in diesem Beispiel das Logo von **FastAPI**): diff --git a/docs/de/docs/how-to/general.md b/docs/de/docs/how-to/general.md index b38b5fabf..0045eab74 100644 --- a/docs/de/docs/how-to/general.md +++ b/docs/de/docs/how-to/general.md @@ -1,39 +1,39 @@ -# Allgemeines – How-To – Rezepte +# Allgemeines – How-To – Rezepte { #general-how-to-recipes } Hier finden Sie mehrere Verweise auf andere Stellen in der Dokumentation, fÃŧr allgemeine oder häufige Fragen. -## Daten filtern – Sicherheit +## Daten filtern – Sicherheit { #filter-data-security } Um sicherzustellen, dass Sie nicht mehr Daten zurÃŧckgeben, als Sie sollten, lesen Sie die Dokumentation unter [Tutorial – Responsemodell – RÃŧckgabetyp](../tutorial/response-model.md){.internal-link target=_blank}. -## Dokumentations-Tags – OpenAPI +## Dokumentations-Tags – OpenAPI { #documentation-tags-openapi } Um Tags zu Ihren *Pfadoperationen* hinzuzufÃŧgen und diese in der Oberfläche der Dokumentation zu gruppieren, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}. -## Zusammenfassung und Beschreibung in der Dokumentation – OpenAPI +## Zusammenfassung und Beschreibung in der Dokumentation – OpenAPI { #documentation-summary-and-description-openapi } -Um Ihren *Pfadoperationen* eine Zusammenfassung und Beschreibung hinzuzufÃŧgen und diese in der Oberfläche der Dokumentation anzuzeigen, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Zusammenfassung und Beschreibung](../tutorial/path-operation-configuration.md#zusammenfassung-und-beschreibung){.internal-link target=_blank}. +Um Ihren *Pfadoperationen* eine Zusammenfassung und Beschreibung hinzuzufÃŧgen und diese in der Oberfläche der Dokumentation anzuzeigen, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Zusammenfassung und Beschreibung](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}. -## Beschreibung der Response in der Dokumentation – OpenAPI +## Beschreibung der Response in der Dokumentation – OpenAPI { #documentation-response-description-openapi } -Um die Beschreibung der Response zu definieren, welche in der Oberfläche der Dokumentation angezeigt wird, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Beschreibung der Response](../tutorial/path-operation-configuration.md#beschreibung-der-response){.internal-link target=_blank}. +Um die Beschreibung der Response zu definieren, welche in der Oberfläche der Dokumentation angezeigt wird, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Beschreibung der Response](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}. -## *Pfadoperation* in der Dokumentation deprecaten – OpenAPI +## *Pfadoperation* in der Dokumentation deprecaten – OpenAPI { #documentation-deprecate-a-path-operation-openapi } -Um eine *Pfadoperation* zu deprecaten – sie als veraltet zu markieren – und das in der Oberfläche der Dokumentation anzuzeigen, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Deprecaten](../tutorial/path-operation-configuration.md#eine-pfadoperation-deprecaten){.internal-link target=_blank}. +Um eine *Pfadoperation* zu deprecaten und das in der Oberfläche der Dokumentation anzuzeigen, lesen Sie die Dokumentation unter [Tutorial – Pfadoperation-Konfiguration – Deprecaten](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}. -## Daten in etwas JSON-kompatibles konvertieren +## Daten in etwas JSON-kompatibles konvertieren { #convert-any-data-to-json-compatible } Um Daten in etwas JSON-kompatibles zu konvertieren, lesen Sie die Dokumentation unter [Tutorial – JSON-kompatibler Encoder](../tutorial/encoder.md){.internal-link target=_blank}. -## OpenAPI-Metadaten – Dokumentation +## OpenAPI-Metadaten – Dokumentation { #openapi-metadata-docs } -Um Metadaten zu Ihrem OpenAPI-Schema hinzuzufÃŧgen, einschließlich einer Lizenz, Version, Kontakt, usw., lesen Sie die Dokumentation unter [Tutorial – Metadaten und URLs der Dokumentationen](../tutorial/metadata.md){.internal-link target=_blank}. +Um Metadaten zu Ihrem OpenAPI-Schema hinzuzufÃŧgen, einschließlich einer Lizenz, Version, Kontakt, usw., lesen Sie die Dokumentation unter [Tutorial – Metadaten und URLs der Dokumentation](../tutorial/metadata.md){.internal-link target=_blank}. -## Benutzerdefinierte OpenAPI-URL +## Benutzerdefinierte OpenAPI-URL { #openapi-custom-url } -Um die OpenAPI-URL anzupassen (oder zu entfernen), lesen Sie die Dokumentation unter [Tutorial – Metadaten und URLs der Dokumentationen](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}. +Um die OpenAPI-URL anzupassen (oder zu entfernen), lesen Sie die Dokumentation unter [Tutorial – Metadaten und URLs der Dokumentation](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}. -## URLs der OpenAPI-Dokumentationen +## URLs der OpenAPI-Dokumentationen { #openapi-docs-urls } -Um die URLs zu aktualisieren, die fÃŧr die automatisch generierten Dokumentations-Oberflächen verwendet werden, lesen Sie die Dokumentation unter [Tutorial – Metadaten und URLs der Dokumentationen](../tutorial/metadata.md#urls-der-dokumentationen){.internal-link target=_blank}. +Um die URLs zu aktualisieren, die fÃŧr die automatisch generierten Dokumentations-Oberflächen verwendet werden, lesen Sie die Dokumentation unter [Tutorial – Metadaten und URLs der Dokumentation](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}. diff --git a/docs/de/docs/how-to/graphql.md b/docs/de/docs/how-to/graphql.md index 4083e66ae..d2958dcd9 100644 --- a/docs/de/docs/how-to/graphql.md +++ b/docs/de/docs/how-to/graphql.md @@ -1,4 +1,4 @@ -# GraphQL +# GraphQL { #graphql } Da **FastAPI** auf dem **ASGI**-Standard basiert, ist es sehr einfach, jede **GraphQL**-Bibliothek zu integrieren, die auch mit ASGI kompatibel ist. @@ -10,42 +10,42 @@ Sie kÃļnnen normale FastAPI-*Pfadoperationen* mit GraphQL in derselben Anwendung Es hat **Vorteile** und **Nachteile** im Vergleich zu gängigen **Web-APIs**. -Wiegen Sie ab, ob die **Vorteile** fÃŧr Ihren Anwendungsfall die **Nachteile** ausgleichen. 🤓 +Stellen Sie sicher, dass Sie prÃŧfen, ob die **Vorteile** fÃŧr Ihren Anwendungsfall die **Nachteile** ausgleichen. 🤓 /// -## GraphQL-Bibliotheken +## GraphQL-Bibliotheken { #graphql-libraries } -Hier sind einige der **GraphQL**-Bibliotheken, welche **ASGI** unterstÃŧtzen. Diese kÃļnnten Sie mit **FastAPI** verwenden: +Hier sind einige der **GraphQL**-Bibliotheken, die **ASGI**-UnterstÃŧtzung haben. Sie kÃļnnten sie mit **FastAPI** verwenden: * Strawberry 🍓 * Mit Dokumentation fÃŧr FastAPI * Ariadne * Mit Dokumentation fÃŧr FastAPI * Tartiflette - * Mit Tartiflette ASGI, fÃŧr ASGI-Integration + * Mit Tartiflette ASGI fÃŧr ASGI-Integration * Graphene * Mit starlette-graphene3 -## GraphQL mit Strawberry +## GraphQL mit Strawberry { #graphql-with-strawberry } -Wenn Sie mit **GraphQL** arbeiten mÃļchten oder mÃŧssen, ist **Strawberry** die **empfohlene** Bibliothek, da deren Design dem Design von **FastAPI** am nächsten kommt und alles auf **Typannotationen** basiert. +Wenn Sie mit **GraphQL** arbeiten mÃļchten oder mÃŧssen, ist **Strawberry** die **empfohlene** Bibliothek, da deren Design **FastAPIs** Design am nächsten kommt und alles auf **Typannotationen** basiert. -Abhängig von Ihrem Anwendungsfall bevorzugen Sie vielleicht eine andere Bibliothek, aber wenn Sie mich fragen wÃŧrden, wÃŧrde ich Ihnen wahrscheinlich empfehlen, **Strawberry** auszuprobieren. +Abhängig von Ihrem Anwendungsfall kÃļnnten Sie eine andere Bibliothek vorziehen, aber wenn Sie mich fragen wÃŧrden, wÃŧrde ich Ihnen wahrscheinlich empfehlen, **Strawberry** auszuprobieren. Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren kÃļnnen: -{* ../../docs_src/graphql/tutorial001.py hl[3,22,25:26] *} +{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *} Weitere Informationen zu Strawberry finden Sie in der Strawberry-Dokumentation. -Und auch die Dokumentation zu Strawberry mit FastAPI. +Und auch in der Dokumentation zu Strawberry mit FastAPI. -## Ältere `GraphQLApp` von Starlette +## Ältere `GraphQLApp` von Starlette { #older-graphqlapp-from-starlette } FrÃŧhere Versionen von Starlette enthielten eine `GraphQLApp`-Klasse zur Integration mit Graphene. -Das wurde von Starlette deprecated, aber wenn Sie Code haben, der das verwendet, kÃļnnen Sie einfach zu starlette-graphene3 **migrieren**, welches denselben Anwendungsfall abdeckt und Ãŧber eine **fast identische Schnittstelle** verfÃŧgt. +Das wurde von Starlette deprecatet, aber wenn Sie Code haben, der das verwendet, kÃļnnen Sie einfach zu starlette-graphene3 **migrieren**, das denselben Anwendungsfall abdeckt und eine **fast identische Schnittstelle** hat. /// tip | Tipp @@ -53,7 +53,7 @@ Wenn Sie GraphQL benÃļtigen, wÃŧrde ich Ihnen trotzdem empfehlen, sich offiziellen GraphQL-Dokumentation. diff --git a/docs/de/docs/how-to/index.md b/docs/de/docs/how-to/index.md index 84a178fc8..36229dcd7 100644 --- a/docs/de/docs/how-to/index.md +++ b/docs/de/docs/how-to/index.md @@ -1,4 +1,4 @@ -# How-To – Rezepte +# How-To – Rezepte { #how-to-recipes } Hier finden Sie verschiedene Rezepte und „How-To“-Anleitungen zu **verschiedenen Themen**. diff --git a/docs/de/docs/how-to/separate-openapi-schemas.md b/docs/de/docs/how-to/separate-openapi-schemas.md index 4f6911e79..31653590b 100644 --- a/docs/de/docs/how-to/separate-openapi-schemas.md +++ b/docs/de/docs/how-to/separate-openapi-schemas.md @@ -1,18 +1,18 @@ -# Separate OpenAPI-Schemas fÃŧr Eingabe und Ausgabe oder nicht +# Separate OpenAPI-Schemas fÃŧr Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not } Bei Verwendung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎 -Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI fÃŧr dasselbe Pydantic-Modell fÃŧr Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben. +Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI fÃŧr dasselbe Pydantic-Modell, fÃŧr Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben. Sehen wir uns an, wie das funktioniert und wie Sie es bei Bedarf ändern kÃļnnen. -## Pydantic-Modelle fÃŧr Eingabe und Ausgabe +## Pydantic-Modelle fÃŧr Eingabe und Ausgabe { #pydantic-models-for-input-and-output } Nehmen wir an, Sie haben ein Pydantic-Modell mit Defaultwerten wie dieses: {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *} -### Modell fÃŧr Eingabe +### Modell fÃŧr Eingabe { #model-for-input } Wenn Sie dieses Modell wie hier als Eingabe verwenden: @@ -20,7 +20,7 @@ Wenn Sie dieses Modell wie hier als Eingabe verwenden: ... dann ist das Feld `description` **nicht erforderlich**. Weil es den Defaultwert `None` hat. -### Eingabemodell in der Dokumentation +### Eingabemodell in der Dokumentation { #input-model-in-docs } Sie kÃļnnen ÃŧberprÃŧfen, dass das Feld `description` in der Dokumentation kein **rotes Sternchen** enthält, es ist nicht als erforderlich markiert: @@ -28,17 +28,17 @@ Sie kÃļnnen ÃŧberprÃŧfen, dass das Feld `description` in der Dokumentation kein
-### Modell fÃŧr die Ausgabe +### Modell fÃŧr die Ausgabe { #model-for-output } Wenn Sie jedoch dasselbe Modell als Ausgabe verwenden, wie hier: {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *} -... dann, weil `description` einen Defaultwert hat, wird es, wenn Sie fÃŧr dieses Feld **nichts zurÃŧckgeben**, immer noch diesen **Defaultwert** haben. +... dann, weil `description` einen Defaultwert hat, wird es, wenn Sie fÃŧr dieses Feld **nichts zurÃŧckgeben**, immer noch diesen **Defaultwert** haben. -### Modell fÃŧr Ausgabe-Responsedaten +### Modell fÃŧr Ausgabe-Responsedaten { #model-for-output-response-data } -Wenn Sie mit der Dokumentation interagieren und die Response ÃŧberprÃŧfen, enthält die JSON-Response den Defaultwert (`null`), obwohl der Code nichts in eines der `description`-Felder geschrieben hat: +Wenn Sie mit der Dokumentation interagieren und die Response ÃŧberprÃŧfen, enthält die JSON-Response den Defaultwert (`null`), obwohl der Code nichts in eines der `description`-Felder geschrieben hat:
@@ -55,7 +55,7 @@ Aus diesem Grund kann das JSON-Schema fÃŧr ein Modell unterschiedlich sein, je n * fÃŧr die **Eingabe** ist `description` **nicht erforderlich** * fÃŧr die **Ausgabe** ist es **erforderlich** (und mÃļglicherweise `None` oder, in JSON-Begriffen, `null`) -### Ausgabemodell in der Dokumentation +### Ausgabemodell in der Dokumentation { #model-for-output-in-docs } Sie kÃļnnen das Ausgabemodell auch in der Dokumentation ÃŧberprÃŧfen. **Sowohl** `name` **als auch** `description` sind mit einem **roten Sternchen** als **erforderlich** markiert: @@ -63,7 +63,7 @@ Sie kÃļnnen das Ausgabemodell auch in der Dokumentation ÃŧberprÃŧfen. **Sowohl**
-### Eingabe- und Ausgabemodell in der Dokumentation +### Eingabe- und Ausgabemodell in der Dokumentation { #model-for-input-and-output-in-docs } Und wenn Sie alle verfÃŧgbaren Schemas (JSON-Schemas) in OpenAPI ÃŧberprÃŧfen, werden Sie feststellen, dass es zwei gibt, ein `Item-Input` und ein `Item-Output`. @@ -77,7 +77,7 @@ Aber fÃŧr `Item-Output` ist `description` **erforderlich**, es hat ein rotes Ste Mit dieser Funktion von **Pydantic v2** ist Ihre API-Dokumentation **präziser**, und wenn Sie Ãŧber automatisch generierte Clients und SDKs verfÃŧgen, sind diese auch präziser, mit einer besseren **Entwicklererfahrung** und Konsistenz. 🎉 -## Schemas nicht trennen +## Schemas nicht trennen { #do-not-separate-schemas } Nun gibt es einige Fälle, in denen Sie mÃļglicherweise **dasselbe Schema fÃŧr Eingabe und Ausgabe** haben mÃļchten. @@ -85,7 +85,7 @@ Der Hauptanwendungsfall hierfÃŧr besteht wahrscheinlich darin, dass Sie das mal In diesem Fall kÃļnnen Sie diese Funktion in **FastAPI** mit dem Parameter `separate_input_output_schemas=False` deaktivieren. -/// info +/// info | Info UnterstÃŧtzung fÃŧr `separate_input_output_schemas` wurde in FastAPI `0.102.0` hinzugefÃŧgt. 🤓 @@ -93,7 +93,7 @@ UnterstÃŧtzung fÃŧr `separate_input_output_schemas` wurde in FastAPI `0.102.0` h {* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *} -### Gleiches Schema fÃŧr Eingabe- und Ausgabemodelle in der Dokumentation +### Gleiches Schema fÃŧr Eingabe- und Ausgabemodelle in der Dokumentation { #same-schema-for-input-and-output-models-in-docs } Und jetzt wird es ein einziges Schema fÃŧr die Eingabe und Ausgabe des Modells geben, nur `Item`, und es wird `description` als **nicht erforderlich** kennzeichnen: diff --git a/docs/de/docs/how-to/testing-database.md b/docs/de/docs/how-to/testing-database.md new file mode 100644 index 000000000..1a6095e53 --- /dev/null +++ b/docs/de/docs/how-to/testing-database.md @@ -0,0 +1,7 @@ +# Eine Datenbank testen { #testing-a-database } + +Sie kÃļnnen sich Ãŧber Datenbanken, SQL und SQLModel in der SQLModel-Dokumentation informieren. 🤓 + +Es gibt ein kurzes Tutorial zur Verwendung von SQLModel mit FastAPI. ✨ + +Dieses Tutorial enthält einen Abschnitt Ãŧber das Testen von SQL-Datenbanken. 😎 diff --git a/docs/de/docs/index.md b/docs/de/docs/index.md index d239f0815..edcb61b94 100644 --- a/docs/de/docs/index.md +++ b/docs/de/docs/index.md @@ -1,21 +1,21 @@ -# FastAPI +# FastAPI { #fastapi }

- FastAPI + FastAPI

- FastAPI Framework, hochperformant, leicht zu erlernen, schnell zu programmieren, einsatzbereit + FastAPI-Framework, hohe Performanz, leicht zu lernen, schnell zu entwickeln, produktionsreif

Test - Coverage + Testabdeckung Package-Version @@ -27,7 +27,7 @@ --- -**Dokumentation**: https://fastapi.tiangolo.com +**Dokumentation**: https://fastapi.tiangolo.com/de **Quellcode**: https://github.com/fastapi/fastapi @@ -37,19 +37,18 @@ FastAPI ist ein modernes, schnelles (hoch performantes) Webframework zur Erstell Seine SchlÃŧssel-Merkmale sind: -* **Schnell**: Sehr hohe Leistung, auf AugenhÃļhe mit **NodeJS** und **Go** (Dank Starlette und Pydantic). [Eines der schnellsten verfÃŧgbaren Python-Frameworks](#performanz). - -* **Schnell zu programmieren**: ErhÃļhen Sie die Geschwindigkeit bei der Entwicklung von Funktionen um etwa 200 % bis 300 %. * +* **Schnell**: Sehr hohe Performanz, auf AugenhÃļhe mit **NodeJS** und **Go** (dank Starlette und Pydantic). [Eines der schnellsten verfÃŧgbaren Python-Frameworks](#performance). +* **Schnell zu entwickeln**: ErhÃļhen Sie die Geschwindigkeit bei der Entwicklung von Features um etwa 200 % bis 300 %. * * **Weniger Bugs**: Verringern Sie die von Menschen (Entwicklern) verursachten Fehler um etwa 40 %. * -* **Intuitiv**: Exzellente Editor-UnterstÃŧtzung. Code-Vervollständigung Ãŧberall. Weniger Debuggen. -* **Einfach**: So konzipiert, dass es einfach zu benutzen und zu erlernen ist. Weniger Zeit fÃŧr das Lesen der Dokumentation. -* **Kurz**: Minimieren Sie die Verdoppelung von Code. Mehrere Funktionen aus jeder Parameterdeklaration. Weniger Bugs. +* **Intuitiv**: Hervorragende Editor-UnterstÃŧtzung. Code-Vervollständigung Ãŧberall. Weniger Zeit mit Debuggen verbringen. +* **Einfach**: So konzipiert, dass es einfach zu benutzen und zu erlernen ist. Weniger Zeit mit dem Lesen von Dokumentation verbringen. +* **Kurz**: Minimieren Sie die Verdoppelung von Code. Mehrere Features aus jeder Parameterdeklaration. Weniger Bugs. * **Robust**: Erhalten Sie produktionsreifen Code. Mit automatischer, interaktiver Dokumentation. * **Standards-basiert**: Basierend auf (und vollständig kompatibel mit) den offenen Standards fÃŧr APIs: OpenAPI (frÃŧher bekannt als Swagger) und JSON Schema. -* Schätzung auf Basis von Tests in einem internen Entwicklungsteam, das Produktionsanwendungen erstellt. +* Schätzung basierend auf Tests in einem internen Entwicklungsteam, das Produktionsanwendungen erstellt. -## Sponsoren +## Sponsoren { #sponsors } @@ -64,55 +63,55 @@ Seine SchlÃŧssel-Merkmale sind: -Andere Sponsoren +Andere Sponsoren -## Meinungen +## Meinungen { #opinions } -„_[...] Ich verwende **FastAPI** heutzutage sehr oft. [...] Ich habe tatsächlich vor, es fÃŧr alle **ML-Dienste meines Teams bei Microsoft** zu verwenden. Einige davon werden in das Kernprodukt **Windows** und einige **Office**-Produkte integriert._“ +„_[...] Ich verwende **FastAPI** heutzutage sehr oft. [...] Ich habe tatsächlich vor, es fÃŧr alle **ML-Services meines Teams bei Microsoft** zu verwenden. Einige davon werden in das Kernprodukt **Windows** und einige **Office**-Produkte integriert._“ -

Kabir Khan - Microsoft (Ref)
+
Kabir Khan – Microsoft (Ref.)
--- -„_Wir haben die **FastAPI**-Bibliothek genommen, um einen **REST**-Server zu erstellen, der abgefragt werden kann, um **Vorhersagen** zu erhalten. [fÃŧr Ludwig]_“ +„_Wir haben die **FastAPI**-Bibliothek Ãŧbernommen, um einen **REST**-Server zu erstellen, der fÃŧr **Vorhersagen** abgefragt werden kann. [fÃŧr Ludwig]_“ -
Piero Molino, Yaroslav Dudin, und Sai Sumanth Miryala - Uber (Ref)
+
Piero Molino, Yaroslav Dudin, und Sai Sumanth Miryala – Uber (Ref.)
--- „_**Netflix** freut sich, die Open-Source-VerÃļffentlichung unseres **Krisenmanagement**-Orchestrierung-Frameworks bekannt zu geben: **Dispatch**! [erstellt mit **FastAPI**]_“ -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (Ref)
+
Kevin Glisson, Marc Vilanova, Forest Monsen – Netflix (Ref.)
--- -„_Ich bin ÃŧberglÃŧcklich mit **FastAPI**. Es macht so viel Spaß!_“ +„_Ich bin hellauf begeistert von **FastAPI**. Es macht so viel Spaß!_“ -
Brian Okken - Host des Python Bytes Podcast (Ref)
+
Brian Okken – Python Bytes Podcast-Host (Ref.)
--- „_Ehrlich, was Du gebaut hast, sieht super solide und poliert aus. In vielerlei Hinsicht ist es so, wie ich **Hug** haben wollte – es ist wirklich inspirierend, jemanden so etwas bauen zu sehen._“ -
Timothy Crosley - Autor von Hug (Ref)
+
Timothy Crosley – Hug-Autor (Ref.)
--- -„_Wenn Sie ein **modernes Framework** zum Erstellen von REST-APIs erlernen mÃļchten, schauen Sie sich **FastAPI** an. [...] Es ist schnell, einfach zu verwenden und leicht zu erlernen [...]_“ +„_Wenn Sie ein **modernes Framework** zum Erstellen von REST-APIs erlernen mÃļchten, schauen Sie sich **FastAPI** an. [...] Es ist schnell, einfach zu verwenden und leicht zu lernen [...]_“ „_Wir haben zu **FastAPI** fÃŧr unsere **APIs** gewechselt [...] Ich denke, es wird Ihnen gefallen [...]_“ -
Ines Montani - Matthew Honnibal - GrÃŧnder von Explosion AI - Autoren von spaCy (Ref) - (Ref)
+
Ines Montani – Matthew Honnibal – Explosion AI-GrÃŧnder – spaCy-Autoren (Ref.) – (Ref.)
--- -„_Falls irgendjemand eine Produktions-Python-API erstellen mÃļchte, kann ich **FastAPI** wärmstens empfehlen. Es ist **wunderschÃļn konzipiert**, **einfach zu verwenden** und **hoch skalierbar**; es ist zu einer **SchlÃŧsselkomponente** in unserer API-First-Entwicklungsstrategie geworden und treibt viele Automatisierungen und Dienste an, wie etwa unseren virtuellen TAC-Ingenieur._“ +„_Falls irgendjemand eine Produktions-Python-API erstellen mÃļchte, kann ich **FastAPI** wärmstens empfehlen. Es ist **wunderschÃļn konzipiert**, **einfach zu verwenden** und **hoch skalierbar**; es ist zu einer **SchlÃŧsselkomponente** unserer API-First-Entwicklungsstrategie geworden und treibt viele Automatisierungen und Services an, wie etwa unseren Virtual TAC Engineer._“ -
Deon Pillsbury - Cisco (Ref)
+
Deon Pillsbury – Cisco (Ref.)
--- -## **Typer**, das FastAPI der CLIs +## **Typer**, das FastAPI der CLIs { #typer-the-fastapi-of-clis } @@ -120,42 +119,34 @@ Wenn Sie eine Starlette fÃŧr die Webanteile. -* Pydantic fÃŧr die Datenanteile. +* Pydantic fÃŧr die Datenanteile. -## Installation +## Installation { #installation } + +Erstellen und aktivieren Sie eine virtuelle Umgebung und installieren Sie dann FastAPI:
```console -$ pip install fastapi +$ pip install "fastapi[standard]" ---> 100% ```
-Sie benÃļtigen außerdem einen ASGI-Server. FÃŧr die Produktumgebung beispielsweise Uvicorn oder Hypercorn. +**Hinweis**: Stellen Sie sicher, dass Sie `"fastapi[standard]"` in AnfÃŧhrungszeichen setzen, damit es in allen Terminals funktioniert. -
+## Beispiel { #example } -```console -$ pip install "uvicorn[standard]" +### Erstellung { #create-it } ----> 100% -``` - -
- -## Beispiel - -### Erstellung - -* Erstellen Sie eine Datei `main.py` mit: +Erstellen Sie eine Datei `main.py` mit: ```Python from typing import Union @@ -198,23 +189,37 @@ async def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` -**Anmerkung**: +**Hinweis**: + +Wenn Sie das nicht kennen, schauen Sie sich den Abschnitt _„In Eile?“_ Ãŧber `async` und `await` in der Dokumentation an. -Wenn Sie das nicht kennen, schauen Sie sich den Abschnitt _„In Eile?“_ Ãŧber `async` und `await` in der Dokumentation an. -### Starten +### Starten { #run-it } -FÃŧhren Sie den Server aus: +Starten Sie den Server mit:
```console -$ uvicorn main:app --reload +$ fastapi dev main.py + ╭────────── FastAPI CLI - Development mode ───────────╮ + │ │ + │ Serving at: http://127.0.0.1:8000 │ + │ │ + │ API docs: http://127.0.0.1:8000/docs │ + │ │ + │ Running in development mode, for production use: │ + │ │ + │ fastapi run │ + │ │ + ╰─────────────────────────────────────────────────────╯ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] 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: Started reloader process [2248755] using WatchFiles +INFO: Started server process [2248757] INFO: Waiting for application startup. INFO: Application startup complete. ``` @@ -222,34 +227,34 @@ INFO: Application startup complete.
-Was macht der Befehl uvicorn main:app --reload ... +Was der Befehl fastapi dev main.py macht ... -Der Befehl `uvicorn main:app` bezieht sich auf: +Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit Uvicorn. -* `main`: die Datei `main.py` (das Python-„Modul“). -* `app`: das Objekt, das innerhalb von `main.py` mit der Zeile `app = FastAPI()` erzeugt wurde. -* `--reload`: lässt den Server nach Codeänderungen neu starten. Tun Sie das nur während der Entwicklung. +Standardmäßig wird `fastapi dev` mit aktiviertem Auto-Reload fÃŧr die lokale Entwicklung gestartet. + +Sie kÃļnnen mehr darÃŧber in der FastAPI CLI Dokumentation lesen.
-### Testen +### Es testen { #check-it } Öffnen Sie Ihren Browser unter http://127.0.0.1:8000/items/5?q=somequery. -Sie erhalten die JSON-Response: +Sie sehen die JSON-Response als: ```JSON {"item_id": 5, "q": "somequery"} ``` -Damit haben Sie bereits eine API erstellt, welche: +Sie haben bereits eine API erstellt, welche: -* HTTP-Anfragen auf den _Pfaden_ `/` und `/items/{item_id}` entgegennimmt. -* Beide _Pfade_ erhalten `GET` Operationen (auch bekannt als HTTP _Methoden_). -* Der _Pfad_ `/items/{item_id}` hat einen _Pfadparameter_ `item_id`, der ein `int` sein sollte. -* Der _Pfad_ `/items/{item_id}` hat einen optionalen `str` _Query Parameter_ `q`. +* HTTP-Requests auf den _Pfaden_ `/` und `/items/{item_id}` entgegennimmt. +* Beide _Pfade_ nehmen `GET` Operationen (auch bekannt als HTTP-_Methoden_) entgegen. +* Der _Pfad_ `/items/{item_id}` hat einen _Pfad-Parameter_ `item_id`, der ein `int` sein sollte. +* Der _Pfad_ `/items/{item_id}` hat einen optionalen `str`-_Query-Parameter_ `q`. -### Interaktive API-Dokumentation +### Interaktive API-Dokumentation { #interactive-api-docs } Gehen Sie nun auf http://127.0.0.1:8000/docs. @@ -257,19 +262,19 @@ Sie sehen die automatische interaktive API-Dokumentation (bereitgestellt von http://127.0.0.1:8000/redoc. +Und jetzt gehen Sie auf http://127.0.0.1:8000/redoc. Sie sehen die alternative automatische Dokumentation (bereitgestellt von ReDoc): ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) -## Beispiel Aktualisierung +## Beispiel Aktualisierung { #example-upgrade } -Ändern Sie jetzt die Datei `main.py`, um den Body einer `PUT`-Anfrage zu empfangen. +Ändern Sie jetzt die Datei `main.py`, um den Body eines `PUT`-Requests zu empfangen. -Deklarieren Sie den Body mithilfe von Standard-Python-Typen, dank Pydantic. +Deklarieren Sie den Body mit Standard-Python-Typen, dank Pydantic. ```Python hl_lines="4 9-12 25-27" from typing import Union @@ -301,9 +306,9 @@ def update_item(item_id: int, item: Item): return {"item_name": item.name, "item_id": item_id} ``` -Der Server sollte automatisch neu geladen werden (weil Sie oben `--reload` zum Befehl `uvicorn` hinzugefÃŧgt haben). +Der `fastapi dev`-Server sollte automatisch neu laden. -### Aktualisierung der interaktiven API-Dokumentation +### Interaktive API-Dokumentation aktualisieren { #interactive-api-docs-upgrade } Gehen Sie jetzt auf http://127.0.0.1:8000/docs. @@ -311,31 +316,31 @@ Gehen Sie jetzt auf http://127.0.0.1:8000/redoc. +Und jetzt gehen Sie auf http://127.0.0.1:8000/redoc. -* Die alternative Dokumentation wird ebenfalls den neuen Abfrageparameter und -inhalt widerspiegeln: +* Die alternative Dokumentation wird ebenfalls den neuen Query-Parameter und Body widerspiegeln: ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### Zusammenfassung +### Zusammenfassung { #recap } -Zusammengefasst deklarieren Sie **einmal** die Typen von Parametern, Body, etc. als Funktionsparameter. +Zusammengefasst deklarieren Sie **einmal** die Typen von Parametern, Body, usw. als Funktionsparameter. Das machen Sie mit modernen Standard-Python-Typen. Sie mÃŧssen keine neue Syntax, Methoden oder Klassen einer bestimmten Bibliothek usw. lernen. -Nur Standard-**Python+**. +Nur Standard-**Python**. Zum Beispiel fÃŧr ein `int`: @@ -356,22 +361,22 @@ item: Item * TypprÃŧfungen. * Validierung von Daten: * Automatische und eindeutige Fehler, wenn die Daten ungÃŧltig sind. - * Validierung auch fÃŧr tief verschachtelte JSON-Objekte. + * Validierung sogar fÃŧr tief verschachtelte JSON-Objekte. * Konvertierung von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von: * JSON. * Pfad-Parametern. - * Abfrage-Parametern. + * Query-Parametern. * Cookies. - * Header-Feldern. + * Headern. * Formularen. * Dateien. * Konvertierung von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON): * Konvertieren von Python-Typen (`str`, `int`, `float`, `bool`, `list`, usw.). - * `Datetime`-Objekte. + * `datetime`-Objekte. * `UUID`-Objekte. * Datenbankmodelle. * ... und viele mehr. -* Automatische interaktive API-Dokumentation, einschließlich 2 alternativer Benutzeroberflächen: +* Automatische interaktive API-Dokumentation, einschließlich zwei alternativer Benutzeroberflächen: * Swagger UI. * ReDoc. @@ -379,13 +384,13 @@ item: Item Um auf das vorherige Codebeispiel zurÃŧckzukommen, **FastAPI** wird: -* ÜberprÃŧfen, dass es eine `item_id` im Pfad fÃŧr `GET`- und `PUT`-Anfragen gibt. -* ÜberprÃŧfen, ob die `item_id` vom Typ `int` fÃŧr `GET`- und `PUT`-Anfragen ist. - * Falls nicht, wird dem Client ein nÃŧtzlicher, eindeutiger Fehler angezeigt. -* PrÃŧfen, ob es einen optionalen Abfrageparameter namens `q` (wie in `http://127.0.0.1:8000/items/foo?q=somequery`) fÃŧr `GET`-Anfragen gibt. +* Validieren, dass es eine `item_id` im Pfad fÃŧr `GET`- und `PUT`-Requests gibt. +* Validieren, ob die `item_id` vom Typ `int` fÃŧr `GET`- und `PUT`-Requests ist. + * Falls nicht, sieht der Client einen hilfreichen, klaren Fehler. +* PrÃŧfen, ob es einen optionalen Query-Parameter namens `q` (wie in `http://127.0.0.1:8000/items/foo?q=somequery`) fÃŧr `GET`-Requests gibt. * Da der `q`-Parameter mit `= None` deklariert ist, ist er optional. * Ohne das `None` wäre er erforderlich (wie der Body im Fall von `PUT`). -* Bei `PUT`-Anfragen an `/items/{item_id}` den Body als JSON lesen: +* Bei `PUT`-Requests an `/items/{item_id}` den Body als JSON lesen: * PrÃŧfen, ob er ein erforderliches Attribut `name` hat, das ein `str` sein muss. * PrÃŧfen, ob er ein erforderliches Attribut `price` hat, das ein `float` sein muss. * PrÃŧfen, ob er ein optionales Attribut `is_offer` hat, das ein `bool` sein muss, falls vorhanden. @@ -394,7 +399,7 @@ Um auf das vorherige Codebeispiel zurÃŧckzukommen, **FastAPI** wird: * Alles mit OpenAPI dokumentieren, welches verwendet werden kann von: * Interaktiven Dokumentationssystemen. * Automatisch Client-Code generierenden Systemen fÃŧr viele Sprachen. -* Zwei interaktive Dokumentation-Webschnittstellen direkt zur VerfÃŧgung stellen. +* Zwei interaktive Dokumentations-Weboberflächen direkt bereitstellen. --- @@ -418,57 +423,79 @@ Versuchen Sie, diese Zeile zu ändern: ... "item_price": item.price ... ``` -... und sehen Sie, wie Ihr Editor die Attribute automatisch ausfÃŧllt und ihre Typen kennt: +... und sehen Sie, wie Ihr Editor die Attribute automatisch vervollständigt und ihre Typen kennt: ![Editor UnterstÃŧtzung](https://fastapi.tiangolo.com/img/vscode-completion.png) -FÃŧr ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das Tutorial - Benutzerhandbuch. +FÃŧr ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das Tutorial – Benutzerhandbuch. -**Spoiler-Alarm**: Das Tutorial - Benutzerhandbuch enthält: +**Spoiler-Alarm**: Das Tutorial – Benutzerhandbuch enthält: -* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header-Felder**, **Cookies**, **Formularfelder** und **Dateien**. -* Wie man **Validierungseinschränkungen** wie `maximum_length` oder `regex` setzt. +* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header**, **Cookies**, **Formularfelder** und **Dateien**. +* Wie man **Validierungs-Constraints** wie `maximum_length` oder `regex` setzt. * Ein sehr leistungsfähiges und einfach zu bedienendes System fÃŧr **Dependency Injection**. -* Sicherheit und Authentifizierung, einschließlich UnterstÃŧtzung fÃŧr **OAuth2** mit **JWT-Tokens** und **HTTP-Basic**-Authentifizierung. +* Sicherheit und Authentifizierung, einschließlich UnterstÃŧtzung fÃŧr **OAuth2** mit **JWT-Tokens** und **HTTP Basic** Authentifizierung. * Fortgeschrittenere (aber ebenso einfache) Techniken zur Deklaration **tief verschachtelter JSON-Modelle** (dank Pydantic). -* **GraphQL** Integration mit Strawberry und anderen Bibliotheken. -* Viele zusätzliche Funktionen (dank Starlette) wie: +* **GraphQL**-Integration mit Strawberry und anderen Bibliotheken. +* Viele zusätzliche Features (dank Starlette) wie: * **WebSockets** - * extrem einfache Tests auf Basis von `httpx` und `pytest` + * extrem einfache Tests auf Basis von HTTPX und `pytest` * **CORS** - * **Cookie Sessions** + * **Cookie-Sessions** * ... und mehr. -## Performanz +## Performanz { #performance } -Unabhängige TechEmpower-Benchmarks zeigen **FastAPI**-Anwendungen, die unter Uvicorn laufen, als eines der schnellsten verfÃŧgbaren Python-Frameworks, nur noch hinter Starlette und Uvicorn selbst (intern von FastAPI verwendet). +Unabhängige TechEmpower-Benchmarks zeigen **FastAPI**-Anwendungen, die unter Uvicorn laufen, als eines der schnellsten verfÃŧgbaren Python-Frameworks, nur hinter Starlette und Uvicorn selbst (intern von FastAPI verwendet). (*) -Um mehr darÃŧber zu erfahren, siehe den Abschnitt Benchmarks. +Um mehr darÃŧber zu erfahren, siehe den Abschnitt Benchmarks. -## Optionale Abhängigkeiten +## Abhängigkeiten { #dependencies } -Wird von Pydantic verwendet: +FastAPI hängt von Pydantic und Starlette ab. -* email-validator - fÃŧr E-Mail-Validierung. -* pydantic-settings - fÃŧr die Verwaltung von Einstellungen. -* pydantic-extra-types - fÃŧr zusätzliche Typen, mit Pydantic zu verwenden. +### `standard`-Abhängigkeiten { #standard-dependencies } -Wird von Starlette verwendet: +Wenn Sie FastAPI mit `pip install "fastapi[standard]"` installieren, kommt es mit der `standard`-Gruppe optionaler Abhängigkeiten: -* httpx - erforderlich, wenn Sie den `TestClient` verwenden mÃļchten. -* jinja2 - erforderlich, wenn Sie die Standardkonfiguration fÃŧr Templates verwenden mÃļchten. -* python-multipart - erforderlich, wenn Sie Formulare mittels `request.form()` „parsen“ mÃļchten. -* itsdangerous - erforderlich fÃŧr `SessionMiddleware` UnterstÃŧtzung. -* pyyaml - erforderlich fÃŧr Starlette's `SchemaGenerator` UnterstÃŧtzung (Sie brauchen das wahrscheinlich nicht mit FastAPI). -* ujson - erforderlich, wenn Sie `UJSONResponse` verwenden mÃļchten. +Verwendet von Pydantic: -Wird von FastAPI / Starlette verwendet: +* email-validator – fÃŧr E-Mail-Validierung. -* uvicorn - fÃŧr den Server, der Ihre Anwendung lädt und serviert. -* orjson - erforderlich, wenn Sie `ORJSONResponse` verwenden mÃļchten. +Verwendet von Starlette: -Sie kÃļnnen diese alle mit `pip install "fastapi[all]"` installieren. +* httpx – erforderlich, wenn Sie den `TestClient` verwenden mÃļchten. +* jinja2 – erforderlich, wenn Sie die Default-Template-Konfiguration verwenden mÃļchten. +* python-multipart – erforderlich, wenn Sie Formulare mittels `request.form()` „parsen“ mÃļchten. -## Lizenz +Verwendet von FastAPI: + +* uvicorn – fÃŧr den Server, der Ihre Anwendung lädt und bereitstellt. Dies umfasst `uvicorn[standard]`, das einige Abhängigkeiten (z. B. `uvloop`) beinhaltet, die fÃŧr eine Bereitstellung mit hoher Performanz benÃļtigt werden. +* `fastapi-cli[standard]` – um den `fastapi`-Befehl bereitzustellen. + * Dies beinhaltet `fastapi-cloud-cli`, das es Ihnen ermÃļglicht, Ihre FastAPI-Anwendung auf FastAPI Cloud bereitzustellen. + +### Ohne `standard`-Abhängigkeiten { #without-standard-dependencies } + +Wenn Sie die `standard` optionalen Abhängigkeiten nicht einschließen mÃļchten, kÃļnnen Sie mit `pip install fastapi` statt `pip install "fastapi[standard]"` installieren. + +### Ohne `fastapi-cloud-cli` { #without-fastapi-cloud-cli } + +Wenn Sie FastAPI mit den Standardabhängigkeiten, aber ohne das `fastapi-cloud-cli` installieren mÃļchten, kÃļnnen Sie mit `pip install "fastapi[standard-no-fastapi-cloud-cli]"` installieren. + +### Zusätzliche optionale Abhängigkeiten { #additional-optional-dependencies } + +Es gibt einige zusätzliche Abhängigkeiten, die Sie installieren mÃļchten. + +Zusätzliche optionale Pydantic-Abhängigkeiten: + +* pydantic-settings – fÃŧr die Verwaltung von Einstellungen. +* pydantic-extra-types – fÃŧr zusätzliche Typen zur Verwendung mit Pydantic. + +Zusätzliche optionale FastAPI-Abhängigkeiten: + +* orjson – erforderlich, wenn Sie `ORJSONResponse` verwenden mÃļchten. +* ujson – erforderlich, wenn Sie `UJSONResponse` verwenden mÃļchten. + +## Lizenz { #license } Dieses Projekt ist unter den Bedingungen der MIT-Lizenz lizenziert. diff --git a/docs/de/docs/learn/index.md b/docs/de/docs/learn/index.md index b5582f55b..e1f583fb3 100644 --- a/docs/de/docs/learn/index.md +++ b/docs/de/docs/learn/index.md @@ -1,5 +1,5 @@ -# Lernen +# Lernen { #learn } -Hier finden Sie die einfÃŧhrenden Kapitel und Tutorials zum Erlernen von **FastAPI**. +Hier sind die einfÃŧhrenden Abschnitte und Tutorials, um **FastAPI** zu lernen. Sie kÃļnnten dies als **Buch**, als **Kurs**, als **offizielle** und empfohlene Methode zum Erlernen von FastAPI betrachten. 😎 diff --git a/docs/de/docs/project-generation.md b/docs/de/docs/project-generation.md index c47bcb6d3..e6da4949c 100644 --- a/docs/de/docs/project-generation.md +++ b/docs/de/docs/project-generation.md @@ -1,84 +1,28 @@ -# Projektgenerierung – Vorlage +# Full Stack FastAPI Template { #full-stack-fastapi-template } -Sie kÃļnnen einen Projektgenerator fÃŧr den Einstieg verwenden, welcher einen Großteil der Ersteinrichtung, Sicherheit, Datenbank und einige API-Endpunkte bereits fÃŧr Sie erstellt. +Vorlagen, die normalerweise mit einem bestimmten Setup geliefert werden, sind so konzipiert, dass sie flexibel und anpassbar sind. Dies ermÃļglicht es Ihnen, sie zu ändern und an die Anforderungen Ihres Projekts anzupassen und sie somit zu einem hervorragenden Ausgangspunkt zu machen. 🏁 -Ein Projektgenerator verfÃŧgt immer Ãŧber ein sehr spezifisches Setup, das Sie aktualisieren und an Ihre eigenen BedÃŧrfnisse anpassen sollten, aber es kÃļnnte ein guter Ausgangspunkt fÃŧr Ihr Projekt sein. +Sie kÃļnnen diese Vorlage verwenden, um loszulegen, da sie bereits vieles der anfänglichen Einrichtung, Sicherheit, Datenbank und einige API-Endpunkte fÃŧr Sie eingerichtet hat. -## Full Stack FastAPI PostgreSQL +GitHub-Repository: Full Stack FastAPI Template -GitHub: https://github.com/tiangolo/full-stack-fastapi-postgresql +## Full Stack FastAPI Template – Technologiestack und Funktionen { #full-stack-fastapi-template-technology-stack-and-features } -### Full Stack FastAPI PostgreSQL – Funktionen - -* Vollständige **Docker**-Integration (Docker-basiert). -* Docker-Schwarmmodus-Deployment. -* **Docker Compose**-Integration und Optimierung fÃŧr die lokale Entwicklung. -* **Produktionsbereit** Python-Webserver, verwendet Uvicorn und Gunicorn. -* Python **FastAPI**-Backend: - * **Schnell**: Sehr hohe Leistung, auf AugenhÃļhe mit **NodeJS** und **Go** (dank Starlette und Pydantic). - * **Intuitiv**: Hervorragende Editor-UnterstÃŧtzung. Codevervollständigung Ãŧberall. Weniger Zeitaufwand fÃŧr das Debuggen. - * **Einfach**: Einfach zu bedienen und zu erlernen. Weniger Zeit fÃŧr das Lesen von Dokumentationen. - * **Kurz**: Codeverdoppelung minimieren. Mehrere Funktionalitäten aus jeder Parameterdeklaration. - * **Robust**: Erhalten Sie produktionsbereiten Code. Mit automatischer, interaktiver Dokumentation. - * **Standards-basiert**: Basierend auf (und vollständig kompatibel mit) den offenen Standards fÃŧr APIs: OpenAPI und JSON Schema. - * **Viele weitere Funktionen**, einschließlich automatischer Validierung, Serialisierung, interaktiver Dokumentation, Authentifizierung mit OAuth2-JWT-Tokens, usw. -* **Sicheres Passwort**-Hashing standardmäßig. -* **JWT-Token**-Authentifizierung. -* **SQLAlchemy**-Modelle (unabhängig von Flask-Erweiterungen, sodass sie direkt mit Celery-Workern verwendet werden kÃļnnen). -* Grundlegende Startmodelle fÃŧr Benutzer (ändern und entfernen Sie nach Bedarf). -* **Alembic**-Migrationen. -* **CORS** (Cross Origin Resource Sharing). -* **Celery**-Worker, welche Modelle und Code aus dem Rest des Backends selektiv importieren und verwenden kÃļnnen. -* REST-Backend-Tests basierend auf **Pytest**, integriert in Docker, sodass Sie die vollständige API-Interaktion unabhängig von der Datenbank testen kÃļnnen. Da es in Docker ausgefÃŧhrt wird, kann jedes Mal ein neuer Datenspeicher von Grund auf erstellt werden (Sie kÃļnnen also ElasticSearch, MongoDB, CouchDB oder was auch immer Sie mÃļchten verwenden und einfach testen, ob die API funktioniert). -* Einfache Python-Integration mit **Jupyter-Kerneln** fÃŧr Remote- oder In-Docker-Entwicklung mit Erweiterungen wie Atom Hydrogen oder Visual Studio Code Jupyter. -* **Vue**-Frontend: - * Mit Vue CLI generiert. - * Handhabung der **JWT-Authentifizierung**. - * Login-View. - * Nach der Anmeldung Hauptansicht des Dashboards. - * Haupt-Dashboard mit Benutzererstellung und -bearbeitung. - * Bearbeitung des eigenen Benutzers. - * **Vuex**. - * **Vue-Router**. - * **Vuetify** fÃŧr schÃļne Material-Designkomponenten. - * **TypeScript**. - * Docker-Server basierend auf **Nginx** (konfiguriert, um gut mit Vue-Router zu funktionieren). - * Mehrstufigen Docker-Erstellung, sodass Sie kompilierten Code nicht speichern oder committen mÃŧssen. - * Frontend-Tests, welche zur Erstellungszeit ausgefÃŧhrt werden (kÃļnnen auch deaktiviert werden). - * So modular wie mÃļglich gestaltet, sodass es sofort einsatzbereit ist. Sie kÃļnnen es aber mit Vue CLI neu generieren oder es so wie Sie mÃļchten erstellen und wiederverwenden, was Sie mÃļchten. -* **PGAdmin** fÃŧr die PostgreSQL-Datenbank, kÃļnnen Sie problemlos ändern, sodass PHPMyAdmin und MySQL verwendet wird. -* **Flower** fÃŧr die Überwachung von Celery-Jobs. -* Load Balancing zwischen Frontend und Backend mit **Traefik**, sodass Sie beide unter derselben Domain haben kÃļnnen, getrennt durch den Pfad, aber von unterschiedlichen Containern ausgeliefert. -* Traefik-Integration, einschließlich automatischer Generierung von Let's Encrypt-**HTTPS**-Zertifikaten. -* GitLab **CI** (kontinuierliche Integration), einschließlich Frontend- und Backend-Testen. - -## Full Stack FastAPI Couchbase - -GitHub: https://github.com/tiangolo/full-stack-fastapi-couchbase - -âš ī¸ **WARNUNG** âš ī¸ - -Wenn Sie ein neues Projekt von Grund auf starten, prÃŧfen Sie die Alternativen hier. - -Zum Beispiel kÃļnnte der Projektgenerator Full Stack FastAPI PostgreSQL eine bessere Alternative sein, da er aktiv gepflegt und genutzt wird. Und er enthält alle neuen Funktionen und Verbesserungen. - -Es steht Ihnen weiterhin frei, den Couchbase-basierten Generator zu verwenden, wenn Sie mÃļchten. Er sollte wahrscheinlich immer noch gut funktionieren, und wenn Sie bereits ein Projekt damit erstellt haben, ist das auch in Ordnung (und Sie haben es wahrscheinlich bereits an Ihre BedÃŧrfnisse angepasst). - -Weitere Informationen hierzu finden Sie in der Dokumentation des Repos. - -## Full Stack FastAPI MongoDB - -... kÃļnnte später kommen, abhängig von meiner verfÃŧgbaren Zeit und anderen Faktoren. 😅 🎉 - -## Modelle fÃŧr maschinelles Lernen mit spaCy und FastAPI - -GitHub: https://github.com/microsoft/cookiecutter-spacy-fastapi - -### Modelle fÃŧr maschinelles Lernen mit spaCy und FastAPI – Funktionen - -* **spaCy** NER-Modellintegration. -* **Azure Cognitive Search**-Anforderungsformat integriert. -* **Produktionsbereit** Python-Webserver, verwendet Uvicorn und Gunicorn. -* **Azure DevOps** Kubernetes (AKS) CI/CD-Deployment integriert. -* **Mehrsprachig** Wählen Sie bei der Projekteinrichtung ganz einfach eine der integrierten Sprachen von spaCy aus. -* **Einfach erweiterbar** auf andere Modellframeworks (Pytorch, Tensorflow), nicht nur auf SpaCy. +- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/de) fÃŧr die Python-Backend-API. + - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) fÃŧr die Interaktion mit der Python-SQL-Datenbank (ORM). + - 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, fÃŧr die Datenvalidierung und das Einstellungsmanagement. + - 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank. +- 🚀 [React](https://react.dev) fÃŧr das Frontend. + - 💃 Verwendung von TypeScript, Hooks, [Vite](https://vitejs.dev) und anderen Teilen eines modernen Frontend-Stacks. + - 🎨 [Chakra UI](https://chakra-ui.com) fÃŧr die Frontend-Komponenten. + - 🤖 Ein automatisch generierter Frontend-Client. + - đŸ§Ē [Playwright](https://playwright.dev) fÃŧr End-to-End-Tests. + - đŸĻ‡ UnterstÃŧtzung des Dunkelmodus. +- 🐋 [Docker Compose](https://www.docker.com) fÃŧr Entwicklung und Produktion. +- 🔒 Sicheres Passwort-Hashing standardmäßig. +- 🔑 JWT-Token-Authentifizierung. +- đŸ“Ģ E-Mail-basierte Passwortwiederherstellung. +- ✅ Tests mit [Pytest](https://pytest.org). +- 📞 [Traefik](https://traefik.io) als Reverse-Proxy / Load Balancer. +- đŸšĸ Deployment-Anleitungen unter Verwendung von Docker Compose, einschließlich der Einrichtung eines Frontend-Traefik-Proxys zur Handhabung automatischer HTTPS-Zertifikate. +- 🏭 CI (kontinuierliche Integration) und CD (kontinuierliche Bereitstellung) basierend auf GitHub Actions. diff --git a/docs/de/docs/python-types.md b/docs/de/docs/python-types.md index 81d43bc5b..317ee4e62 100644 --- a/docs/de/docs/python-types.md +++ b/docs/de/docs/python-types.md @@ -1,8 +1,8 @@ -# EinfÃŧhrung in Python-Typen +# EinfÃŧhrung in Python-Typen { #python-types-intro } -Python hat UnterstÃŧtzung fÃŧr optionale „Typhinweise“ (Englisch: „Type Hints“). Auch „Typ Annotationen“ genannt. +Python hat UnterstÃŧtzung fÃŧr optionale „Typhinweise“ (auch „Typannotationen“ genannt). -Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den Typ einer Variablen zu deklarieren. +Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den Typ einer Variablen zu deklarieren. Durch das Deklarieren von Typen fÃŧr Ihre Variablen kÃļnnen Editoren und Tools bessere UnterstÃŧtzung bieten. @@ -18,7 +18,7 @@ Wenn Sie ein Python-Experte sind und bereits alles Ãŧber Typhinweise wissen, Ãŧb /// -## Motivation +## Motivation { #motivation } Fangen wir mit einem einfachen Beispiel an: @@ -38,7 +38,7 @@ Die Funktion macht Folgendes: {* ../../docs_src/python_types/tutorial001.py hl[2] *} -### Bearbeiten Sie es +### Es bearbeiten { #edit-it } Es ist ein sehr einfaches Programm. @@ -58,7 +58,7 @@ Aber leider erhalten Sie nichts NÃŧtzliches: -### Typen hinzufÃŧgen +### Typen hinzufÃŧgen { #add-types } Lassen Sie uns eine einzelne Zeile aus der vorherigen Version ändern. @@ -102,7 +102,7 @@ Hier kÃļnnen Sie durch die Optionen blättern, bis Sie diejenige finden, bei der -## Mehr Motivation +## Mehr Motivation { #more-motivation } Sehen Sie sich diese Funktion an, sie hat bereits Typhinweise: @@ -116,13 +116,13 @@ Jetzt, da Sie wissen, dass Sie das reparieren mÃŧssen, konvertieren Sie `age` mi {* ../../docs_src/python_types/tutorial004.py hl[2] *} -## Deklarieren von Typen +## Deklarieren von Typen { #declaring-types } Sie haben gerade den Haupt-Einsatzort fÃŧr die Deklaration von Typhinweisen gesehen. Als Funktionsparameter. Das ist auch meistens, wie sie in **FastAPI** verwendet werden. -### Einfache Typen +### Einfache Typen { #simple-types } Sie kÃļnnen alle Standard-Python-Typen deklarieren, nicht nur `str`. @@ -135,7 +135,7 @@ Zum Beispiel diese: {* ../../docs_src/python_types/tutorial005.py hl[1] *} -### Generische Typen mit Typ-Parametern +### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters } Es gibt Datenstrukturen, die andere Werte enthalten kÃļnnen, wie etwa `dict`, `list`, `set` und `tuple`. Die inneren Werte kÃļnnen auch ihren eigenen Typ haben. @@ -143,7 +143,7 @@ Diese Typen mit inneren Typen werden „**generische**“ Typen genannt. Es ist Um diese Typen und die inneren Typen zu deklarieren, kÃļnnen Sie Pythons Standardmodul `typing` verwenden. Es existiert speziell fÃŧr die UnterstÃŧtzung dieser Typhinweise. -#### Neuere Python-Versionen +#### Neuere Python-Versionen { #newer-versions-of-python } Die Syntax, welche `typing` verwendet, ist **kompatibel** mit allen Versionen, von Python 3.6 aufwärts zu den neuesten, inklusive Python 3.9, Python 3.10, usw. @@ -157,7 +157,7 @@ Zum Beispiel bedeutet „**Python 3.6+**“, dass das Beispiel kompatibel mit Py Wenn Sie Ãŧber die **neueste Version von Python** verfÃŧgen, verwenden Sie die Beispiele fÃŧr die neueste Version, diese werden die **beste und einfachste Syntax** haben, zum Beispiel, „**Python 3.10+**“. -#### Liste +#### Liste { #list } Definieren wir zum Beispiel eine Variable, die eine `list` von `str` – eine Liste von Strings – sein soll. @@ -195,7 +195,7 @@ Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckige //// -/// tip | Tipp +/// info | Info Die inneren Typen in den eckigen Klammern werden als „Typ-Parameter“ bezeichnet. @@ -221,7 +221,7 @@ Beachten Sie, dass die Variable `item` eines der Elemente in der Liste `items` i Und trotzdem weiß der Editor, dass es sich um ein `str` handelt, und bietet entsprechende UnterstÃŧtzung. -#### Tupel und Menge +#### Tupel und Menge { #tuple-and-set } Das Gleiche gilt fÃŧr die Deklaration eines Tupels – `tuple` – und einer Menge – `set`: @@ -246,7 +246,7 @@ Das bedeutet: * Die Variable `items_t` ist ein `tuple` mit 3 Elementen, einem `int`, einem weiteren `int` und einem `str`. * Die Variable `items_s` ist ein `set`, und jedes seiner Elemente ist vom Typ `bytes`. -#### Dict +#### Dict { #dict } Um ein `dict` zu definieren, Ãŧbergeben Sie zwei Typ-Parameter, getrennt durch Kommas. @@ -276,7 +276,7 @@ Das bedeutet: * Die SchlÃŧssel dieses `dict` sind vom Typ `str` (z. B. die Namen der einzelnen Artikel). * Die Werte dieses `dict` sind vom Typ `float` (z. B. der Preis jedes Artikels). -#### Union +#### Union { #union } Sie kÃļnnen deklarieren, dass eine Variable einer von **verschiedenen Typen** sein kann, zum Beispiel ein `int` oder ein `str`. @@ -302,13 +302,15 @@ In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die mÃļ In beiden Fällen bedeutet das, dass `item` ein `int` oder ein `str` sein kann. -#### Vielleicht `None` +#### Vielleicht `None` { #possibly-none } Sie kÃļnnen deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` sein kann. In Python 3.6 und darÃŧber (inklusive Python 3.10) kÃļnnen Sie das deklarieren, indem Sie `Optional` vom `typing` Modul importieren und verwenden. -{* ../../docs_src/python_types/tutorial009.py hl[1,4] *} +```Python hl_lines="1 4" +{!../../docs_src/python_types/tutorial009.py!} +``` Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen kÃļnnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein kÃļnnte. @@ -340,7 +342,7 @@ Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden kÃļnnen: //// -#### `Union` oder `Optional` verwenden? +#### `Union` oder `Optional` verwenden? { #using-union-or-optional } Wenn Sie eine Python-Version unterhalb 3.10 verwenden, hier ist mein sehr **subjektiver** Standpunkt dazu: @@ -366,7 +368,7 @@ say_hi() # Oh, nein, das lÃļst einen Fehler aus! 😱 Der `name` Parameter wird **immer noch benÃļtigt** (nicht *optional*), weil er keinen Default-Wert hat. `name` akzeptiert aber dennoch `None` als Wert: ```Python -say_hi(name=None) # Das funktioniert, None is gÃŧltig 🎉 +say_hi(name=None) # Das funktioniert, None ist gÃŧltig 🎉 ``` Die gute Nachricht ist, dass Sie sich darÃŧber keine Sorgen mehr machen mÃŧssen, wenn Sie Python 3.10 verwenden, da Sie einfach `|` verwenden kÃļnnen, um Vereinigungen von Typen zu definieren: @@ -375,7 +377,7 @@ Die gute Nachricht ist, dass Sie sich darÃŧber keine Sorgen mehr machen mÃŧssen, Und dann mÃŧssen Sie sich nicht mehr um Namen wie `Optional` und `Union` kÃŧmmern. 😎 -#### Generische Typen +#### Generische Typen { #generic-types } Diese Typen, die Typ-Parameter in eckigen Klammern akzeptieren, werden **generische Typen** oder **Generics** genannt. @@ -427,7 +429,7 @@ Verwenden Sie fÃŧr den Rest, wie unter Python 3.8, das `typing`-Modul: //// -### Klassen als Typen +### Klassen als Typen { #classes-as-types } Sie kÃļnnen auch eine Klasse als Typ einer Variablen deklarieren. @@ -447,9 +449,9 @@ Beachten Sie, das bedeutet: „`one_person` ist eine **Instanz** der Klasse `Per Es bedeutet nicht: „`one_person` ist die **Klasse** genannt `Person`“. -## Pydantic Modelle +## Pydantic-Modelle { #pydantic-models } -Pydantic ist eine Python-Bibliothek fÃŧr die Validierung von Daten. +Pydantic ist eine Python-Bibliothek fÃŧr die Validierung von Daten. Sie deklarieren die „Form“ der Daten als Klassen mit Attributen. @@ -485,25 +487,25 @@ Ein Beispiel aus der offiziellen Pydantic Dokumentation: //// -/// info +/// info | Info -Um mehr Ãŧber Pydantic zu erfahren, schauen Sie sich dessen Dokumentation an. +Um mehr Ãŧber Pydantic zu erfahren, schauen Sie sich dessen Dokumentation an. /// **FastAPI** basiert vollständig auf Pydantic. -Viel mehr von all dem werden Sie in praktischer Anwendung im [Tutorial - Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank} sehen. +Viel mehr von all dem werden Sie in praktischer Anwendung im [Tutorial – Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank} sehen. /// tip | Tipp -Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Etwas, None]` ohne einen Default-Wert verwenden. Sie kÃļnnen darÃŧber in der Pydantic Dokumentation unter Required fields mehr erfahren. +Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None]` ohne einen Defaultwert verwenden. Sie kÃļnnen darÃŧber in der Pydantic Dokumentation unter Erforderliche optionale Felder mehr erfahren. /// -## Typhinweise mit Metadaten-Annotationen +## Typhinweise mit Metadaten-Annotationen { #type-hints-with-metadata-annotations } -Python bietet auch die MÃļglichkeit, **zusätzliche Metadaten** in Typhinweisen unterzubringen, mittels `Annotated`. +Python bietet auch die MÃļglichkeit, **zusätzliche Metadaten** in Typhinweisen unterzubringen, mittels `Annotated`. //// tab | Python 3.9+ @@ -529,7 +531,7 @@ Es wird bereits mit **FastAPI** installiert sein. Python selbst macht nichts mit `Annotated`. FÃŧr Editoren und andere Tools ist der Typ immer noch `str`. -Aber Sie kÃļnnen `Annotated` nutzen, um **FastAPI** mit Metadaten zu versorgen, die ihm sagen, wie sich ihre Anwendung verhalten soll. +Aber Sie kÃļnnen `Annotated` nutzen, um **FastAPI** mit Metadaten zu versorgen, die ihm sagen, wie sich Ihre Anwendung verhalten soll. Wichtig ist, dass **der erste *Typ-Parameter***, den Sie `Annotated` Ãŧbergeben, der **tatsächliche Typ** ist. Der Rest sind Metadaten fÃŧr andere Tools. @@ -539,13 +541,13 @@ Später werden Sie sehen, wie **mächtig** es sein kann. /// tip | Tipp -Der Umstand, dass es **Standard-Python** ist, bedeutet, dass Sie immer noch die **bestmÃļgliche Entwickler-Erfahrung** in ihrem Editor haben, sowie mit den Tools, die Sie nutzen, um ihren Code zu analysieren, zu refaktorisieren, usw. ✨ +Der Umstand, dass es **Standard-Python** ist, bedeutet, dass Sie immer noch die **bestmÃļgliche Entwickler-Erfahrung** in Ihrem Editor haben, sowie mit den Tools, die Sie nutzen, um Ihren Code zu analysieren, zu refaktorisieren, usw. ✨ Und ebenfalls, dass Ihr Code sehr kompatibel mit vielen anderen Python-Tools und -Bibliotheken sein wird. 🚀 /// -## Typhinweise in **FastAPI** +## Typhinweise in **FastAPI** { #type-hints-in-fastapi } **FastAPI** macht sich diese Typhinweise zunutze, um mehrere Dinge zu tun. @@ -556,18 +558,18 @@ Mit **FastAPI** deklarieren Sie Parameter mit Typhinweisen, und Sie erhalten: ... und **FastAPI** verwendet dieselben Deklarationen, um: -* **Anforderungen** zu definieren: aus Anfrage-Pfadparametern, Abfrageparametern, Header-Feldern, Bodys, Abhängigkeiten, usw. -* **Daten umzuwandeln**: aus der Anfrage in den erforderlichen Typ. -* **Daten zu validieren**: aus jeder Anfrage: +* **Anforderungen** zu definieren: aus Request-Pfadparametern, Query-Parametern, Header-Feldern, Bodys, Abhängigkeiten, usw. +* **Daten umzuwandeln**: aus dem Request in den erforderlichen Typ. +* **Daten zu validieren**: aus jedem Request: * **Automatische Fehler** generieren, die an den Client zurÃŧckgegeben werden, wenn die Daten ungÃŧltig sind. * Die API mit OpenAPI zu **dokumentieren**: * Die dann von den Benutzeroberflächen der automatisch generierten interaktiven Dokumentation verwendet wird. -Das mag alles abstrakt klingen. Machen Sie sich keine Sorgen. Sie werden all das in Aktion sehen im [Tutorial - Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank}. +Das mag alles abstrakt klingen. Machen Sie sich keine Sorgen. Sie werden all das in Aktion sehen im [Tutorial – Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank}. Das Wichtigste ist, dass **FastAPI** durch die Verwendung von Standard-Python-Typen an einer einzigen Stelle (anstatt weitere Klassen, Dekoratoren usw. hinzuzufÃŧgen) einen Großteil der Arbeit fÃŧr Sie erledigt. -/// info +/// info | Info Wenn Sie bereits das ganze Tutorial durchgearbeitet haben und mehr Ãŧber Typen erfahren wollen, dann ist eine gute Ressource der „Cheat Sheet“ von `mypy`. diff --git a/docs/de/docs/resources/index.md b/docs/de/docs/resources/index.md index abf270d9f..2c5046c73 100644 --- a/docs/de/docs/resources/index.md +++ b/docs/de/docs/resources/index.md @@ -1,3 +1,3 @@ -# Ressourcen +# Ressourcen { #resources } Zusätzliche Ressourcen, externe Links, Artikel und mehr. âœˆī¸ diff --git a/docs/de/docs/tutorial/background-tasks.md b/docs/de/docs/tutorial/background-tasks.md index 05779e12c..ea85207ce 100644 --- a/docs/de/docs/tutorial/background-tasks.md +++ b/docs/de/docs/tutorial/background-tasks.md @@ -1,8 +1,8 @@ -# Hintergrundtasks +# Hintergrundtasks { #background-tasks } -Sie kÃļnnen Hintergrundtasks (Hintergrund-Aufgaben) definieren, die *nach* der RÃŧckgabe einer Response ausgefÃŧhrt werden sollen. +Sie kÃļnnen Hintergrundtasks definieren, die *nach* der RÃŧckgabe einer Response ausgefÃŧhrt werden sollen. -Das ist nÃŧtzlich fÃŧr Vorgänge, die nach einem Request ausgefÃŧhrt werden mÃŧssen, bei denen der Client jedoch nicht unbedingt auf den Abschluss des Vorgangs warten muss, bevor er die Response erhält. +Das ist nÃŧtzlich fÃŧr Vorgänge, die nach einem Request ausgefÃŧhrt werden mÃŧssen, bei denen der Client jedoch nicht unbedingt auf den Abschluss des Vorgangs warten muss, bevor er die Response erhält. Hierzu zählen beispielsweise: @@ -11,7 +11,7 @@ Hierzu zählen beispielsweise: * Daten verarbeiten: * Angenommen, Sie erhalten eine Datei, die einen langsamen Prozess durchlaufen muss. Sie kÃļnnen als Response „Accepted“ (HTTP 202) zurÃŧckgeben und die Datei im Hintergrund verarbeiten. -## `BackgroundTasks` verwenden +## `BackgroundTasks` verwenden { #using-backgroundtasks } Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`: @@ -19,7 +19,7 @@ Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter i **FastAPI** erstellt fÃŧr Sie das Objekt vom Typ `BackgroundTasks` und Ãŧbergibt es als diesen Parameter. -## Eine Taskfunktion erstellen +## Eine Taskfunktion erstellen { #create-a-task-function } Erstellen Sie eine Funktion, die als Hintergrundtask ausgefÃŧhrt werden soll. @@ -33,7 +33,7 @@ Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir di {* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *} -## Den Hintergrundtask hinzufÃŧgen +## Den Hintergrundtask hinzufÃŧgen { #add-the-background-task } Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt: @@ -45,21 +45,23 @@ Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir di * Eine beliebige Folge von Argumenten, die der Reihe nach an die Taskfunktion Ãŧbergeben werden sollen (`email`). * Alle SchlÃŧsselwort-Argumente, die an die Taskfunktion Ãŧbergeben werden sollen (`message="some notification"`). -## Dependency Injection +## Dependency Injection { #dependency-injection } Die Verwendung von `BackgroundTasks` funktioniert auch mit dem Dependency Injection System. Sie kÃļnnen einen Parameter vom Typ `BackgroundTasks` auf mehreren Ebenen deklarieren: in einer *Pfadoperation-Funktion*, in einer Abhängigkeit (Dependable), in einer Unterabhängigkeit usw. **FastAPI** weiß, was jeweils zu tun ist und wie dasselbe Objekt wiederverwendet werden kann, sodass alle Hintergrundtasks zusammengefÃŧhrt und anschließend im Hintergrund ausgefÃŧhrt werden: + {* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *} + In obigem Beispiel werden die Nachrichten, *nachdem* die Response gesendet wurde, in die Datei `log.txt` geschrieben. Wenn im Request ein Query-Parameter enthalten war, wird dieser in einem Hintergrundtask in das Log geschrieben. Und dann schreibt ein weiterer Hintergrundtask, der in der *Pfadoperation-Funktion* erstellt wird, eine Nachricht unter Verwendung des Pfad-Parameters `email`. -## Technische Details +## Technische Details { #technical-details } Die Klasse `BackgroundTasks` stammt direkt von `starlette.background`. @@ -69,16 +71,16 @@ Indem Sie nur `BackgroundTasks` (und nicht `BackgroundTask`) verwenden, ist es d Es ist immer noch mÃļglich, `BackgroundTask` allein in FastAPI zu verwenden, aber Sie mÃŧssen das Objekt in Ihrem Code erstellen und eine Starlette-`Response` zurÃŧckgeben, die es enthält. -Weitere Details finden Sie in der offiziellen Starlette-Dokumentation fÃŧr Hintergrundtasks. +Weitere Details finden Sie in Starlettes offizieller Dokumentation fÃŧr Hintergrundtasks. -## Vorbehalt +## Vorbehalt { #caveat } Wenn Sie umfangreiche Hintergrundberechnungen durchfÃŧhren mÃŧssen und diese nicht unbedingt vom selben Prozess ausgefÃŧhrt werden mÃŧssen (z. B. mÃŧssen Sie Speicher, Variablen, usw. nicht gemeinsam nutzen), kÃļnnte die Verwendung anderer grÃļßerer Tools wie z. B. Celery von Vorteil sein. Sie erfordern in der Regel komplexere Konfigurationen und einen Nachrichten-/Job-Queue-Manager wie RabbitMQ oder Redis, ermÃļglichen Ihnen jedoch die AusfÃŧhrung von Hintergrundtasks in mehreren Prozessen und insbesondere auf mehreren Servern. -Wenn Sie jedoch Ãŧber dieselbe **FastAPI**-Anwendung auf Variablen und Objekte zugreifen oder kleine Hintergrundtasks ausfÃŧhren mÃŧssen (z. B. das Senden einer E-Mail-Benachrichtigung), kÃļnnen Sie einfach `BackgroundTasks` verwenden. +Wenn Sie jedoch Ãŧber dieselbe **FastAPI**-App auf Variablen und Objekte zugreifen oder kleine Hintergrundtasks ausfÃŧhren mÃŧssen (z. B. das Senden einer E-Mail-Benachrichtigung), kÃļnnen Sie einfach `BackgroundTasks` verwenden. -## Zusammenfassung +## Zusammenfassung { #recap } Importieren und verwenden Sie `BackgroundTasks` mit Parametern in *Pfadoperation-Funktionen* und Abhängigkeiten, um Hintergrundtasks hinzuzufÃŧgen. diff --git a/docs/de/docs/tutorial/bigger-applications.md b/docs/de/docs/tutorial/bigger-applications.md index 514e3fd3a..928d50adf 100644 --- a/docs/de/docs/tutorial/bigger-applications.md +++ b/docs/de/docs/tutorial/bigger-applications.md @@ -1,16 +1,16 @@ -# GrÃļßere Anwendungen – mehrere Dateien +# GrÃļßere Anwendungen – mehrere Dateien { #bigger-applications-multiple-files } Wenn Sie eine Anwendung oder eine Web-API erstellen, ist es selten der Fall, dass Sie alles in einer einzigen Datei unterbringen kÃļnnen. **FastAPI** bietet ein praktisches Werkzeug zur Strukturierung Ihrer Anwendung bei gleichzeitiger Wahrung der Flexibilität. -/// info +/// info | Info Wenn Sie von Flask kommen, wäre dies das Äquivalent zu Flasks Blueprints. /// -## Eine Beispiel-Dateistruktur +## Eine Beispiel-Dateistruktur { #an-example-file-structure } Nehmen wir an, Sie haben eine Dateistruktur wie diese: @@ -71,7 +71,7 @@ Die gleiche Dateistruktur mit Kommentaren: │   └── admin.py # „admin“-Submodul, z. B. import app.internal.admin ``` -## `APIRouter` +## `APIRouter` { #apirouter } Nehmen wir an, die Datei, die nur fÃŧr die Verwaltung von Benutzern zuständig ist, ist das Submodul unter `/app/routers/users.py`. @@ -81,7 +81,7 @@ Aber es ist immer noch Teil derselben **FastAPI**-Anwendung/Web-API (es ist Teil Sie kÃļnnen die *Pfadoperationen* fÃŧr dieses Modul mit `APIRouter` erstellen. -### `APIRouter` importieren +### `APIRouter` importieren { #import-apirouter } Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie mit der Klasse `FastAPI`: @@ -89,7 +89,7 @@ Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie m {!../../docs_src/bigger_applications/app/routers/users.py!} ``` -### *Pfadoperationen* mit `APIRouter` +### *Pfadoperationen* mit `APIRouter` { #path-operations-with-apirouter } Und dann verwenden Sie ihn, um Ihre *Pfadoperationen* zu deklarieren. @@ -113,7 +113,7 @@ In diesem Beispiel heißt die Variable `router`, aber Sie kÃļnnen ihr einen beli Wir werden diesen `APIRouter` in die Hauptanwendung `FastAPI` einbinden, aber zuerst kÃŧmmern wir uns um die Abhängigkeiten und einen anderen `APIRouter`. -## Abhängigkeiten +## Abhängigkeiten { #dependencies } Wir sehen, dass wir einige Abhängigkeiten benÃļtigen, die an mehreren Stellen der Anwendung verwendet werden. @@ -159,7 +159,7 @@ Aber in der Praxis werden Sie mit den integrierten [Sicherheits-Werkzeugen](secu /// -## Ein weiteres Modul mit `APIRouter`. +## Ein weiteres Modul mit `APIRouter` { #another-module-with-apirouter } Nehmen wir an, Sie haben im Modul unter `app/routers/items.py` auch die Endpunkte, die fÃŧr die Verarbeitung von Artikeln („Items“) aus Ihrer Anwendung vorgesehen sind. @@ -199,7 +199,7 @@ Das Präfix lautet in diesem Fall also `/items`. Wir kÃļnnen auch eine Liste von `tags` und zusätzliche `responses` hinzufÃŧgen, die auf alle in diesem Router enthaltenen *Pfadoperationen* angewendet werden. -Und wir kÃļnnen eine Liste von `dependencies` hinzufÃŧgen, die allen *Pfadoperationen* im Router hinzugefÃŧgt und fÃŧr jeden an sie gerichteten Request ausgefÃŧhrt/aufgelÃļst werden. +Und wir kÃļnnen eine Liste von `dependencies` hinzufÃŧgen, die allen *Pfadoperationen* im Router hinzugefÃŧgt und fÃŧr jeden an sie gerichteten Request ausgefÃŧhrt/aufgelÃļst werden. /// tip | Tipp @@ -228,13 +228,13 @@ Das Endergebnis ist, dass die Pfade fÃŧr diese Artikel jetzt wie folgt lauten: /// -/// check +/// check | Testen Die Parameter `prefix`, `tags`, `responses` und `dependencies` sind (wie in vielen anderen Fällen) nur ein Feature von **FastAPI**, um Ihnen dabei zu helfen, Codeverdoppelung zu vermeiden. /// -### Die Abhängigkeiten importieren +### Die Abhängigkeiten importieren { #import-the-dependencies } Der folgende Code befindet sich im Modul `app.routers.items`, also in der Datei `app/routers/items.py`. @@ -246,7 +246,7 @@ Daher verwenden wir einen relativen Import mit `..` fÃŧr die Abhängigkeiten: {!../../docs_src/bigger_applications/app/routers/items.py!} ``` -#### Wie relative Importe funktionieren +#### Wie relative Importe funktionieren { #how-relative-imports-work } /// tip | Tipp @@ -309,7 +309,7 @@ Das wÃŧrde sich auf ein Paket oberhalb von `app/` beziehen, mit seiner eigenen D Aber jetzt wissen Sie, wie es funktioniert, sodass Sie relative Importe in Ihren eigenen Anwendungen verwenden kÃļnnen, egal wie komplex diese sind. 🤓 -### Einige benutzerdefinierte `tags`, `responses`, und `dependencies` hinzufÃŧgen +### Einige benutzerdefinierte `tags`, `responses`, und `dependencies` hinzufÃŧgen { #add-some-custom-tags-responses-and-dependencies } Wir fÃŧgen weder das Präfix `/items` noch `tags=["items"]` zu jeder *Pfadoperation* hinzu, da wir sie zum `APIRouter` hinzugefÃŧgt haben. @@ -323,21 +323,21 @@ Aber wir kÃļnnen immer noch _mehr_ `tags` hinzufÃŧgen, die auf eine bestimmte *P Diese letzte Pfadoperation wird eine Kombination von Tags haben: `["items", "custom"]`. -Und sie wird auch beide Responses in der Dokumentation haben, eine fÃŧr `404` und eine fÃŧr `403`. +Und sie wird auch beide Responses in der Dokumentation haben, eine fÃŧr `404` und eine fÃŧr `403`. /// -## Das Haupt-`FastAPI`. +## Das Haupt-`FastAPI` { #the-main-fastapi } Sehen wir uns nun das Modul unter `app/main.py` an. Hier importieren und verwenden Sie die Klasse `FastAPI`. -Dies ist die Hauptdatei Ihrer Anwendung, die alles zusammen bindet. +Dies ist die Hauptdatei Ihrer Anwendung, die alles zusammenfÃŧgt. Und da sich der Großteil Ihrer Logik jetzt in seinem eigenen spezifischen Modul befindet, wird die Hauptdatei recht einfach sein. -### `FastAPI` importieren +### `FastAPI` importieren { #import-fastapi } Sie importieren und erstellen wie gewohnt eine `FastAPI`-Klasse. @@ -347,7 +347,7 @@ Und wir kÃļnnen sogar [globale Abhängigkeiten](dependencies/global-dependencies {!../../docs_src/bigger_applications/app/main.py!} ``` -### Den `APIRouter` importieren +### Den `APIRouter` importieren { #import-the-apirouter } Jetzt importieren wir die anderen Submodule, die `APIRouter` haben: @@ -357,7 +357,7 @@ Jetzt importieren wir die anderen Submodule, die `APIRouter` haben: Da es sich bei den Dateien `app/routers/users.py` und `app/routers/items.py` um Submodule handelt, die Teil desselben Python-Packages `app` sind, kÃļnnen wir einen einzelnen Punkt `.` verwenden, um sie mit „relativen Imports“ zu importieren. -### Wie das Importieren funktioniert +### Wie das Importieren funktioniert { #how-the-importing-works } Die Sektion: @@ -381,7 +381,7 @@ Wir kÃļnnten sie auch wie folgt importieren: from app.routers import items, users ``` -/// info +/// info | Info Die erste Version ist ein „relativer Import“: @@ -399,7 +399,7 @@ Um mehr Ãŧber Python-Packages und -Module zu erfahren, lesen Sie ```console -$ uvicorn app.main:app --reload +$ fastapi dev app/main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -538,7 +537,7 @@ Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Su -## Den gleichen Router mehrmals mit unterschiedlichem `prefix` inkludieren +## Den gleichen Router mehrmals mit unterschiedlichem `prefix` inkludieren { #include-the-same-router-multiple-times-with-different-prefix } Sie kÃļnnen `.include_router()` auch mehrmals mit *demselben* Router und unterschiedlichen Präfixen verwenden. @@ -546,7 +545,7 @@ Dies kÃļnnte beispielsweise nÃŧtzlich sein, um dieselbe API unter verschiedenen Dies ist eine fortgeschrittene Verwendung, die Sie mÃļglicherweise nicht wirklich benÃļtigen, aber fÃŧr den Fall, dass Sie sie benÃļtigen, ist sie vorhanden. -## Einen `APIRouter` in einen anderen einfÃŧgen +## Einen `APIRouter` in einen anderen einfÃŧgen { #include-an-apirouter-in-another } Auf die gleiche Weise, wie Sie einen `APIRouter` in eine `FastAPI`-Anwendung einbinden kÃļnnen, kÃļnnen Sie einen `APIRouter` in einen anderen `APIRouter` einbinden, indem Sie Folgendes verwenden: diff --git a/docs/de/docs/tutorial/body-fields.md b/docs/de/docs/tutorial/body-fields.md index 9fddfb1f0..b73d57d2d 100644 --- a/docs/de/docs/tutorial/body-fields.md +++ b/docs/de/docs/tutorial/body-fields.md @@ -1,8 +1,8 @@ -# Body – Felder +# Body – Felder { #body-fields } -So wie Sie zusätzliche Validation und Metadaten in Parametern der **Pfadoperation-Funktion** mittels `Query`, `Path` und `Body` deklarieren, kÃļnnen Sie auch innerhalb von Pydantic-Modellen zusätzliche Validation und Metadaten deklarieren, mittels Pydantics `Field`. +So wie Sie zusätzliche Validierung und Metadaten in Parametern der *Pfadoperation-Funktion* mittels `Query`, `Path` und `Body` deklarieren, kÃļnnen Sie auch innerhalb von Pydantic-Modellen zusätzliche Validierung und Metadaten deklarieren, mittels Pydantics `Field`. -## `Field` importieren +## `Field` importieren { #import-field } Importieren Sie es zuerst: @@ -14,7 +14,7 @@ Beachten Sie, dass `Field` direkt von `pydantic` importiert wird, nicht von `fas /// -## Modellattribute deklarieren +## Modellattribute deklarieren { #declare-model-attributes } Dann kÃļnnen Sie `Field` mit Modellattributen deklarieren: @@ -24,23 +24,23 @@ Dann kÃļnnen Sie `Field` mit Modellattributen deklarieren: /// note | Technische Details -Tatsächlich erstellen `Query`, `Path` und andere, die sie kennenlernen werden, Instanzen von Unterklassen einer allgemeinen Klasse `Param`, die ihrerseits eine Unterklasse von Pydantics `FieldInfo`-Klasse ist. +Tatsächlich erstellen `Query`, `Path` und andere, die Sie als nächstes sehen werden, Instanzen von Unterklassen einer allgemeinen Klasse `Param`, welche selbst eine Unterklasse von Pydantics `FieldInfo`-Klasse ist. Und Pydantics `Field` gibt ebenfalls eine Instanz von `FieldInfo` zurÃŧck. -`Body` gibt auch Instanzen einer Unterklasse von `FieldInfo` zurÃŧck. Und später werden Sie andere sehen, die Unterklassen der `Body`-Klasse sind. +`Body` gibt auch direkt Instanzen einer Unterklasse von `FieldInfo` zurÃŧck. Später werden Sie andere sehen, die Unterklassen der `Body`-Klasse sind. -Denken Sie daran, dass `Query`, `Path` und andere von `fastapi` tatsächlich Funktionen sind, die spezielle Klassen zurÃŧckgeben. +Denken Sie daran, dass `Query`, `Path` und andere, wenn Sie sie von `fastapi` importieren, tatsächlich Funktionen sind, die spezielle Klassen zurÃŧckgeben. /// /// tip | Tipp -Beachten Sie, dass jedes Modellattribut mit einem Typ, Defaultwert und `Field` die gleiche Struktur hat wie ein Parameter einer Pfadoperation-Funktion, nur mit `Field` statt `Path`, `Query`, `Body`. +Beachten Sie, wie jedes Attribut eines Modells mit einem Typ, Defaultwert und `Field` die gleiche Struktur hat wie ein Parameter einer *Pfadoperation-Funktion*, nur mit `Field` statt `Path`, `Query`, `Body`. /// -## Zusätzliche Information hinzufÃŧgen +## Zusätzliche Information hinzufÃŧgen { #add-extra-information } Sie kÃļnnen zusätzliche Information in `Field`, `Query`, `Body`, usw. deklarieren. Und es wird im generierten JSON-Schema untergebracht. @@ -48,12 +48,12 @@ Sie werden später mehr darÃŧber lernen, wie man zusätzliche Information unterb /// warning | Achtung -Extra-SchlÃŧssel, die `Field` Ãŧberreicht werden, werden auch im resultierenden OpenAPI-Schema Ihrer Anwendung gelistet. Da diese SchlÃŧssel nicht notwendigerweise Teil der OpenAPI-Spezifikation sind, kÃļnnten einige OpenAPI-Tools, wie etwa [der OpenAPI-Validator](https://validator.swagger.io/), nicht mit Ihrem generierten Schema funktionieren. +Extra-SchlÃŧssel, die `Field` Ãŧberreicht werden, werden auch im resultierenden OpenAPI-Schema Ihrer Anwendung gelistet. Da diese SchlÃŧssel mÃļglicherweise nicht Teil der OpenAPI-Spezifikation sind, kÃļnnten einige OpenAPI-Tools, wie etwa [der OpenAPI-Validator](https://validator.swagger.io/), nicht mit Ihrem generierten Schema funktionieren. /// -## Zusammenfassung +## Zusammenfassung { #recap } Sie kÃļnnen Pydantics `Field` verwenden, um zusätzliche Validierungen und Metadaten fÃŧr Modellattribute zu deklarieren. -Sie kÃļnnen auch Extra-SchlÃŧssel verwenden, um zusätzliche JSON-Schema-Metadaten zu Ãŧberreichen. +Sie kÃļnnen auch die zusätzlichen SchlÃŧsselwortargumente verwenden, um zusätzliche JSON-Schema-Metadaten zu Ãŧbergeben. diff --git a/docs/de/docs/tutorial/body-multiple-params.md b/docs/de/docs/tutorial/body-multiple-params.md index 8a9978d34..3b5fa52dd 100644 --- a/docs/de/docs/tutorial/body-multiple-params.md +++ b/docs/de/docs/tutorial/body-multiple-params.md @@ -1,8 +1,8 @@ -# Body – Mehrere Parameter +# Body – Mehrere Parameter { #body-multiple-parameters } -Jetzt, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere VerwendungsmÃļglichkeiten von Requestbody-Deklarationen an. +Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere VerwendungsmÃļglichkeiten von Requestbody-Deklarationen an. -## `Path`-, `Query`- und Body-Parameter vermischen +## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters } Zuerst einmal, Sie kÃļnnen `Path`-, `Query`- und Requestbody-Parameter-Deklarationen frei mischen und **FastAPI** wird wissen, was zu tun ist. @@ -16,9 +16,9 @@ Beachten Sie, dass in diesem Fall das `item`, welches vom Body genommen wird, op /// -## Mehrere Body-Parameter +## Mehrere Body-Parameter { #multiple-body-parameters } -Im vorherigen Beispiel erwartete die *Pfadoperation* einen JSON-Body mit den Attributen eines `Item`s, etwa: +Im vorherigen Beispiel erwarteten die *Pfadoperationen* einen JSON-Body mit den Attributen eines `Item`s, etwa: ```JSON { @@ -35,7 +35,7 @@ Aber Sie kÃļnnen auch mehrere Body-Parameter deklarieren, z. B. `item` und `user In diesem Fall wird **FastAPI** bemerken, dass es mehr als einen Body-Parameter in der Funktion gibt (zwei Parameter, die Pydantic-Modelle sind). -Es wird deshalb die Parameternamen als SchlÃŧssel (Feldnamen) im Body verwenden, und erwartet einen Body wie folgt: +Es wird deshalb die Parameternamen als SchlÃŧssel (Feldnamen) im Body verwenden und erwartet einen Body wie folgt: ```JSON { @@ -58,17 +58,17 @@ Beachten Sie, dass, obwohl `item` wie zuvor deklariert wurde, es nun unter einem /// -**FastAPI** wird die automatische Konvertierung des Requests Ãŧbernehmen, sodass der Parameter `item` seinen spezifischen Inhalt bekommt, genau so wie der Parameter `user`. +**FastAPI** wird die automatische Konvertierung des Requests Ãŧbernehmen, sodass der Parameter `item` seinen spezifischen Inhalt bekommt, und das Gleiche gilt fÃŧr den Parameter `user`. -Es wird die Validierung dieser zusammengesetzten Daten Ãŧbernehmen, und sie im OpenAPI-Schema und der automatischen Dokumentation dokumentieren. +Es wird die Validierung dieser zusammengesetzten Daten Ãŧbernehmen, und diese im OpenAPI-Schema und der automatischen Dokumentation dokumentieren. -## Einzelne Werte im Body +## Einzelne Werte im Body { #singular-values-in-body } -So wie `Query` und `Path` fÃŧr Query- und Pfad-Parameter, hat **FastAPI** auch das Äquivalent `Body`, um Extra-Daten fÃŧr Body-Parameter zu definieren. +So wie `Query` und `Path` fÃŧr Query- und Pfad-Parameter, stellt **FastAPI** das Äquivalent `Body` zur VerfÃŧgung, um Extra-Daten fÃŧr Body-Parameter zu definieren. -Zum Beispiel, das vorherige Modell erweiternd, kÃļnnten Sie entscheiden, dass Sie einen weiteren SchlÃŧssel `importance` haben mÃļchten, im selben Body, Seite an Seite mit `item` und `user`. +Zum Beispiel, das vorherige Modell erweiternd, kÃļnnten Sie entscheiden, dass Sie einen weiteren SchlÃŧssel `importance` im selben Body haben mÃļchten, neben `item` und `user`. -Wenn Sie diesen Parameter einfach so hinzufÃŧgen, wird **FastAPI** annehmen, dass es ein Query-Parameter ist. +Wenn Sie diesen Parameter einfach so hinzufÃŧgen, wird **FastAPI** annehmen, dass es ein Query-Parameter ist, da er ein einzelner Wert ist. Aber Sie kÃļnnen **FastAPI** instruieren, ihn als weiteren Body-SchlÃŧssel zu erkennen, indem Sie `Body` verwenden: @@ -92,9 +92,9 @@ In diesem Fall erwartet **FastAPI** einen Body wie: } ``` -Wiederum wird es die Daten konvertieren, validieren, dokumentieren, usw. +Wiederum wird es die Datentypen konvertieren, validieren, dokumentieren, usw. -## Mehrere Body-Parameter und Query-Parameter +## Mehrere Body-Parameter und Query-Parameter { #multiple-body-params-and-query } NatÃŧrlich kÃļnnen Sie auch, wann immer Sie das brauchen, weitere Query-Parameter hinzufÃŧgen, zusätzlich zu den Body-Parametern. @@ -112,21 +112,21 @@ q: str | None = None Zum Beispiel: -{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[27] *} +{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *} -/// info +/// info | Info -`Body` hat die gleichen zusätzlichen Validierungs- und Metadaten-Parameter wie `Query` und `Path` und andere, die Sie später kennenlernen. +`Body` hat die gleichen zusätzlichen Validierungs- und Metadaten-Parameter wie `Query`, `Path` und andere, die Sie später kennenlernen werden. /// -## Einen einzelnen Body-Parameter einbetten +## Einen einzelnen Body-Parameter einbetten { #embed-a-single-body-parameter } -Nehmen wir an, Sie haben nur einen einzelnen `item`-Body-Parameter, ein Pydantic-Modell `Item`. +Nehmen wir an, Sie haben nur einen einzelnen `item`-Body-Parameter von einem Pydantic-Modell `Item`. -Normalerweise wird **FastAPI** dann seinen JSON-Body direkt erwarten. +Standardmäßig wird **FastAPI** dann seinen Body direkt erwarten. -Aber wenn Sie mÃļchten, dass es einen JSON-Body erwartet, mit einem SchlÃŧssel `item` und darin den Inhalt des Modells, so wie es das tut, wenn Sie mehrere Body-Parameter deklarieren, dann kÃļnnen Sie den speziellen `Body`-Parameter `embed` setzen: +Aber wenn Sie mÃļchten, dass es einen JSON-Body mit einem SchlÃŧssel `item` erwartet, und darin den Inhalt des Modells, so wie es das tut, wenn Sie mehrere Body-Parameter deklarieren, dann kÃļnnen Sie den speziellen `Body`-Parameter `embed` setzen: ```Python item: Item = Body(embed=True) @@ -160,11 +160,11 @@ statt: } ``` -## Zusammenfassung +## Zusammenfassung { #recap } -Sie kÃļnnen mehrere Body-Parameter zu ihrer *Pfadoperation-Funktion* hinzufÃŧgen, obwohl ein Request nur einen einzigen Body enthalten kann. +Sie kÃļnnen mehrere Body-Parameter zu Ihrer *Pfadoperation-Funktion* hinzufÃŧgen, obwohl ein Request nur einen einzigen Body enthalten kann. -**FastAPI** wird sich darum kÃŧmmern, Ihnen korrekte Daten in Ihrer Funktion zu Ãŧberreichen, und das korrekte Schema in der *Pfadoperation* zu validieren und zu dokumentieren. +Aber **FastAPI** wird sich darum kÃŧmmern, Ihnen korrekte Daten in Ihrer Funktion zu Ãŧberreichen, und das korrekte Schema in der *Pfadoperation* zu validieren und zu dokumentieren. Sie kÃļnnen auch einzelne Werte deklarieren, die als Teil des Bodys empfangen werden. diff --git a/docs/de/docs/tutorial/body-nested-models.md b/docs/de/docs/tutorial/body-nested-models.md index 6287490c6..324d31928 100644 --- a/docs/de/docs/tutorial/body-nested-models.md +++ b/docs/de/docs/tutorial/body-nested-models.md @@ -1,20 +1,20 @@ -# Body – Verschachtelte Modelle +# Body – Verschachtelte Modelle { #body-nested-models } -Mit **FastAPI** kÃļnnen Sie (dank Pydantic) beliebig tief verschachtelte Modelle definieren, validieren und dokumentieren. +Mit **FastAPI** kÃļnnen Sie (dank Pydantic) beliebig tief verschachtelte Modelle definieren, validieren, dokumentieren und verwenden. -## Listen als Felder +## Listen als Felder { #list-fields } -Sie kÃļnnen ein Attribut als Kindtyp definieren, zum Beispiel eine Python-`list`e. +Sie kÃļnnen ein Attribut als Kindtyp definieren, zum Beispiel eine Python-`list`. {* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *} Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts Ãŧber den Typ der Elemente der Liste aussagt. -## Listen mit Typ-Parametern als Felder +## Listen mit Typ-Parametern als Felder { #list-fields-with-type-parameter } Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren. -### `List` von `typing` importieren +### `List` von `typing` importieren { #import-typings-list } In Python 3.9 oder darÃŧber kÃļnnen Sie einfach `list` verwenden, um diese Typannotationen zu deklarieren, wie wir unten sehen werden. 💡 @@ -22,7 +22,7 @@ In Python-Versionen vor 3.9 (3.6 und darÃŧber), mÃŧssen Sie zuerst `List` von Py {* ../../docs_src/body_nested_models/tutorial002.py hl[1] *} -### Eine `list`e mit einem Typ-Parameter deklarieren +### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter } Um Typen wie `list`, `dict`, `tuple` mit inneren Typ-Parametern (inneren Typen) zu deklarieren: @@ -51,7 +51,7 @@ In unserem Beispiel kÃļnnen wir also bewirken, dass `tags` spezifisch eine „Li {* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *} -## Set-Typen +## Set-Typen { #set-types } Aber dann denken wir darÃŧber nach und stellen fest, dass sich die Tags nicht wiederholen sollen, es sollen eindeutige Strings sein. @@ -61,13 +61,13 @@ Deklarieren wir also `tags` als Set von Strings. {* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *} -Jetzt, selbst wenn Sie einen Request mit duplizierten Daten erhalten, werden diese zu einem Set eindeutiger Dinge konvertiert. +Jetzt, selbst wenn Sie einen Request mit duplizierten Daten erhalten, werden diese zu einem Set eindeutiger Dinge konvertiert. Und wann immer Sie diese Daten ausgeben, selbst wenn die Quelle Duplikate hatte, wird es als Set von eindeutigen Dingen ausgegeben. Und es wird entsprechend annotiert/dokumentiert. -## Verschachtelte Modelle +## Verschachtelte Modelle { #nested-models } Jedes Attribut eines Pydantic-Modells hat einen Typ. @@ -77,19 +77,19 @@ Sie kÃļnnen also tief verschachtelte JSON-„Objekte“ deklarieren, mit spezifi Alles das beliebig tief verschachtelt. -### Ein Kindmodell definieren +### Ein Kindmodell definieren { #define-a-submodel } -Wir kÃļnnen zum Beispiel ein `Image`-Modell definieren. +FÃŧr ein Beispiel kÃļnnen wir ein `Image`-Modell definieren. {* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *} -### Das Kindmodell als Typ verwenden +### Das Kindmodell als Typ verwenden { #use-the-submodel-as-a-type } -Und dann kÃļnnen wir es als Typ eines Attributes verwenden. +Und dann kÃļnnen wir es als Typ eines Attributes verwenden: {* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *} -Das wÃŧrde bedeuten, dass **FastAPI** einen Body erwartet wie: +Das wÃŧrde bedeuten, dass **FastAPI** einen Body wie folgt erwartet: ```JSON { @@ -112,25 +112,25 @@ Wiederum, nur mit dieser Deklaration erhalten Sie von **FastAPI**: * Datenvalidierung * Automatische Dokumentation -## Spezielle Typen und Validierungen +## Spezielle Typen und Validierungen { #special-types-and-validation } -Abgesehen von normalen einfachen Typen, wie `str`, `int`, `float`, usw. kÃļnnen Sie komplexere einfache Typen verwenden, die von `str` erben. +Abgesehen von normalen einfachen Typen wie `str`, `int`, `float`, usw. kÃļnnen Sie komplexere einfache Typen verwenden, die von `str` erben. -Um alle Optionen kennenzulernen, die Sie haben, schauen Sie sich Pydantics TypÃŧbersicht an. Sie werden im nächsten Kapitel ein paar Beispiele kennenlernen. +Um alle Optionen kennenzulernen, die Sie haben, schauen Sie sich Pydantics TypÃŧbersicht an. Sie werden einige Beispiele im nächsten Kapitel kennenlernen. -Da wir zum Beispiel im `Image`-Modell ein Feld `url` haben, kÃļnnen wir deklarieren, dass das eine Instanz von Pydantics `HttpUrl` sein soll, anstelle eines `str`: +Zum Beispiel, da wir im `Image`-Modell ein Feld `url` haben, kÃļnnen wir deklarieren, dass das eine Instanz von Pydantics `HttpUrl` sein soll, anstelle eines `str`: {* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *} Es wird getestet, ob der String eine gÃŧltige URL ist, und als solche wird er in JSON Schema / OpenAPI dokumentiert. -## Attribute mit Listen von Kindmodellen +## Attribute mit Listen von Kindmodellen { #attributes-with-lists-of-submodels } Sie kÃļnnen Pydantic-Modelle auch als Typen innerhalb von `list`, `set`, usw. verwenden: {* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *} -Das wird einen JSON-Body erwarten (konvertieren, validieren, dokumentieren), wie: +Das wird einen JSON-Body erwarten (konvertieren, validieren, dokumentieren, usw.) wie: ```JSON hl_lines="11" { @@ -156,27 +156,27 @@ Das wird einen JSON-Body erwarten (konvertieren, validieren, dokumentieren), wie } ``` -/// info +/// info | Info Beachten Sie, dass der `images`-SchlÃŧssel jetzt eine Liste von Bild-Objekten hat. /// -## Tief verschachtelte Modelle +## Tief verschachtelte Modelle { #deeply-nested-models } Sie kÃļnnen beliebig tief verschachtelte Modelle definieren: {* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *} -/// info +/// info | Info -Beachten Sie, wie `Offer` eine Liste von `Item`s hat, von denen jedes seinerseits eine optionale Liste von `Image`s hat. +Beachten Sie, wie `Offer` eine Liste von `Item`s hat, die ihrerseits eine optionale Liste von `Image`s haben. /// -## Bodys aus reinen Listen +## Bodys aus reinen Listen { #bodies-of-pure-lists } -Wenn Sie mÃļchten, dass das äußerste Element des JSON-Bodys ein JSON-`array` (eine Python-`list`e) ist, kÃļnnen Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen: +Wenn das äußerste Element des JSON-Bodys, das Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, kÃļnnen Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen: ```Python images: List[Image] @@ -192,7 +192,7 @@ so wie in: {* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *} -## Editor-UnterstÃŧtzung Ãŧberall +## Editor-UnterstÃŧtzung Ãŧberall { #editor-support-everywhere } Und Sie erhalten Editor-UnterstÃŧtzung Ãŧberall. @@ -204,11 +204,11 @@ Sie wÃŧrden diese Editor-UnterstÃŧtzung nicht erhalten, wenn Sie direkt mit `dic Aber Sie mÃŧssen sich auch nicht weiter um die Modelle kÃŧmmern, hereinkommende Dicts werden automatisch in sie konvertiert. Und was Sie zurÃŧckgeben, wird automatisch nach JSON konvertiert. -## Bodys mit beliebigen `dict`s +## Bodys mit beliebigen `dict`s { #bodies-of-arbitrary-dicts } Sie kÃļnnen einen Body auch als `dict` deklarieren, mit SchlÃŧsseln eines Typs und Werten eines anderen Typs. -So brauchen Sie vorher nicht zu wissen, wie die Feld-/Attribut-Namen lauten (wie es bei Pydantic-Modellen der Fall wäre). +So brauchen Sie vorher nicht zu wissen, wie die Feld-/Attributnamen lauten (wie es bei Pydantic-Modellen der Fall wäre). Das ist nÃŧtzlich, wenn Sie SchlÃŧssel empfangen, deren Namen Sie nicht bereits kennen. @@ -218,7 +218,7 @@ Ein anderer nÃŧtzlicher Anwendungsfall ist, wenn Sie SchlÃŧssel eines anderen Ty Das schauen wir uns mal an. -Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-SchlÃŧssel und `float`-Werte hat. +Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-SchlÃŧssel und `float`-Werte hat: {* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *} @@ -230,11 +230,11 @@ Aber Pydantic hat automatische Datenkonvertierung. Das bedeutet, dass Ihre API-Clients nur Strings senden kÃļnnen, aber solange diese Strings nur Zahlen enthalten, wird Pydantic sie konvertieren und validieren. -Und das `dict` welches Sie als `weights` erhalten, wird `int`-SchlÃŧssel und `float`-Werte haben. +Und das `dict`, welches Sie als `weights` erhalten, wird `int`-SchlÃŧssel und `float`-Werte haben. /// -## Zusammenfassung +## Zusammenfassung { #recap } Mit **FastAPI** haben Sie die maximale Flexibilität von Pydantic-Modellen, während Ihr Code einfach, kurz und elegant bleibt. diff --git a/docs/de/docs/tutorial/body-updates.md b/docs/de/docs/tutorial/body-updates.md index 574016c58..aa62199fe 100644 --- a/docs/de/docs/tutorial/body-updates.md +++ b/docs/de/docs/tutorial/body-updates.md @@ -1,16 +1,16 @@ -# Body – Aktualisierungen +# Body – Aktualisierungen { #body-updates } -## Ersetzendes Aktualisieren mit `PUT` +## Ersetzendes Aktualisieren mit `PUT` { #update-replacing-with-put } Um einen Artikel zu aktualisieren, kÃļnnen Sie die HTTP `PUT` Operation verwenden. -Sie kÃļnnen den `jsonable_encoder` verwenden, um die empfangenen Daten in etwas zu konvertieren, das als JSON gespeichert werden kann (in z. B. einer NoSQL-Datenbank). Zum Beispiel, um ein `datetime` in einen `str` zu konvertieren. +Sie kÃļnnen den `jsonable_encoder` verwenden, um die empfangenen Daten in etwas zu konvertieren, das als JSON gespeichert werden kann (z. B. in einer NoSQL-Datenbank). Zum Beispiel, um ein `datetime` in einen `str` zu konvertieren. {* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *} `PUT` wird verwendet, um Daten zu empfangen, die die existierenden Daten ersetzen sollen. -### Warnung bezÃŧglich des Ersetzens +### Warnung bezÃŧglich des Ersetzens { #warning-about-replacing } Das bedeutet, dass, wenn Sie den Artikel `bar` aktualisieren wollen, mittels `PUT` und folgendem Body: @@ -22,15 +22,15 @@ Das bedeutet, dass, wenn Sie den Artikel `bar` aktualisieren wollen, mittels `PU } ``` -das Eingabemodell nun den Defaultwert `"tax": 10.5` hat, weil Sie das bereits gespeicherte Attribut `"tax": 20.2` nicht mit Ãŧbergeben haben. +weil das bereits gespeicherte Attribut `"tax": 20.2` nicht enthalten ist, das Eingabemodell den Defaultwert `"tax": 10.5` erhalten wÃŧrde. -Die Daten werden darum mit einem „neuen“ `tax`-Wert von `10.5` abgespeichert. +Und die Daten wÃŧrden mit diesem „neuen“ `tax` von `10.5` gespeichert werden. -## Teilweises Ersetzen mit `PATCH` +## Teil-Aktualisierungen mit `PATCH` { #partial-updates-with-patch } Sie kÃļnnen auch die HTTP `PATCH` Operation verwenden, um Daten *teilweise* zu ersetzen. -Das bedeutet, sie senden nur die Daten, die Sie aktualisieren wollen, der Rest bleibt unverändert. +Das bedeutet, Sie senden nur die Daten, die Sie aktualisieren wollen, der Rest bleibt unverändert. /// note | Hinweis @@ -44,33 +44,33 @@ Aber dieser Leitfaden zeigt Ihnen mehr oder weniger, wie die beiden normalerweis /// -### Pydantics `exclude_unset`-Parameter verwenden +### Pydantics `exclude_unset`-Parameter verwenden { #using-pydantics-exclude-unset-parameter } Wenn Sie Teil-Aktualisierungen entgegennehmen, ist der `exclude_unset`-Parameter in der `.model_dump()`-Methode von Pydantic-Modellen sehr nÃŧtzlich. Wie in `item.model_dump(exclude_unset=True)`. -/// info +/// info | Info -In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie deprecated (aber immer noch unterstÃŧtzt) und in `.model_dump()` umbenannt. +In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie deprecatet (aber immer noch unterstÃŧtzt) und in `.model_dump()` umbenannt. Die Beispiele hier verwenden `.dict()` fÃŧr die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden kÃļnnen. /// -Das wird ein `dict` erstellen, mit nur den Daten, die gesetzt wurden als das `item`-Modell erstellt wurde, Defaultwerte ausgeschlossen. +Das wird ein `dict` erstellen, mit nur den Daten, die gesetzt wurden, als das `item`-Modell erstellt wurde, Defaultwerte ausgeschlossen. -Sie kÃļnnen das verwenden, um ein `dict` zu erstellen, das nur die (im Request) gesendeten Daten enthält, ohne Defaultwerte: +Sie kÃļnnen das verwenden, um ein `dict` zu erstellen, das nur die (im Request) gesendeten Daten enthält, ohne Defaultwerte: {* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *} -### Pydantics `update`-Parameter verwenden +### Pydantics `update`-Parameter verwenden { #using-pydantics-update-parameter } Jetzt kÃļnnen Sie eine Kopie des existierenden Modells mittels `.model_copy()` erstellen, wobei Sie dem `update`-Parameter ein `dict` mit den zu ändernden Daten Ãŧbergeben. -/// info +/// info | Info -In Pydantic v1 hieß diese Methode `.copy()`, in Pydantic v2 wurde sie deprecated (aber immer noch unterstÃŧtzt) und in `.model_copy()` umbenannt. +In Pydantic v1 hieß diese Methode `.copy()`, in Pydantic v2 wurde sie deprecatet (aber immer noch unterstÃŧtzt) und in `.model_copy()` umbenannt. Die Beispiele hier verwenden `.copy()` fÃŧr die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_copy()` verwenden, wenn Sie Pydantic v2 verwenden kÃļnnen. @@ -80,9 +80,9 @@ Wie in `stored_item_model.model_copy(update=update_data)`: {* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *} -### Rekapitulation zum teilweisen Ersetzen +### Rekapitulation zu Teil-Aktualisierungen { #partial-updates-recap } -Zusammengefasst, um Teil-Ersetzungen vorzunehmen: +Zusammengefasst, um Teil-Aktualisierungen vorzunehmen: * (Optional) verwenden Sie `PATCH` statt `PUT`. * Lesen Sie die bereits gespeicherten Daten aus. @@ -90,7 +90,7 @@ Zusammengefasst, um Teil-Ersetzungen vorzunehmen: * Erzeugen Sie aus dem empfangenen Modell ein `dict` ohne Defaultwerte (mittels `exclude_unset`). * So ersetzen Sie nur die tatsächlich vom Benutzer gesetzten Werte, statt dass bereits gespeicherte Werte mit Defaultwerten des Modells Ãŧberschrieben werden. * Erzeugen Sie eine Kopie ihres gespeicherten Modells, wobei Sie die Attribute mit den empfangenen Teil-Ersetzungen aktualisieren (mittels des `update`-Parameters). -* Konvertieren Sie das kopierte Modell zu etwas, das in ihrer Datenbank gespeichert werden kann (indem Sie beispielsweise `jsonable_encoder` verwenden). +* Konvertieren Sie das kopierte Modell zu etwas, das in Ihrer Datenbank gespeichert werden kann (indem Sie beispielsweise `jsonable_encoder` verwenden). * Das ist vergleichbar dazu, die `.model_dump()`-Methode des Modells erneut aufzurufen, aber es wird sicherstellen, dass die Werte zu Daten konvertiert werden, die ihrerseits zu JSON konvertiert werden kÃļnnen, zum Beispiel `datetime` zu `str`. * Speichern Sie die Daten in Ihrer Datenbank. * Geben Sie das aktualisierte Modell zurÃŧck. diff --git a/docs/de/docs/tutorial/body.md b/docs/de/docs/tutorial/body.md index e25323786..1e6382b6f 100644 --- a/docs/de/docs/tutorial/body.md +++ b/docs/de/docs/tutorial/body.md @@ -1,40 +1,40 @@ -# Requestbody +# Requestbody { #request-body } -Wenn Sie Daten von einem Client (sagen wir, einem Browser) zu Ihrer API senden, dann senden Sie diese als einen **Requestbody** (Deutsch: AnfragekÃļrper). +Wenn Sie Daten von einem Client (sagen wir, einem Browser) zu Ihrer API senden mÃŧssen, senden Sie sie als **Requestbody**. -Ein **Request**body sind Daten, die vom Client zu Ihrer API gesendet werden. Ein **Response**body (Deutsch: AntwortkÃļrper) sind Daten, die Ihre API zum Client sendet. +Ein **Request**body sind Daten, die vom Client zu Ihrer API gesendet werden. Ein **Response**body sind Daten, die Ihre API zum Client sendet. -Ihre API sendet fast immer einen **Response**body. Aber Clients senden nicht unbedingt immer **Request**bodys (sondern nur Metadaten). +Ihre API muss fast immer einen **Response**body senden. Aber Clients mÃŧssen nicht unbedingt immer **Requestbodys** senden, manchmal fordern sie nur einen Pfad an, vielleicht mit einigen Query-Parametern, aber senden keinen Body. -Um einen **Request**body zu deklarieren, verwenden Sie Pydantic-Modelle mit allen deren Fähigkeiten und VorzÃŧgen. +Um einen **Request**body zu deklarieren, verwenden Sie Pydantic-Modelle mit all deren Fähigkeiten und VorzÃŧgen. -/// info +/// info | Info -Um Daten zu versenden, sollten Sie eines von: `POST` (meistverwendet), `PUT`, `DELETE` oder `PATCH` verwenden. +Um Daten zu senden, sollten Sie eines von: `POST` (meistverwendet), `PUT`, `DELETE` oder `PATCH` verwenden. -Senden Sie einen Body mit einem `GET`-Request, dann fÃŧhrt das laut Spezifikation zu undefiniertem Verhalten. Trotzdem wird es von FastAPI unterstÃŧtzt, fÃŧr sehr komplexe/extreme Anwendungsfälle. +Das Senden eines Bodys mit einem `GET`-Request hat ein undefiniertes Verhalten in den Spezifikationen, wird aber dennoch von FastAPI unterstÃŧtzt, nur fÃŧr sehr komplexe/extreme Anwendungsfälle. -Da aber davon abgeraten wird, zeigt die interaktive Dokumentation mit Swagger-Benutzeroberfläche die Dokumentation fÃŧr den Body auch nicht an, wenn `GET` verwendet wird. Dazwischengeschaltete Proxys unterstÃŧtzen es mÃļglicherweise auch nicht. +Da davon abgeraten wird, zeigt die interaktive Dokumentation mit Swagger-Benutzeroberfläche die Dokumentation fÃŧr den Body nicht an, wenn `GET` verwendet wird, und zwischengeschaltete Proxys unterstÃŧtzen es mÃļglicherweise nicht. /// -## Importieren Sie Pydantics `BaseModel` +## Pydantics `BaseModel` importieren { #import-pydantics-basemodel } Zuerst mÃŧssen Sie `BaseModel` von `pydantic` importieren: {* ../../docs_src/body/tutorial001_py310.py hl[2] *} -## Erstellen Sie Ihr Datenmodell +## Ihr Datenmodell erstellen { #create-your-data-model } Dann deklarieren Sie Ihr Datenmodell als eine Klasse, die von `BaseModel` erbt. -Verwenden Sie Standard-Python-Typen fÃŧr die Klassenattribute: +Verwenden Sie Standard-Python-Typen fÃŧr alle Attribute: {* ../../docs_src/body/tutorial001_py310.py hl[5:9] *} -Wie auch bei Query-Parametern gilt, wenn ein Modellattribut einen Defaultwert hat, ist das Attribut nicht erforderlich. Ansonsten ist es erforderlich. Verwenden Sie `None`, um es als optional zu kennzeichnen. +Wie auch bei der Deklaration von Query-Parametern gilt: Wenn ein Modellattribut einen Defaultwert hat, ist das Attribut nicht erforderlich. Andernfalls ist es erforderlich. Verwenden Sie `None`, um es einfach optional zu machen. -Zum Beispiel deklariert das obige Modell ein JSON "`object`" (oder Python-`dict`) wie dieses: +Zum Beispiel deklariert das obige Modell ein JSON „`object`“ (oder Python-`dict`) wie dieses: ```JSON { @@ -45,7 +45,7 @@ Zum Beispiel deklariert das obige Modell ein JSON "`object`" (oder Python-`dict` } ``` -Da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre folgendes JSON "`object`" auch gÃŧltig: +Da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre folgendes JSON „`object`“ auch gÃŧltig: ```JSON { @@ -54,109 +54,120 @@ Da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre fol } ``` -## Deklarieren Sie es als Parameter +## Als Parameter deklarieren { #declare-it-as-a-parameter } Um es zu Ihrer *Pfadoperation* hinzuzufÃŧgen, deklarieren Sie es auf die gleiche Weise, wie Sie Pfad- und Query-Parameter deklariert haben: {* ../../docs_src/body/tutorial001_py310.py hl[16] *} -... und deklarieren Sie seinen Typ als das Modell, welches Sie erstellt haben, `Item`. +... und deklarieren Sie dessen Typ als das Modell, welches Sie erstellt haben, `Item`. -## Resultate +## Resultate { #results } -Mit nur dieser Python-Typdeklaration, wird **FastAPI**: +Mit nur dieser Python-Typdeklaration wird **FastAPI**: * Den Requestbody als JSON lesen. * Die entsprechenden Typen konvertieren (falls nÃļtig). * Diese Daten validieren. - * Wenn die Daten ungÃŧltig sind, einen klar lesbaren Fehler zurÃŧckgeben, der anzeigt, wo und was die inkorrekten Daten waren. + * Wenn die Daten ungÃŧltig sind, wird ein klar lesbarer Fehler zurÃŧckgegeben, der genau anzeigt, wo und was die inkorrekten Daten sind. * Ihnen die erhaltenen Daten im Parameter `item` Ãŧbergeben. - * Da Sie diesen in der Funktion als vom Typ `Item` deklariert haben, erhalten Sie die ganze Editor-UnterstÃŧtzung (Autovervollständigung, usw.) fÃŧr alle Attribute und deren Typen. -* Eine JSON Schema Definition fÃŧr Ihr Modell generieren, welche Sie Ãŧberall sonst verwenden kÃļnnen, wenn es fÃŧr Ihr Projekt Sinn macht. -* Diese Schemas werden Teil des generierten OpenAPI-Schemas und werden von den UIs der automatischen Dokumentation verwendet. + * Da Sie ihn in der Funktion als vom Typ `Item` deklariert haben, erhalten Sie auch die volle UnterstÃŧtzung des Editors (Autovervollständigung, usw.) fÃŧr alle Attribute und deren Typen. +* JSON Schema-Definitionen fÃŧr Ihr Modell generieren, die Sie auch Ãŧberall sonst verwenden kÃļnnen, wenn es fÃŧr Ihr Projekt Sinn macht. +* Diese Schemas werden Teil des generierten OpenAPI-Schemas und werden von den UIs der automatischen Dokumentation genutzt. -## Automatische Dokumentation +## Automatische Dokumentation { #automatic-docs } -Die JSON-Schemas Ihrer Modelle werden Teil ihrer OpenAPI-generierten Schemas und werden in der interaktiven API Dokumentation angezeigt: +Die JSON-Schemas Ihrer Modelle werden Teil Ihres OpenAPI-generierten Schemas und in der interaktiven API-Dokumentation angezeigt: -Und werden auch verwendet in der API-Dokumentation innerhalb jeder *Pfadoperation*, welche sie braucht: +Und werden auch in der API-Dokumentation innerhalb jeder *Pfadoperation*, die sie benÃļtigt, verwendet: -## Editor UnterstÃŧtzung +## Editor-UnterstÃŧtzung { #editor-support } -In Ihrem Editor, innerhalb Ihrer Funktion, erhalten Sie Typhinweise und Code-Vervollständigung Ãŧberall (was nicht der Fall wäre, wenn Sie ein `dict` anstelle eines Pydantic Modells erhalten hätten): +In Ihrem Editor erhalten Sie innerhalb Ihrer Funktion Typhinweise und Code-Vervollständigung Ãŧberall (was nicht der Fall wäre, wenn Sie ein `dict` anstelle eines Pydantic-Modells erhalten hätten): -Sie bekommen auch Fehler-Meldungen fÃŧr inkorrekte Typoperationen: +Sie bekommen auch Fehlermeldungen fÃŧr inkorrekte Typoperationen: Das ist nicht zufällig so, das ganze Framework wurde um dieses Design herum aufgebaut. -Und es wurde in der Designphase grÃŧndlich getestet, vor der Implementierung, um sicherzustellen, dass es mit jedem Editor funktioniert. +Und es wurde in der Designphase grÃŧndlich getestet, bevor irgendeine Implementierung stattfand, um sicherzustellen, dass es mit allen Editoren funktioniert. -Es gab sogar ein paar Änderungen an Pydantic selbst, um das zu unterstÃŧtzen. +Es gab sogar einige Änderungen an Pydantic selbst, um dies zu unterstÃŧtzen. -Die vorherigen Screenshots zeigten Visual Studio Code. +Die vorherigen Screenshots wurden mit Visual Studio Code aufgenommen. -Aber Sie bekommen die gleiche Editor-UnterstÃŧtzung in PyCharm und in den meisten anderen Python-Editoren: +Aber Sie wÃŧrden die gleiche Editor-UnterstÃŧtzung in PyCharm und den meisten anderen Python-Editoren erhalten: /// tip | Tipp -Wenn Sie PyCharm als Ihren Editor verwenden, probieren Sie das Pydantic PyCharm Plugin aus. +Wenn Sie PyCharm als Ihren Editor verwenden, kÃļnnen Sie das Pydantic PyCharm Plugin ausprobieren. Es verbessert die Editor-UnterstÃŧtzung fÃŧr Pydantic-Modelle, mit: * Code-Vervollständigung * TypÃŧberprÃŧfungen * Refaktorisierung -* Suchen +* Suche * Inspektionen /// -## Das Modell verwenden +## Das Modell verwenden { #use-the-model } -Innerhalb der Funktion kÃļnnen Sie alle Attribute des Modells direkt verwenden: +Innerhalb der Funktion kÃļnnen Sie alle Attribute des Modellobjekts direkt verwenden: -{* ../../docs_src/body/tutorial002_py310.py hl[19] *} +{* ../../docs_src/body/tutorial002_py310.py *} -## Requestbody- + Pfad-Parameter +/// info | Info -Sie kÃļnnen Pfad- und Requestbody-Parameter gleichzeitig deklarieren. +In Pydantic v1 hieß die Methode `.dict()`, sie wurde in Pydantic v2 deprecatet (aber weiterhin unterstÃŧtzt) und in `.model_dump()` umbenannt. + +Die Beispiele hier verwenden `.dict()` zur Kompatibilität mit Pydantic v1, aber Sie sollten stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 nutzen kÃļnnen. + +/// + +## Requestbody- + Pfad-Parameter { #request-body-path-parameters } + +Sie kÃļnnen Pfad-Parameter und den Requestbody gleichzeitig deklarieren. **FastAPI** erkennt, dass Funktionsparameter, die mit Pfad-Parametern Ãŧbereinstimmen, **vom Pfad genommen** werden sollen, und dass Funktionsparameter, welche Pydantic-Modelle sind, **vom Requestbody genommen** werden sollen. {* ../../docs_src/body/tutorial003_py310.py hl[15:16] *} -## Requestbody- + Pfad- + Query-Parameter + +## Requestbody- + Pfad- + Query-Parameter { #request-body-path-query-parameters } Sie kÃļnnen auch zur gleichen Zeit **Body-**, **Pfad-** und **Query-Parameter** deklarieren. -**FastAPI** wird jeden Parameter korrekt erkennen und die Daten vom richtigen Ort holen. +**FastAPI** wird jeden von ihnen korrekt erkennen und die Daten vom richtigen Ort holen. {* ../../docs_src/body/tutorial004_py310.py hl[16] *} Die Funktionsparameter werden wie folgt erkannt: -* Wenn der Parameter auch im **Pfad** deklariert wurde, wird er als Pfad-Parameter interpretiert. +* Wenn der Parameter auch im **Pfad** deklariert wurde, wird er als Pfad-Parameter verwendet. * Wenn der Parameter ein **einfacher Typ** ist (wie `int`, `float`, `str`, `bool`, usw.), wird er als **Query**-Parameter interpretiert. * Wenn der Parameter vom Typ eines **Pydantic-Modells** ist, wird er als Request**body** interpretiert. /// note | Hinweis -FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, wegen des definierten Defaultwertes `= None` +FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`. -Das `Union` in `Union[str, None]` wird von FastAPI nicht verwendet, aber es erlaubt Ihrem Editor, Sie besser zu unterstÃŧtzen und Fehler zu erkennen. +Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.8+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat. + +Das HinzufÃŧgen der Typannotationen ermÃļglicht jedoch Ihrem Editor, Ihnen eine bessere UnterstÃŧtzung zu bieten und Fehler zu erkennen. /// -## Ohne Pydantic +## Ohne Pydantic { #without-pydantic } -Wenn Sie keine Pydantic-Modelle verwenden wollen, kÃļnnen Sie auch **Body**-Parameter nehmen. Siehe die Dokumentation unter [Body – Mehrere Parameter: Einfache Werte im Body](body-multiple-params.md#einzelne-werte-im-body){.internal-link target=\_blank}. +Wenn Sie keine Pydantic-Modelle verwenden mÃļchten, kÃļnnen Sie auch **Body**-Parameter verwenden. Siehe die Dokumentation unter [Body – Mehrere Parameter: Einfache Werte im Body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}. diff --git a/docs/de/docs/tutorial/cookie-param-models.md b/docs/de/docs/tutorial/cookie-param-models.md new file mode 100644 index 000000000..2baf3d70d --- /dev/null +++ b/docs/de/docs/tutorial/cookie-param-models.md @@ -0,0 +1,76 @@ +# Cookie-Parameter-Modelle { #cookie-parameter-models } + +Wenn Sie eine Gruppe von **Cookies** haben, die zusammengehÃļren, kÃļnnen Sie ein **Pydantic-Modell** erstellen, um diese zu deklarieren. đŸĒ + +Damit kÃļnnen Sie das Modell an **mehreren Stellen wiederverwenden** und auch Validierungen und Metadaten fÃŧr alle Parameter gleichzeitig deklarieren. 😎 + +/// note | Hinweis + +Dies wird seit FastAPI Version `0.115.0` unterstÃŧtzt. 🤓 + +/// + +/// tip | Tipp + +Diese gleiche Technik gilt fÃŧr `Query`, `Cookie` und `Header`. 😎 + +/// + +## Cookies mit einem Pydantic-Modell { #cookies-with-a-pydantic-model } + +Deklarieren Sie die **Cookie**-Parameter, die Sie benÃļtigen, in einem **Pydantic-Modell**, und deklarieren Sie dann den Parameter als `Cookie`: + +{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *} + +**FastAPI** wird die Daten fÃŧr **jedes Feld** aus den im Request empfangenen **Cookies** **extrahieren** und Ihnen das von Ihnen definierte Pydantic-Modell bereitstellen. + +## Die Dokumentation testen { #check-the-docs } + +Sie kÃļnnen die definierten Cookies in der Dokumentationsoberfläche unter `/docs` sehen: + +
+ +
+ +/// info | Info + +Bitte beachten Sie, dass Browser Cookies auf spezielle Weise und im Hintergrund bearbeiten, sodass sie **nicht** leicht **JavaScript** erlauben, diese zu berÃŧhren. + +Wenn Sie zur **API-Dokumentationsoberfläche** unter `/docs` gehen, kÃļnnen Sie die **Dokumentation** fÃŧr Cookies fÃŧr Ihre *Pfadoperationen* sehen. + +Aber selbst wenn Sie die **Daten ausfÃŧllen** und auf „AusfÃŧhren“ klicken, werden aufgrund der Tatsache, dass die Dokumentationsoberfläche mit **JavaScript** arbeitet, die Cookies nicht gesendet, und Sie werden eine **Fehlermeldung** sehen, als ob Sie keine Werte eingegeben hätten. + +/// + +## Zusätzliche Cookies verbieten { #forbid-extra-cookies } + +In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) mÃļchten Sie mÃļglicherweise die Cookies, die Sie empfangen mÃļchten, **einschränken**. + +Ihre API hat jetzt die Macht, ihre eigene Cookie-Einwilligung zu kontrollieren. đŸ¤ĒđŸĒ + +Sie kÃļnnen die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu verbieten (`forbid`): + +{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *} + +Wenn ein Client versucht, einige **zusätzliche Cookies** zu senden, erhält er eine **Error-Response**. + +Arme Cookie-Banner, wie sie sich mÃŧhen, Ihre Einwilligung zu erhalten, dass die API sie ablehnen darf. đŸĒ + +Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` Cookie nicht erlaubt ist: + +```json +{ + "detail": [ + { + "type": "extra_forbidden", + "loc": ["cookie", "santa_tracker"], + "msg": "Extra inputs are not permitted", + "input": "good-list-please", + } + ] +} +``` + +## Zusammenfassung { #summary } + +Sie kÃļnnen **Pydantic-Modelle** verwenden, um **Cookies** in **FastAPI** zu deklarieren. 😎 diff --git a/docs/de/docs/tutorial/cookie-params.md b/docs/de/docs/tutorial/cookie-params.md index 711c8c8e9..81a753211 100644 --- a/docs/de/docs/tutorial/cookie-params.md +++ b/docs/de/docs/tutorial/cookie-params.md @@ -1,35 +1,45 @@ -# Cookie-Parameter +# Cookie-Parameter { #cookie-parameters } -So wie `Query`- und `Path`-Parameter kÃļnnen Sie auch Cookie-Parameter definieren. +Sie kÃļnnen Cookie-Parameter auf die gleiche Weise definieren wie `Query`- und `Path`-Parameter. -## `Cookie` importieren +## `Cookie` importieren { #import-cookie } Importieren Sie zuerst `Cookie`: {* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *} -## `Cookie`-Parameter deklarieren +## `Cookie`-Parameter deklarieren { #declare-cookie-parameters } -Dann deklarieren Sie Ihre Cookie-Parameter, auf die gleiche Weise, wie Sie auch `Path`- und `Query`-Parameter deklarieren. +Deklarieren Sie dann die Cookie-Parameter mit derselben Struktur wie bei `Path` und `Query`. -Der erste Wert ist der Typ. Sie kÃļnnen `Cookie` die gehabten Extra Validierungs- und Beschreibungsparameter hinzufÃŧgen. Danach kÃļnnen Sie einen Defaultwert vergeben: +Sie kÃļnnen den Defaultwert sowie alle zusätzlichen Validierungen oder Annotierungsparameter definieren: {* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *} /// note | Technische Details -`Cookie` ist eine Schwesterklasse von `Path` und `Query`. Sie erbt von derselben gemeinsamen `Param`-Elternklasse. +`Cookie` ist eine „Schwester“-Klasse von `Path` und `Query`. Sie erbt auch von derselben gemeinsamen `Param`-Klasse. -Aber erinnern Sie sich, dass, wenn Sie `Query`, `Path`, `Cookie` und andere von `fastapi` importieren, diese tatsächlich Funktionen sind, welche spezielle Klassen zurÃŧckgeben. +Aber denken Sie daran, dass, wenn Sie `Query`, `Path`, `Cookie` und andere von `fastapi` importieren, diese tatsächlich Funktionen sind, die spezielle Klassen zurÃŧckgeben. /// -/// info +/// info | Info -Um Cookies zu deklarieren, mÃŧssen Sie `Cookie` verwenden, da diese Parameter sonst als Query-Parameter interpretiert werden wÃŧrden. +Um Cookies zu deklarieren, mÃŧssen Sie `Cookie` verwenden, da die Parameter sonst als Query-Parameter interpretiert wÃŧrden. /// -## Zusammenfassung +/// info | Info -Deklarieren Sie Cookies mittels `Cookie`, auf die gleiche Weise wie bei `Query` und `Path`. +Beachten Sie, dass **Browser Cookies auf besondere Weise und hinter den Kulissen handhaben** und **JavaScript** **nicht** ohne Weiteres erlauben, auf sie zuzugreifen. + +Wenn Sie zur **API-Dokumentations-UI** unter `/docs` gehen, kÃļnnen Sie die **Dokumentation** zu Cookies fÃŧr Ihre *Pfadoperationen* sehen. + +Aber selbst wenn Sie die **Daten ausfÃŧllen** und auf „Execute“ klicken, da die Dokumentations-UI mit **JavaScript** arbeitet, werden die Cookies nicht gesendet, und Sie sehen eine **Fehler**-Meldung, als hätten Sie keine Werte eingegeben. + +/// + +## Zusammenfassung { #recap } + +Deklarieren Sie Cookies mit `Cookie` und verwenden Sie dabei das gleiche allgemeine Muster wie bei `Query` und `Path`. diff --git a/docs/de/docs/tutorial/cors.md b/docs/de/docs/tutorial/cors.md new file mode 100644 index 000000000..191a7b4ef --- /dev/null +++ b/docs/de/docs/tutorial/cors.md @@ -0,0 +1,88 @@ +# CORS (Cross-Origin Resource Sharing) { #cors-cross-origin-resource-sharing } + +CORS oder „Cross-Origin Resource Sharing“ bezieht sich auf Situationen, in denen ein Frontend, das in einem Browser läuft, JavaScript-Code enthält, der mit einem Backend kommuniziert, und das Backend sich in einem anderen „Origin“ als das Frontend befindet. + +## Origin { #origin } + +Ein Origin ist die Kombination aus Protokoll (`http`, `https`), Domain (`myapp.com`, `localhost`, `localhost.tiangolo.com`) und Port (`80`, `443`, `8080`). + +Alle folgenden sind also unterschiedliche Origins: + +* `http://localhost` +* `https://localhost` +* `http://localhost:8080` + +Auch wenn sie alle in `localhost` sind, verwenden sie unterschiedliche Protokolle oder Ports, daher sind sie unterschiedliche „Origins“. + +## Schritte { #steps } + +Angenommen, Sie haben ein Frontend, das in Ihrem Browser unter `http://localhost:8080` läuft, und dessen JavaScript versucht, mit einem Backend zu kommunizieren, das unter `http://localhost` läuft (da wir keinen Port angegeben haben, geht der Browser vom Default-Port `80` aus). + +Dann wird der Browser ein HTTP-`OPTIONS`-Request an das `:80`-Backend senden, und wenn das Backend die entsprechenden Header sendet, die die Kommunikation von diesem anderen Origin (`http://localhost:8080`) autorisieren, lässt der `:8080`-Browser das JavaScript im Frontend seinen Request an das `:80`-Backend senden. + +Um dies zu erreichen, muss das `:80`-Backend eine Liste von „erlaubten Origins“ haben. + +In diesem Fall mÃŧsste die Liste `http://localhost:8080` enthalten, damit das `:8080`-Frontend korrekt funktioniert. + +## Wildcards { #wildcards } + +Es ist auch mÃļglich, die Liste als `"*"` (ein „Wildcard“) zu deklarieren, um anzuzeigen, dass alle erlaubt sind. + +Aber das erlaubt nur bestimmte Arten der Kommunikation und schließt alles aus, was Anmeldeinformationen beinhaltet: Cookies, Autorisierungsheader wie die, die mit Bearer Tokens verwendet werden, usw. + +Um sicherzustellen, dass alles korrekt funktioniert, ist es besser, die erlaubten Origins explizit anzugeben. + +## `CORSMiddleware` verwenden { #use-corsmiddleware } + +Sie kÃļnnen das in Ihrer **FastAPI**-Anwendung mit der `CORSMiddleware` konfigurieren. + +* Importieren Sie `CORSMiddleware`. +* Erstellen Sie eine Liste der erlaubten Origins (als Strings). +* FÃŧgen Sie es als „Middleware“ zu Ihrer **FastAPI**-Anwendung hinzu. + +Sie kÃļnnen auch angeben, ob Ihr Backend erlaubt: + +* Anmeldeinformationen (Autorisierungsheader, Cookies, usw.). +* Bestimmte HTTP-Methoden (`POST`, `PUT`) oder alle mit der Wildcard `"*"`. +* Bestimmte HTTP-Header oder alle mit der Wildcard `"*"`. + +{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *} + +Die von der `CORSMiddleware`-Implementierung verwendeten Defaultparameter sind standardmäßig restriktiv, daher mÃŧssen Sie bestimmte Origins, Methoden oder Header ausdrÃŧcklich aktivieren, damit Browser sie in einem Cross-Domain-Kontext verwenden dÃŧrfen. + +Die folgenden Argumente werden unterstÃŧtzt: + +* `allow_origins` – Eine Liste von Origins, die Cross-Origin-Requests machen dÃŧrfen. z. B. `['https://example.org', 'https://www.example.org']`. Sie kÃļnnen `['*']` verwenden, um jedes Origin zuzulassen. +* `allow_origin_regex` – Ein Regex-String zum Abgleichen gegen Origins, die Cross-Origin-Requests machen dÃŧrfen. z. B. `'https://.*\.example\.org'`. +* `allow_methods` – Eine Liste von HTTP-Methoden, die fÃŧr Cross-Origin-Requests erlaubt sein sollen. Standardmäßig `['GET']`. Sie kÃļnnen `['*']` verwenden, um alle Standardmethoden zu erlauben. +* `allow_headers` – Eine Liste von HTTP-Requestheadern, die fÃŧr Cross-Origin-Requests unterstÃŧtzt werden sollten. Standardmäßig `[]`. Sie kÃļnnen `['*']` verwenden, um alle Header zu erlauben. Die Header `Accept`, `Accept-Language`, `Content-Language` und `Content-Type` sind immer fÃŧr einfache CORS-Requests erlaubt. +* `allow_credentials` – Anzeigen, dass Cookies fÃŧr Cross-Origin-Requests unterstÃŧtzt werden sollten. Standardmäßig `False`. + + Keines der `allow_origins`, `allow_methods` und `allow_headers` kann auf `['*']` gesetzt werden, wenn `allow_credentials` auf `True` gesetzt ist. Alle mÃŧssen explizit angegeben werden. + +* `expose_headers` – Angabe der Responseheader, auf die der Browser zugreifen kÃļnnen soll. Standardmäßig `[]`. +* `max_age` – Legt eine maximale Zeit in Sekunden fest, die Browser CORS-Responses zwischenspeichern dÃŧrfen. Standardmäßig `600`. + +Die Middleware antwortet auf zwei besondere Arten von HTTP-Requests ... + +### CORS-Preflight-Requests { #cors-preflight-requests } + +Dies sind alle `OPTIONS`-Requests mit `Origin`- und `Access-Control-Request-Method`-Headern. + +In diesem Fall wird die Middleware den eingehenden Request abfangen und mit entsprechenden CORS-Headern, und entweder einer `200`- oder `400`-Response zu Informationszwecken antworten. + +### Einfache Requests { #simple-requests } + +Jeder Request mit einem `Origin`-Header. In diesem Fall wird die Middleware den Request wie gewohnt durchlassen, aber entsprechende CORS-Header in die Response aufnehmen. + +## Weitere Informationen { #more-info } + +Weitere Informationen zu CORS finden Sie in der Mozilla CORS-Dokumentation. + +/// note | Technische Details + +Sie kÃļnnten auch `from starlette.middleware.cors import CORSMiddleware` verwenden. + +**FastAPI** bietet mehrere Middlewares in `fastapi.middleware` nur als Komfort fÃŧr Sie, den Entwickler. Aber die meisten der verfÃŧgbaren Middlewares stammen direkt von Starlette. + +/// diff --git a/docs/de/docs/tutorial/debugging.md b/docs/de/docs/tutorial/debugging.md new file mode 100644 index 000000000..0a31f8653 --- /dev/null +++ b/docs/de/docs/tutorial/debugging.md @@ -0,0 +1,113 @@ +# Debugging { #debugging } + +Sie kÃļnnen den Debugger in Ihrem Editor verbinden, zum Beispiel mit Visual Studio Code oder PyCharm. + +## `uvicorn` aufrufen { #call-uvicorn } + +Importieren und fÃŧhren Sie `uvicorn` direkt in Ihrer FastAPI-Anwendung aus: + +{* ../../docs_src/debugging/tutorial001.py hl[1,15] *} + +### Über `__name__ == "__main__"` { #about-name-main } + +Der Hauptzweck von `__name__ == "__main__"` ist, dass Code ausgefÃŧhrt wird, wenn Ihre Datei mit folgendem Befehl aufgerufen wird: + +
+ +```console +$ python myapp.py +``` + +
+ +aber nicht aufgerufen wird, wenn eine andere Datei sie importiert, wie in: + +```Python +from myapp import app +``` + +#### Weitere Details { #more-details } + +Angenommen, Ihre Datei heißt `myapp.py`. + +Wenn Sie sie mit folgendem Befehl ausfÃŧhren: + +
+ +```console +$ python myapp.py +``` + +
+ +dann hat in Ihrer Datei die interne Variable `__name__`, die von Python automatisch erstellt wird, als Wert den String `"__main__"`. + +Daher wird der Abschnitt: + +```Python + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + +ausgefÃŧhrt. + +--- + +Dies wird nicht passieren, wenn Sie das Modul (die Datei) importieren. + +Wenn Sie also eine weitere Datei `importer.py` mit folgendem Inhalt haben: + +```Python +from myapp import app + +# Hier mehr Code +``` + +wird in diesem Fall in `myapp.py` die automatisch erstellte Variable `__name__` nicht den Wert `"__main__"` haben. + +Daher wird die Zeile: + +```Python + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + +nicht ausgefÃŧhrt. + +/// info | Info + +FÃŧr weitere Informationen besuchen Sie bitte die offizielle Python-Dokumentation. + +/// + +## Ihren Code mit Ihrem Debugger ausfÃŧhren { #run-your-code-with-your-debugger } + +Da Sie den Uvicorn-Server direkt aus Ihrem Code ausfÃŧhren, kÃļnnen Sie Ihr Python-Programm (Ihre FastAPI-Anwendung) direkt aus dem Debugger aufrufen. + +--- + +Zum Beispiel kÃļnnen Sie in Visual Studio Code: + +* Zum „Debug“-Panel gehen. +* „Konfiguration hinzufÃŧgen ...“ auswählen. +* „Python“ auswählen. +* Den Debugger mit der Option „`Python: Current File (Integrated Terminal)`“ ausfÃŧhren. + +Der Server wird dann mit Ihrem **FastAPI**-Code gestartet, an Ihren Haltepunkten angehalten, usw. + +So kÃļnnte es aussehen: + + + +--- + +Wenn Sie Pycharm verwenden, kÃļnnen Sie: + +* Das MenÃŧ „Run“ Ãļffnen. +* Die Option „Debug ...“ auswählen. +* Ein KontextmenÃŧ wird angezeigt. +* Die zu debuggende Datei auswählen (in diesem Fall `main.py`). + +Der Server wird dann mit Ihrem **FastAPI**-Code gestartet, an Ihren Haltepunkten angehalten, usw. + +So kÃļnnte es aussehen: + + diff --git a/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md index e9f25f786..3d4493f35 100644 --- a/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md @@ -1,10 +1,10 @@ -# Klassen als Abhängigkeiten +# Klassen als Abhängigkeiten { #classes-as-dependencies } Bevor wir tiefer in das **Dependency Injection** System eintauchen, lassen Sie uns das vorherige Beispiel verbessern. -## Ein `dict` aus dem vorherigen Beispiel +## Ein `dict` aus dem vorherigen Beispiel { #a-dict-from-the-previous-example } -Im vorherigen Beispiel haben wir ein `dict` von unserer Abhängigkeit („Dependable“) zurÃŧckgegeben: +Im vorherigen Beispiel haben wir ein `dict` von unserer Abhängigkeit („Dependable“) zurÃŧckgegeben: {* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *} @@ -14,7 +14,7 @@ Und wir wissen, dass Editoren nicht viel UnterstÃŧtzung (wie etwa Code-Vervollst Das kÃļnnen wir besser machen ... -## Was macht eine Abhängigkeit aus +## Was macht eine Abhängigkeit aus { #what-makes-a-dependency } Bisher haben Sie Abhängigkeiten gesehen, die als Funktionen deklariert wurden. @@ -38,7 +38,7 @@ something(some_argument, some_keyword_argument="foo") dann ist das ein „Callable“ (ein „Aufrufbares“). -## Klassen als Abhängigkeiten +## Klassen als Abhängigkeiten { #classes-as-dependencies_1 } MÃļglicherweise stellen Sie fest, dass Sie zum Erstellen einer Instanz einer Python-Klasse die gleiche Syntax verwenden. @@ -89,7 +89,7 @@ In beiden Fällen wird sie haben: In beiden Fällen werden die Daten konvertiert, validiert, im OpenAPI-Schema dokumentiert, usw. -## Verwendung +## Verwenden { #use-it } Jetzt kÃļnnen Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren. @@ -97,7 +97,7 @@ Jetzt kÃļnnen Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren. **FastAPI** ruft die Klasse `CommonQueryParams` auf. Dadurch wird eine „Instanz“ dieser Klasse erstellt und die Instanz wird als Parameter `commons` an Ihre Funktion Ãŧberreicht. -## Typannotation vs. `Depends` +## Typannotation vs. `Depends` { #type-annotation-vs-depends } Beachten Sie, wie wir `CommonQueryParams` im obigen Code zweimal schreiben: @@ -193,7 +193,7 @@ Es wird jedoch empfohlen, den Typ zu deklarieren, da Ihr Editor so weiß, was al -## AbkÃŧrzung +## AbkÃŧrzung { #shortcut } Aber Sie sehen, dass wir hier etwas Codeduplizierung haben, indem wir `CommonQueryParams` zweimal schreiben: diff --git a/docs/de/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/de/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md index bbba1a536..59c9fcf48 100644 --- a/docs/de/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md +++ b/docs/de/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md @@ -1,14 +1,14 @@ -# Abhängigkeiten in Pfadoperation-Dekoratoren +# Abhängigkeiten in Pfadoperation-Dekoratoren { #dependencies-in-path-operation-decorators } Manchmal benÃļtigen Sie den RÃŧckgabewert einer Abhängigkeit innerhalb Ihrer *Pfadoperation-Funktion* nicht wirklich. Oder die Abhängigkeit gibt keinen Wert zurÃŧck. -Aber Sie mÃŧssen Sie trotzdem ausfÃŧhren/auflÃļsen. +Aber Sie mÃŧssen sie trotzdem ausfÃŧhren/auflÃļsen. In diesen Fällen kÃļnnen Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list`e von `dependencies` zum *Pfadoperation-Dekorator* hinzufÃŧgen. -## `dependencies` zum *Pfadoperation-Dekorator* hinzufÃŧgen +## `dependencies` zum *Pfadoperation-Dekorator* hinzufÃŧgen { #add-dependencies-to-the-path-operation-decorator } Der *Pfadoperation-Dekorator* erhält ein optionales Argument `dependencies`. @@ -28,7 +28,7 @@ Damit wird auch vermieden, neue Entwickler mÃļglicherweise zu verwirren, die ein /// -/// info +/// info | Info In diesem Beispiel verwenden wir zwei erfundene benutzerdefinierte Header `X-Key` und `X-Token`. @@ -36,23 +36,23 @@ Aber in realen Fällen wÃŧrden Sie bei der Implementierung von Sicherheit mehr V /// -## Abhängigkeitsfehler und -RÃŧckgabewerte +## Abhängigkeitsfehler und -RÃŧckgabewerte { #dependencies-errors-and-return-values } Sie kÃļnnen dieselben Abhängigkeits-*Funktionen* verwenden, die Sie normalerweise verwenden. -### Abhängigkeitsanforderungen +### Abhängigkeitsanforderungen { #dependency-requirements } -Sie kÃļnnen Anforderungen fÃŧr einen Request (wie Header) oder andere Unterabhängigkeiten deklarieren: +Sie kÃļnnen Anforderungen fÃŧr einen Request (wie Header) oder andere Unterabhängigkeiten deklarieren: {* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *} -### Exceptions auslÃļsen +### Exceptions auslÃļsen { #raise-exceptions } Die Abhängigkeiten kÃļnnen Exceptions `raise`n, genau wie normale Abhängigkeiten: {* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *} -### RÃŧckgabewerte +### RÃŧckgabewerte { #return-values } Und sie kÃļnnen Werte zurÃŧckgeben oder nicht, die Werte werden nicht verwendet. @@ -60,10 +60,10 @@ Sie kÃļnnen also eine normale Abhängigkeit (die einen Wert zurÃŧckgibt), die Si {* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *} -## Abhängigkeiten fÃŧr eine Gruppe von *Pfadoperationen* +## Abhängigkeiten fÃŧr eine Gruppe von *Pfadoperationen* { #dependencies-for-a-group-of-path-operations } Wenn Sie später lesen, wie Sie grÃļßere Anwendungen strukturieren ([GrÃļßere Anwendungen – Mehrere Dateien](../../tutorial/bigger-applications.md){.internal-link target=_blank}), mÃļglicherweise mit mehreren Dateien, lernen Sie, wie Sie einen einzelnen `dependencies`-Parameter fÃŧr eine Gruppe von *Pfadoperationen* deklarieren. -## Globale Abhängigkeiten +## Globale Abhängigkeiten { #global-dependencies } Als Nächstes werden wir sehen, wie man Abhängigkeiten zur gesamten `FastAPI`-Anwendung hinzufÃŧgt, sodass sie fÃŧr jede *Pfadoperation* gelten. diff --git a/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md index 4b12f8447..178c2673e 100644 --- a/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md @@ -1,4 +1,4 @@ -# Abhängigkeiten mit yield +# Abhängigkeiten mit `yield` { #dependencies-with-yield } FastAPI unterstÃŧtzt Abhängigkeiten, die nach Abschluss einige zusätzliche Schritte ausfÃŧhren. @@ -23,11 +23,11 @@ Tatsächlich verwendet FastAPI diese beiden Dekoratoren intern. /// -## Eine Datenbank-Abhängigkeit mit `yield`. +## Eine Datenbank-Abhängigkeit mit `yield` { #a-database-dependency-with-yield } Sie kÃļnnten damit beispielsweise eine Datenbanksession erstellen und diese nach Abschluss schließen. -Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgefÃŧhrt, bevor eine Response erzeugt wird: +Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgefÃŧhrt, bevor eine Response erzeugt wird: {* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} @@ -35,19 +35,19 @@ Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeit {* ../../docs_src/dependencies/tutorial007.py hl[4] *} -Der auf die `yield`-Anweisung folgende Code wird ausgefÃŧhrt, nachdem die Response gesendet wurde: +Der auf die `yield`-Anweisung folgende Code wird ausgefÃŧhrt, nachdem die Response erstellt wurde, aber bevor sie gesendet wird: {* ../../docs_src/dependencies/tutorial007.py hl[5:6] *} /// tip | Tipp -Sie kÃļnnen `async`hrone oder reguläre Funktionen verwenden. +Sie kÃļnnen `async`- oder reguläre Funktionen verwenden. **FastAPI** wird bei jeder das Richtige tun, so wie auch bei normalen Abhängigkeiten. /// -## Eine Abhängigkeit mit `yield` und `try`. +## Eine Abhängigkeit mit `yield` und `try` { #a-dependency-with-yield-and-try } Wenn Sie einen `try`-Block in einer Abhängigkeit mit `yield` verwenden, empfangen Sie alle Exceptions, die bei Verwendung der Abhängigkeit geworfen wurden. @@ -59,7 +59,7 @@ Auf die gleiche Weise kÃļnnen Sie `finally` verwenden, um sicherzustellen, dass {* ../../docs_src/dependencies/tutorial007.py hl[3,5] *} -## Unterabhängigkeiten mit `yield`. +## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield } Sie kÃļnnen Unterabhängigkeiten und „Bäume“ von Unterabhängigkeiten beliebiger GrÃļße und Form haben, und einige oder alle davon kÃļnnen `yield` verwenden. @@ -93,7 +93,7 @@ Dieses funktioniert dank Pythons Dependency Injection
** System. +**FastAPI** hat ein sehr mächtiges, aber intuitives **Dependency Injection** System. Es ist so konzipiert, sehr einfach zu verwenden zu sein und es jedem Entwickler sehr leicht zu machen, andere Komponenten mit **FastAPI** zu integrieren. -## Was ist „Dependency Injection“ +## Was ist „Dependency Injection“ { #what-is-dependency-injection } **„Dependency Injection“** bedeutet in der Programmierung, dass es fÃŧr Ihren Code (in diesem Fall Ihre *Pfadoperation-Funktionen*) eine MÃļglichkeit gibt, Dinge zu deklarieren, die er verwenden mÃļchte und die er zum Funktionieren benÃļtigt: „Abhängigkeiten“ – „Dependencies“. @@ -19,15 +19,15 @@ Das ist sehr nÃŧtzlich, wenn Sie: All dies, während Sie Codeverdoppelung minimieren. -## Erste Schritte +## Erste Schritte { #first-steps } Sehen wir uns ein sehr einfaches Beispiel an. Es ist so einfach, dass es vorerst nicht sehr nÃŧtzlich ist. Aber so kÃļnnen wir uns besser auf die Funktionsweise des **Dependency Injection** Systems konzentrieren. -### Erstellen Sie eine Abhängigkeit („Dependable“) +### Eine Abhängigkeit erstellen, oder „Dependable“ { #create-a-dependency-or-dependable } -Konzentrieren wir uns zunächst auf die Abhängigkeit - die Dependency. +Konzentrieren wir uns zunächst auf die Abhängigkeit – die Dependency. Es handelt sich einfach um eine Funktion, die die gleichen Parameter entgegennimmt wie eine *Pfadoperation-Funktion*: {* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *} @@ -48,23 +48,23 @@ In diesem Fall erwartet diese Abhängigkeit: * Einen optionalen Query-Parameter `skip`, der ein `int` ist und standardmäßig `0` ist. * Einen optionalen Query-Parameter `limit`, der ein `int` ist und standardmäßig `100` ist. -Und dann wird einfach ein `dict` zurÃŧckgegeben, welches diese Werte enthält. +Und dann wird einfach ein `dict` zurÃŧckgegeben, welches diese Werte enthält. -/// info +/// info | Info FastAPI unterstÃŧtzt (und empfiehlt die Verwendung von) `Annotated` seit Version 0.95.0. Wenn Sie eine ältere Version haben, werden Sie Fehler angezeigt bekommen, wenn Sie versuchen, `Annotated` zu verwenden. -Bitte [aktualisieren Sie FastAPI](../../deployment/versions.md#upgrade-der-fastapi-versionen){.internal-link target=_blank} daher mindestens zu Version 0.95.1, bevor Sie `Annotated` verwenden. +Bitte [aktualisieren Sie FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} daher mindestens zu Version 0.95.1, bevor Sie `Annotated` verwenden. /// -### `Depends` importieren +### `Depends` importieren { #import-depends } {* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *} -### Deklarieren der Abhängigkeit im „Dependant“ +### Die Abhängigkeit im „Dependant“ deklarieren { #declare-the-dependency-in-the-dependant } So wie auch `Body`, `Query`, usw., verwenden Sie `Depends` mit den Parametern Ihrer *Pfadoperation-Funktion*: @@ -86,7 +86,7 @@ Im nächsten Kapitel erfahren Sie, welche anderen „Dinge“, außer Funktionen /// -Immer wenn ein neuer Request eintrifft, kÃŧmmert sich **FastAPI** darum: +Immer wenn ein neuer Request eintrifft, kÃŧmmert sich **FastAPI** darum: * Ihre Abhängigkeitsfunktion („Dependable“) mit den richtigen Parametern aufzurufen. * Sich das Ergebnis von dieser Funktion zu holen. @@ -105,7 +105,7 @@ common_parameters --> read_users Auf diese Weise schreiben Sie gemeinsam genutzten Code nur einmal, und **FastAPI** kÃŧmmert sich darum, ihn fÃŧr Ihre *Pfadoperationen* aufzurufen. -/// check +/// check | Testen Beachten Sie, dass Sie keine spezielle Klasse erstellen und diese irgendwo an **FastAPI** Ãŧbergeben mÃŧssen, um sie zu „registrieren“ oder so ähnlich. @@ -113,7 +113,7 @@ Sie Ãŧbergeben es einfach an `Depends` und **FastAPI** weiß, wie der Rest erled /// -## `Annotated`-Abhängigkeiten wiederverwenden +## `Annotated`-Abhängigkeiten wiederverwenden { #share-annotated-dependencies } In den Beispielen oben sehen Sie, dass es ein kleines bisschen **Codeverdoppelung** gibt. @@ -139,7 +139,7 @@ Die Abhängigkeiten funktionieren weiterhin wie erwartet, und das **Beste daran* Das ist besonders nÃŧtzlich, wenn Sie es in einer **großen Codebasis** verwenden, in der Sie in **vielen *Pfadoperationen*** immer wieder **dieselben Abhängigkeiten** verwenden. -## `async` oder nicht `async` +## `async` oder nicht `async` { #to-async-or-not-to-async } Da Abhängigkeiten auch von **FastAPI** aufgerufen werden (so wie Ihre *Pfadoperation-Funktionen*), gelten beim Definieren Ihrer Funktionen die gleichen Regeln. @@ -151,11 +151,11 @@ Es spielt keine Rolle. **FastAPI** weiß, was zu tun ist. /// note | Hinweis -Wenn Ihnen das nichts sagt, lesen Sie den [Async: *„In Eile?“*](../../async.md#in-eile){.internal-link target=_blank}-Abschnitt Ãŧber `async` und `await` in der Dokumentation. +Wenn Ihnen das nichts sagt, lesen Sie den [Async: *„In Eile?“*](../../async.md#in-a-hurry){.internal-link target=_blank}-Abschnitt Ãŧber `async` und `await` in der Dokumentation. /// -## Integriert in OpenAPI +## Integriert in OpenAPI { #integrated-with-openapi } Alle Requestdeklarationen, -validierungen und -anforderungen Ihrer Abhängigkeiten (und Unterabhängigkeiten) werden in dasselbe OpenAPI-Schema integriert. @@ -163,9 +163,9 @@ Die interaktive Dokumentation enthält also auch alle Informationen aus diesen A -## Einfache Verwendung +## Einfache Verwendung { #simple-usage } -Näher betrachtet, werden *Pfadoperation-Funktionen* deklariert, um verwendet zu werden, wann immer ein *Pfad* und eine *Operation* Ãŧbereinstimmen, und dann kÃŧmmert sich **FastAPI** darum, die Funktion mit den richtigen Parametern aufzurufen, die Daten aus der Anfrage extrahierend. +Näher betrachtet, werden *Pfadoperation-Funktionen* deklariert, um verwendet zu werden, wann immer ein *Pfad* und eine *Operation* Ãŧbereinstimmen, und dann kÃŧmmert sich **FastAPI** darum, die Funktion mit den richtigen Parametern aufzurufen, die Daten aus dem Request extrahierend. Tatsächlich funktionieren alle (oder die meisten) Webframeworks auf die gleiche Weise. @@ -181,7 +181,7 @@ Andere gebräuchliche Begriffe fÃŧr dieselbe Idee der „Abhängigkeitsinjektion * Injectables * Komponenten -## **FastAPI**-Plugins +## **FastAPI**-Plugins { #fastapi-plug-ins } Integrationen und „Plugins“ kÃļnnen mit dem **Dependency Injection** System erstellt werden. Aber tatsächlich besteht **keine Notwendigkeit, „Plugins“ zu erstellen**, da es durch die Verwendung von Abhängigkeiten mÃļglich ist, eine unendliche Anzahl von Integrationen und Interaktionen zu deklarieren, die dann fÃŧr Ihre *Pfadoperation-Funktionen* verfÃŧgbar sind. @@ -189,7 +189,7 @@ Und Abhängigkeiten kÃļnnen auf sehr einfache und intuitive Weise erstellt werde Beispiele hierfÃŧr finden Sie in den nächsten Kapiteln zu relationalen und NoSQL-Datenbanken, Sicherheit usw. -## **FastAPI**-Kompatibilität +## **FastAPI**-Kompatibilität { #fastapi-compatibility } Die Einfachheit des Dependency Injection Systems macht **FastAPI** kompatibel mit: @@ -199,10 +199,10 @@ Die Einfachheit des Dependency Injection Systems macht **FastAPI** kompatibel mi * externen APIs * Authentifizierungs- und Autorisierungssystemen * API-Nutzungs-Überwachungssystemen -* Responsedaten-Injektionssystemen +* Responsedaten-Injektionssystemen * usw. -## Einfach und leistungsstark +## Einfach und leistungsstark { #simple-and-powerful } Obwohl das hierarchische Dependency Injection System sehr einfach zu definieren und zu verwenden ist, ist es dennoch sehr mächtig. @@ -242,7 +242,7 @@ admin_user --> activate_user paying_user --> pro_items ``` -## Integriert mit **OpenAPI** +## Integriert mit **OpenAPI** { #integrated-with-openapi_1 } Alle diese Abhängigkeiten, während sie ihre Anforderungen deklarieren, fÃŧgen auch Parameter, Validierungen, usw. zu Ihren *Pfadoperationen* hinzu. diff --git a/docs/de/docs/tutorial/dependencies/sub-dependencies.md b/docs/de/docs/tutorial/dependencies/sub-dependencies.md index 66bdc7043..061952f92 100644 --- a/docs/de/docs/tutorial/dependencies/sub-dependencies.md +++ b/docs/de/docs/tutorial/dependencies/sub-dependencies.md @@ -1,4 +1,4 @@ -# Unterabhängigkeiten +# Unterabhängigkeiten { #sub-dependencies } Sie kÃļnnen Abhängigkeiten erstellen, die **Unterabhängigkeiten** haben. @@ -6,17 +6,17 @@ Diese kÃļnnen so **tief** verschachtelt sein, wie nÃļtig. **FastAPI** kÃŧmmert sich darum, sie aufzulÃļsen. -## Erste Abhängigkeit, „Dependable“ +## Erste Abhängigkeit, „Dependable“ { #first-dependency-dependable } Sie kÃļnnten eine erste Abhängigkeit („Dependable“) wie folgt erstellen: {* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *} -Diese deklariert einen optionalen Abfrageparameter `q` vom Typ `str` und gibt ihn dann einfach zurÃŧck. +Diese deklariert einen optionalen Query-Parameter `q` vom Typ `str` und gibt ihn dann einfach zurÃŧck. Das ist recht einfach (nicht sehr nÃŧtzlich), hilft uns aber dabei, uns auf die Funktionsweise der Unterabhängigkeiten zu konzentrieren. -## Zweite Abhängigkeit, „Dependable“ und „Dependant“ +## Zweite Abhängigkeit, „Dependable“ und „Dependant“ { #second-dependency-dependable-and-dependant } Dann kÃļnnen Sie eine weitere Abhängigkeitsfunktion (ein „Dependable“) erstellen, die gleichzeitig eine eigene Abhängigkeit deklariert (also auch ein „Dependant“ ist): @@ -29,17 +29,17 @@ Betrachten wir die deklarierten Parameter: * Sie deklariert außerdem ein optionales `last_query`-Cookie, ein `str`. * Wenn der Benutzer keine Query `q` Ãŧbermittelt hat, verwenden wir die zuletzt Ãŧbermittelte Query, die wir zuvor in einem Cookie gespeichert haben. -## Die Abhängigkeit verwenden +## Die Abhängigkeit verwenden { #use-the-dependency } Diese Abhängigkeit verwenden wir nun wie folgt: {* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *} -/// info +/// info | Info Beachten Sie, dass wir in der *Pfadoperation-Funktion* nur eine einzige Abhängigkeit deklarieren, den `query_or_cookie_extractor`. -Aber **FastAPI** wird wissen, dass es zuerst `query_extractor` auflÃļsen muss, um dessen Resultat `query_or_cookie_extractor` zu Ãŧbergeben, wenn dieses aufgerufen wird. +Aber **FastAPI** wird wissen, dass es zuerst `query_extractor` auflÃļsen muss, um dessen Resultat an `query_or_cookie_extractor` zu Ãŧbergeben, wenn dieses aufgerufen wird. /// @@ -54,13 +54,13 @@ read_query["/items/"] query_extractor --> query_or_cookie_extractor --> read_query ``` -## Dieselbe Abhängigkeit mehrmals verwenden +## Dieselbe Abhängigkeit mehrmals verwenden { #using-the-same-dependency-multiple-times } -Wenn eine Ihrer Abhängigkeiten mehrmals fÃŧr dieselbe *Pfadoperation* deklariert wird, beispielsweise wenn mehrere Abhängigkeiten eine gemeinsame Unterabhängigkeit haben, wird **FastAPI** diese Unterabhängigkeit nur einmal pro Request aufrufen. +Wenn eine Ihrer Abhängigkeiten mehrmals fÃŧr dieselbe *Pfadoperation* deklariert wird, beispielsweise wenn mehrere Abhängigkeiten eine gemeinsame Unterabhängigkeit haben, wird **FastAPI** diese Unterabhängigkeit nur einmal pro Request aufrufen. Und es speichert den zurÃŧckgegebenen Wert in einem „Cache“ und Ãŧbergibt diesen gecachten Wert an alle „Dependanten“, die ihn in diesem spezifischen Request benÃļtigen, anstatt die Abhängigkeit mehrmals fÃŧr denselben Request aufzurufen. -In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (mÃļglicherweise mehrmals) in derselben Anfrage aufgerufen werden muss, anstatt den zwischengespeicherten Wert zu verwenden, kÃļnnen Sie den Parameter `use_cache=False` festlegen, wenn Sie `Depends` verwenden: +In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (mÃļglicherweise mehrmals) in demselben Request aufgerufen werden muss, anstatt den zwischengespeicherten Wert zu verwenden, kÃļnnen Sie den Parameter `use_cache=False` festlegen, wenn Sie `Depends` verwenden: //// tab | Python 3.8+ @@ -86,7 +86,7 @@ async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False //// -## Zusammenfassung +## Zusammenfassung { #recap } Abgesehen von all den ausgefallenen WÃļrtern, die hier verwendet werden, ist das **Dependency Injection**-System recht simpel. diff --git a/docs/de/docs/tutorial/encoder.md b/docs/de/docs/tutorial/encoder.md index 5678d7b8f..25dc6fa18 100644 --- a/docs/de/docs/tutorial/encoder.md +++ b/docs/de/docs/tutorial/encoder.md @@ -1,12 +1,12 @@ -# JSON-kompatibler Encoder +# JSON-kompatibler Encoder { #json-compatible-encoder } -Es gibt Fälle, da mÃļchten Sie einen Datentyp (etwa ein Pydantic-Modell) in etwas konvertieren, das kompatibel mit JSON ist (etwa ein `dict`, eine `list`e, usw.). +Es gibt Fälle, da mÃļchten Sie einen Datentyp (etwa ein Pydantic-Modell) in etwas konvertieren, das kompatibel mit JSON ist (etwa ein `dict`, eine `list`, usw.). Zum Beispiel, wenn Sie es in einer Datenbank speichern mÃļchten. DafÃŧr bietet **FastAPI** eine Funktion `jsonable_encoder()`. -## `jsonable_encoder` verwenden +## `jsonable_encoder` verwenden { #using-the-jsonable-encoder } Stellen wir uns vor, Sie haben eine Datenbank `fake_db`, die nur JSON-kompatible Daten entgegennimmt. diff --git a/docs/de/docs/tutorial/extra-data-types.md b/docs/de/docs/tutorial/extra-data-types.md index 334f32f7b..5002f0534 100644 --- a/docs/de/docs/tutorial/extra-data-types.md +++ b/docs/de/docs/tutorial/extra-data-types.md @@ -1,4 +1,4 @@ -# Zusätzliche Datentypen +# Zusätzliche Datentypen { #extra-data-types } Bisher haben Sie gängige Datentypen verwendet, wie zum Beispiel: @@ -12,12 +12,12 @@ Sie kÃļnnen aber auch komplexere Datentypen verwenden. Und Sie haben immer noch dieselbe Funktionalität wie bisher gesehen: * Großartige Editor-UnterstÃŧtzung. -* Datenkonvertierung bei eingehenden Requests. -* Datenkonvertierung fÃŧr Response-Daten. +* Datenkonvertierung bei eingehenden Requests. +* Datenkonvertierung fÃŧr Response-Daten. * Datenvalidierung. * Automatische Annotation und Dokumentation. -## Andere Datentypen +## Andere Datentypen { #other-data-types } Hier sind einige der zusätzlichen Datentypen, die Sie verwenden kÃļnnen: @@ -36,11 +36,11 @@ Hier sind einige der zusätzlichen Datentypen, die Sie verwenden kÃļnnen: * `datetime.timedelta`: * Ein Python-`datetime.timedelta`. * Wird in Requests und Responses als `float` der Gesamtsekunden dargestellt. - * Pydantic ermÃļglicht auch die Darstellung als „ISO 8601 Zeitdifferenz-Kodierung“, Weitere Informationen finden Sie in der Dokumentation. + * Pydantic ermÃļglicht auch die Darstellung als „ISO 8601 Zeitdifferenz-Kodierung“, siehe die Dokumentation fÃŧr weitere Informationen. * `frozenset`: * Wird in Requests und Responses wie ein `set` behandelt: * Bei Requests wird eine Liste gelesen, Duplikate entfernt und in ein `set` umgewandelt. - * Bei Responses wird das `set` in eine `list`e umgewandelt. + * Bei Responses wird das `set` in eine `list` umgewandelt. * Das generierte Schema zeigt an, dass die `set`-Werte eindeutig sind (unter Verwendung von JSON Schemas `uniqueItems`). * `bytes`: * Standard-Python-`bytes`. @@ -49,9 +49,9 @@ Hier sind einige der zusätzlichen Datentypen, die Sie verwenden kÃļnnen: * `Decimal`: * Standard-Python-`Decimal`. * In Requests und Responses wird es wie ein `float` behandelt. -* Sie kÃļnnen alle gÃŧltigen Pydantic-Datentypen hier ÃŧberprÃŧfen: Pydantic data types. +* Sie kÃļnnen alle gÃŧltigen Pydantic-Datentypen hier ÃŧberprÃŧfen: Pydantic-Datentypen. -## Beispiel +## Beispiel { #example } Hier ist ein Beispiel fÃŧr eine *Pfadoperation* mit Parametern, die einige der oben genannten Typen verwenden. diff --git a/docs/de/docs/tutorial/extra-models.md b/docs/de/docs/tutorial/extra-models.md index 6aad1c0f4..967e8535b 100644 --- a/docs/de/docs/tutorial/extra-models.md +++ b/docs/de/docs/tutorial/extra-models.md @@ -1,42 +1,42 @@ -# Extramodelle +# Extramodelle { #extra-models } -Fahren wir beim letzten Beispiel fort. Es gibt normalerweise mehrere zusammengehÃļrende Modelle. +Im Anschluss an das vorherige Beispiel ist es Ãŧblich, mehr als ein zusammenhängendes Modell zu haben. -Insbesondere Benutzermodelle, denn: +Dies gilt insbesondere fÃŧr Benutzermodelle, denn: -* Das **hereinkommende Modell** sollte ein Passwort haben kÃļnnen. -* Das **herausgehende Modell** sollte kein Passwort haben. -* Das **Datenbankmodell** sollte wahrscheinlich ein gehashtes Passwort haben. +* Das **Eingabemodell** muss ein Passwort enthalten kÃļnnen. +* Das **Ausgabemodell** sollte kein Passwort haben. +* Das **Datenbankmodell** mÃŧsste wahrscheinlich ein gehashtes Passwort haben. /// danger | Gefahr -Speichern Sie niemals das Klartext-Passwort eines Benutzers. Speichern Sie immer den „sicheren Hash“, den Sie verifizieren kÃļnnen. +Speichern Sie niemals das Klartextpasswort eines Benutzers. Speichern Sie immer einen „sicheren Hash“, den Sie dann verifizieren kÃļnnen. -Falls Ihnen das nichts sagt, in den [Sicherheits-Kapiteln](security/simple-oauth2.md#passwort-hashing){.internal-link target=_blank} werden Sie lernen, was ein „Passwort-Hash“ ist. +Wenn Sie nicht wissen, was das ist, werden Sie in den [Sicherheitskapiteln](security/simple-oauth2.md#password-hashing){.internal-link target=_blank} lernen, was ein „Passworthash“ ist. /// -## Mehrere Modelle +## Mehrere Modelle { #multiple-models } -Hier der generelle Weg, wie die Modelle mit ihren Passwort-Feldern aussehen kÃļnnten, und an welchen Orten sie verwendet werden wÃŧrden. +Hier ist eine allgemeine Idee, wie die Modelle mit ihren Passwortfeldern aussehen kÃļnnten und an welchen Stellen sie verwendet werden: {* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *} -/// info +/// info | Info -In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie deprecated (aber immer noch unterstÃŧtzt) und in `.model_dump()` umbenannt. +In Pydantic v1 hieß die Methode `.dict()`, in Pydantic v2 wurde sie deprecatet (aber weiterhin unterstÃŧtzt) und in `.model_dump()` umbenannt. -Die Beispiele hier verwenden `.dict()` fÃŧr die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden kÃļnnen. +Die Beispiele hier verwenden `.dict()` fÃŧr die Kompatibilität mit Pydantic v1, aber Sie sollten `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden kÃļnnen. /// -### Über `**user_in.dict()` +### Über `**user_in.dict()` { #about-user-in-dict } -#### Pydantic's `.dict()` +#### Die `.dict()`-Methode von Pydantic { #pydantics-dict } `user_in` ist ein Pydantic-Modell der Klasse `UserIn`. -Pydantic-Modelle haben eine `.dict()`-Methode, die ein `dict` mit den Daten des Modells zurÃŧckgibt. +Pydantic-Modelle haben eine `.dict()`-Methode, die ein `dict` mit den Daten des Modells zurÃŧckgibt. Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so: @@ -44,21 +44,21 @@ Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so: user_in = UserIn(username="john", password="secret", email="john.doe@example.com") ``` -und wir rufen seine `.dict()`-Methode auf: +und dann aufrufen: ```Python user_dict = user_in.dict() ``` -dann haben wir jetzt in der Variable `user_dict` ein `dict` mit den gleichen Daten (es ist ein `dict` statt eines Pydantic-Modellobjekts). +haben wir jetzt ein `dict` mit den Daten in der Variablen `user_dict` (es ist ein `dict` statt eines Pydantic-Modellobjekts). -Wenn wir es ausgeben: +Und wenn wir aufrufen: ```Python print(user_dict) ``` -bekommen wir ein Python-`dict`: +wÃŧrden wir ein Python-`dict` erhalten mit: ```Python { @@ -69,17 +69,17 @@ bekommen wir ein Python-`dict`: } ``` -#### Ein `dict` entpacken +#### Ein `dict` entpacken { #unpacking-a-dict } -Wenn wir ein `dict` wie `user_dict` nehmen, und es einer Funktion (oder Klassenmethode) mittels `**user_dict` Ãŧbergeben, wird Python es „entpacken“. Es wird die SchlÃŧssel und Werte von `user_dict` direkt als SchlÃŧsselwort-Argumente Ãŧbergeben. +Wenn wir ein `dict` wie `user_dict` nehmen und es einer Funktion (oder Klasse) mit `**user_dict` Ãŧbergeben, wird Python es „entpacken“. Es wird die SchlÃŧssel und Werte von `user_dict` direkt als SchlÃŧsselwort-Argumente Ãŧbergeben. -Wenn wir also das `user_dict` von oben nehmen und schreiben: +Setzen wir also das `user_dict` von oben ein: ```Python UserInDB(**user_dict) ``` -dann ist das ungefähr äquivalent zu: +so ist das äquivalent zu: ```Python UserInDB( @@ -90,7 +90,7 @@ UserInDB( ) ``` -Oder, präziser, `user_dict` wird direkt verwendet, welche Werte es auch immer haben mag: +Oder genauer gesagt, dazu, `user_dict` direkt zu verwenden, mit welchen Inhalten es auch immer in der Zukunft haben mag: ```Python UserInDB( @@ -101,34 +101,34 @@ UserInDB( ) ``` -#### Ein Pydantic-Modell aus den Inhalten eines anderen erstellen. +#### Ein Pydantic-Modell aus dem Inhalt eines anderen { #a-pydantic-model-from-the-contents-of-another } -Da wir in obigem Beispiel `user_dict` mittels `user_in.dict()` erzeugt haben, ist dieser Code: +Da wir im obigen Beispiel `user_dict` von `user_in.dict()` bekommen haben, wäre dieser Code: ```Python user_dict = user_in.dict() UserInDB(**user_dict) ``` -äquivalent zu: +gleichwertig zu: ```Python UserInDB(**user_in.dict()) ``` -... weil `user_in.dict()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es `UserInDB` Ãŧbergeben, mit vorangestelltem `**`. +... weil `user_in.dict()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` Ãŧbergeben. -Wir erhalten also ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells. +Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells. -#### Ein `dict` entpacken und zusätzliche SchlÃŧsselwort-Argumente +#### Ein `dict` entpacken und zusätzliche SchlÃŧsselwort-Argumente { #unpacking-a-dict-and-extra-keywords } -Und dann fÃŧgen wir ein noch weiteres SchlÃŧsselwort-Argument hinzu, `hashed_password=hashed_password`: +Und dann fÃŧgen wir das zusätzliche SchlÃŧsselwort-Argument `hashed_password=hashed_password` hinzu, wie in: ```Python UserInDB(**user_in.dict(), hashed_password=hashed_password) ``` -... was am Ende ergibt: +... was so ist wie: ```Python UserInDB( @@ -142,78 +142,81 @@ UserInDB( /// warning | Achtung -Die Hilfsfunktionen `fake_password_hasher` und `fake_save_user` demonstrieren nur den mÃļglichen Fluss der Daten und bieten natÃŧrlich keine echte Sicherheit. +Die unterstÃŧtzenden zusätzlichen Funktionen `fake_password_hasher` und `fake_save_user` dienen nur zur Demo eines mÃļglichen Datenflusses, bieten jedoch natÃŧrlich keine echte Sicherheit. /// -## Verdopplung vermeiden +## Verdopplung vermeiden { #reduce-duplication } -Reduzierung von Code-Verdoppelung ist eine der Kern-Ideen von **FastAPI**. +Die Reduzierung von Code-Verdoppelung ist eine der Kernideen von **FastAPI**. -Weil Verdoppelung von Code die Wahrscheinlichkeit von Fehlern, Sicherheitsproblemen, Desynchronisation (Code wird nur an einer Stelle verändert, aber nicht an einer anderen), usw. erhÃļht. +Da die Verdopplung von Code die Wahrscheinlichkeit von Fehlern, Sicherheitsproblemen, Problemen mit der Desynchronisation des Codes (wenn Sie an einer Stelle, aber nicht an der anderen aktualisieren) usw. erhÃļht. -Unsere Modelle teilen alle eine Menge der Daten und verdoppeln Attribut-Namen und -Typen. +Und diese Modelle teilen alle eine Menge der Daten und verdoppeln Attributnamen und -typen. -Das kÃļnnen wir besser machen. +Wir kÃļnnten es besser machen. -Wir deklarieren ein `UserBase`-Modell, das als Basis fÃŧr unsere anderen Modelle dient. Dann kÃļnnen wir Unterklassen erstellen, die seine Attribute (Typdeklarationen, Validierungen, usw.) erben. +Wir kÃļnnen ein `UserBase`-Modell deklarieren, das als Basis fÃŧr unsere anderen Modelle dient. Und dann kÃļnnen wir Unterklassen dieses Modells erstellen, die seine Attribute (Typdeklarationen, Validierung usw.) erben. -Die ganze Datenkonvertierung, -validierung, -dokumentation, usw. wird immer noch wie gehabt funktionieren. +Die ganze Datenkonvertierung, -validierung, -dokumentation usw. wird immer noch wie gewohnt funktionieren. -Auf diese Weise beschreiben wir nur noch die Unterschiede zwischen den Modellen (mit Klartext-`password`, mit `hashed_password`, und ohne Passwort): +Auf diese Weise kÃļnnen wir nur die Unterschiede zwischen den Modellen (mit Klartext-`password`, mit `hashed_password` und ohne Passwort) deklarieren: {* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *} -## `Union`, oder `anyOf` +## `Union` oder `anyOf` { #union-or-anyof } -Sie kÃļnnen deklarieren, dass eine Response eine `Union` mehrerer Typen ist, sprich, einer dieser Typen. +Sie kÃļnnen deklarieren, dass eine Response eine `Union` mehrerer Typen ist, das bedeutet, dass die Response einer von ihnen ist. -Das wird in OpenAPI mit `anyOf` angezeigt. +Dies wird in OpenAPI mit `anyOf` definiert. -Um das zu tun, verwenden Sie Pythons Standard-Typhinweis `typing.Union`: +Um das zu tun, verwenden Sie den Standard-Python-Typhinweis `typing.Union`: /// note | Hinweis -Listen Sie, wenn Sie eine `Union` definieren, denjenigen Typ zuerst, der am spezifischsten ist, gefolgt von den weniger spezifischen Typen. Im Beispiel oben, in `Union[PlaneItem, CarItem]` also den spezifischeren `PlaneItem` vor dem weniger spezifischen `CarItem`. +Wenn Sie eine `Union` definieren, listen Sie den spezifischeren Typ zuerst auf, gefolgt vom weniger spezifischen Typ. Im Beispiel unten steht `PlaneItem` vor `CarItem` in `Union[PlaneItem, CarItem]`. /// {* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *} -### `Union` in Python 3.10 -In diesem Beispiel Ãŧbergeben wir dem Argument `response_model` den Wert `Union[PlaneItem, CarItem]`. +### `Union` in Python 3.10 { #union-in-python-3-10 } -Da wir es als **Wert einem Argument Ãŧberreichen**, statt es als **Typannotation** zu verwenden, mÃŧssen wir `Union` verwenden, selbst in Python 3.10. +In diesem Beispiel Ãŧbergeben wir `Union[PlaneItem, CarItem]` als Wert des Arguments `response_model`. -Wenn es eine Typannotation gewesen wäre, hätten wir auch den vertikalen Trennstrich verwenden kÃļnnen, wie in: +Da wir es als **Wert an ein Argument Ãŧbergeben**, anstatt es in einer **Typannotation** zu verwenden, mÃŧssen wir `Union` verwenden, sogar in Python 3.10. + +Wäre es eine Typannotation gewesen, hätten wir den vertikalen Strich verwenden kÃļnnen, wie in: ```Python some_variable: PlaneItem | CarItem ``` -Aber wenn wir das in der Zuweisung `response_model=PlaneItem | CarItem` machen, erhalten wir eine Fehlermeldung, da Python versucht, eine **ungÃŧltige Operation** zwischen `PlaneItem` und `CarItem` durchzufÃŧhren, statt es als Typannotation zu interpretieren. +Aber wenn wir das in der Zuweisung `response_model=PlaneItem | CarItem` machen, wÃŧrden wir einen Fehler erhalten, weil Python versuchen wÃŧrde, eine **ungÃŧltige Operation** zwischen `PlaneItem` und `CarItem` auszufÃŧhren, anstatt es als Typannotation zu interpretieren. -## Listen von Modellen +## Liste von Modellen { #list-of-models } -Genauso kÃļnnen Sie eine Response deklarieren, die eine Liste von Objekten ist. +Auf die gleiche Weise kÃļnnen Sie Responses von Listen von Objekten deklarieren. -Verwenden Sie dafÃŧr Pythons Standard `typing.List` (oder nur `list` in Python 3.9 und darÃŧber): +DafÃŧr verwenden Sie Pythons Standard-`typing.List` (oder nur `list` in Python 3.9 und hÃļher): {* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *} -## Response mit beliebigem `dict` -Sie kÃļnne auch eine Response deklarieren, die ein beliebiges `dict` zurÃŧckgibt, bei dem nur die Typen der SchlÃŧssel und der Werte bekannt sind, ohne ein Pydantic-Modell zu verwenden. +## Response mit beliebigem `dict` { #response-with-arbitrary-dict } -Das ist nÃŧtzlich, wenn Sie die gÃŧltigen Feld-/Attribut-Namen von vorneherein nicht wissen (was fÃŧr ein Pydantic-Modell notwendig ist). +Sie kÃļnnen auch eine Response deklarieren, die ein beliebiges `dict` zurÃŧckgibt, indem Sie nur die Typen der SchlÃŧssel und Werte ohne ein Pydantic-Modell deklarieren. -In diesem Fall kÃļnnen Sie `typing.Dict` verwenden (oder nur `dict` in Python 3.9 und darÃŧber): +Dies ist nÃŧtzlich, wenn Sie die gÃŧltigen Feld-/Attributnamen nicht im Voraus kennen (die fÃŧr ein Pydantic-Modell benÃļtigt werden wÃŧrden). + +In diesem Fall kÃļnnen Sie `typing.Dict` verwenden (oder nur `dict` in Python 3.9 und hÃļher): {* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *} -## Zusammenfassung + +## Zusammenfassung { #recap } Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf. -Sie brauchen kein einzelnes Datenmodell pro Einheit, wenn diese Einheit verschiedene Zustände annehmen kann. So wie unsere Benutzer-„Einheit“, welche einen Zustand mit `password`, einen mit `password_hash` und einen ohne Passwort hatte. +Sie brauchen kein einzelnes Datenmodell pro Einheit, wenn diese Einheit in der Lage sein muss, verschiedene „Zustände“ zu haben. Wie im Fall der Benutzer-„Einheit“ mit einem Zustand einschließlich `password`, `password_hash` und ohne Passwort. diff --git a/docs/de/docs/tutorial/first-steps.md b/docs/de/docs/tutorial/first-steps.md index 3104c8d61..374127c17 100644 --- a/docs/de/docs/tutorial/first-steps.md +++ b/docs/de/docs/tutorial/first-steps.md @@ -1,64 +1,80 @@ -# Erste Schritte +# Erste Schritte { #first-steps } Die einfachste FastAPI-Datei kÃļnnte wie folgt aussehen: {* ../../docs_src/first_steps/tutorial001.py *} -Kopieren Sie dies in eine Datei `main.py`. +Kopieren Sie das in eine Datei `main.py`. Starten Sie den Live-Server:
```console -$ uvicorn main:app --reload +$ fastapi dev main.py -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. + FastAPI Starting development server 🚀 + + Searching for package file structure from directories + with __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with + the following code: + + from main import app + + app Using import string: main:app + + server Server started at http://127.0.0.1:8000 + server Documentation at http://127.0.0.1:8000/docs + + tip Running in development mode, for production use: + fastapi run + + Logs: + + INFO Will watch for changes in these directories: + ['/home/user/code/awesomeapp'] + INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C + to quit) + INFO Started reloader process [383138] using WatchFiles + INFO Started server process [383153] + INFO Waiting for application startup. + INFO Application startup complete. ```
-/// note | Hinweis - -Der Befehl `uvicorn main:app` bezieht sich auf: - -* `main`: die Datei `main.py` (das sogenannte Python-„Modul“). -* `app`: das Objekt, welches in der Datei `main.py` mit der Zeile `app = FastAPI()` erzeugt wurde. -* `--reload`: lässt den Server nach Codeänderungen neu starten. Verwenden Sie das nur während der Entwicklung. - -/// - In der Konsolenausgabe sollte es eine Zeile geben, die ungefähr so aussieht: ```hl_lines="4" INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` -Diese Zeile zeigt die URL, unter der Ihre Anwendung auf Ihrem lokalen Computer bereitgestellt wird. +Diese Zeile zeigt die URL, unter der Ihre App auf Ihrem lokalen Computer bereitgestellt wird. -### Testen Sie es +### Es testen { #check-it } -Öffnen Sie Ihren Browser unter http://127.0.0.1:8000. +Öffnen Sie Ihren Browser unter http://127.0.0.1:8000. -Sie werden folgende JSON-Response sehen: +Sie werden die JSON-Response sehen: ```JSON {"message": "Hello World"} ``` -### Interaktive API-Dokumentation +### Interaktive API-Dokumentation { #interactive-api-docs } -Gehen Sie als Nächstes auf http://127.0.0.1:8000/docs . +Gehen Sie als Nächstes auf http://127.0.0.1:8000/docs. Sie werden die automatisch erzeugte, interaktive API-Dokumentation sehen (bereitgestellt durch Swagger UI): ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) -### Alternative API-Dokumentation +### Alternative API-Dokumentation { #alternative-api-docs } Gehen Sie nun auf http://127.0.0.1:8000/redoc. @@ -66,31 +82,31 @@ Dort sehen Sie die alternative, automatische Dokumentation (bereitgestellt durch ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) -### OpenAPI +### OpenAPI { #openapi } **FastAPI** generiert ein „Schema“ mit all Ihren APIs unter Verwendung des **OpenAPI**-Standards zur Definition von APIs. -#### „Schema“ +#### „Schema“ { #schema } Ein „Schema“ ist eine Definition oder Beschreibung von etwas. Nicht der eigentliche Code, der es implementiert, sondern lediglich eine abstrakte Beschreibung. -#### API-„Schema“ +#### API-„Schema“ { #api-schema } -In diesem Fall ist OpenAPI eine Spezifikation, die vorschreibt, wie ein Schema fÃŧr Ihre API zu definieren ist. +In diesem Fall ist OpenAPI eine Spezifikation, die vorschreibt, wie ein Schema fÃŧr Ihre API zu definieren ist. Diese Schemadefinition enthält Ihre API-Pfade, die mÃļglichen Parameter, welche diese entgegennehmen, usw. -#### Daten-„Schema“ +#### Daten-„Schema“ { #data-schema } Der Begriff „Schema“ kann sich auch auf die Form von Daten beziehen, wie z. B. einen JSON-Inhalt. In diesem Fall sind die JSON-Attribute und deren Datentypen, usw. gemeint. -#### OpenAPI und JSON Schema +#### OpenAPI und JSON Schema { #openapi-and-json-schema } OpenAPI definiert ein API-Schema fÃŧr Ihre API. Dieses Schema enthält Definitionen (oder „Schemas“) der Daten, die von Ihrer API unter Verwendung von **JSON Schema**, dem Standard fÃŧr JSON-Datenschemata, gesendet und empfangen werden. -#### ÜberprÃŧfen Sie die `openapi.json` +#### Die `openapi.json` testen { #check-the-openapi-json } Falls Sie wissen mÃļchten, wie das rohe OpenAPI-Schema aussieht: FastAPI generiert automatisch ein JSON (Schema) mit den Beschreibungen Ihrer gesamten API. @@ -119,7 +135,7 @@ Es wird ein JSON angezeigt, welches ungefähr so aussieht: ... ``` -#### WofÃŧr OpenAPI gedacht ist +#### WofÃŧr OpenAPI gedacht ist { #what-is-openapi-for } Das OpenAPI-Schema ist die Grundlage fÃŧr die beiden enthaltenen interaktiven Dokumentationssysteme. @@ -127,9 +143,9 @@ Es gibt dutzende Alternativen, die alle auf OpenAPI basieren. Sie kÃļnnen jede d Ebenfalls kÃļnnen Sie es verwenden, um automatisch Code fÃŧr Clients zu generieren, die mit Ihrer API kommunizieren. Zum Beispiel fÃŧr Frontend-, Mobile- oder IoT-Anwendungen. -## RÃŧckblick, Schritt fÃŧr Schritt +## Zusammenfassung, Schritt fÃŧr Schritt { #recap-step-by-step } -### Schritt 1: Importieren von `FastAPI` +### Schritt 1: `FastAPI` importieren { #step-1-import-fastapi } {* ../../docs_src/first_steps/tutorial001.py hl[1] *} @@ -137,13 +153,13 @@ Ebenfalls kÃļnnen Sie es verwenden, um automatisch Code fÃŧr Clients zu generier /// note | Technische Details -`FastAPI` ist eine Klasse, die direkt von `Starlette` erbt. +`FastAPI` ist eine Klasse, die direkt von `Starlette` erbt. Sie kÃļnnen alle Starlette-Funktionalitäten auch mit `FastAPI` nutzen. /// -### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ +### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ { #step-2-create-a-fastapi-instance } {* ../../docs_src/first_steps/tutorial001.py hl[3] *} @@ -151,37 +167,9 @@ In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI Dies wird der Hauptinteraktionspunkt fÃŧr die Erstellung all Ihrer APIs sein. -Die Variable `app` ist dieselbe, auf die sich der Befehl `uvicorn` bezieht: +### Schritt 3: Erstellen einer *Pfadoperation* { #step-3-create-a-path-operation } -
- -```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -Wenn Sie Ihre Anwendung wie folgt erstellen: - -{* ../../docs_src/first_steps/tutorial002.py hl[3] *} - -Und in eine Datei `main.py` einfÃŧgen, dann wÃŧrden Sie `uvicorn` wie folgt aufrufen: - -
- -```console -$ uvicorn main:my_awesome_api --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -### Schritt 3: Erstellen einer *Pfadoperation* - -#### Pfad +#### Pfad { #path } „Pfad“ bezieht sich hier auf den letzten Teil der URL, beginnend mit dem ersten `/`. @@ -197,7 +185,7 @@ https://example.com/items/foo /items/foo ``` -/// info +/// info | Info Ein „Pfad“ wird häufig auch als „Endpunkt“ oder „Route“ bezeichnet. @@ -205,7 +193,7 @@ Ein „Pfad“ wird häufig auch als „Endpunkt“ oder „Route“ bezeichnet. Bei der Erstellung einer API ist der „Pfad“ die wichtigste MÃļglichkeit zur Trennung von „Anliegen“ und „Ressourcen“. -#### Operation +#### Operation { #operation } „Operation“ bezieht sich hier auf eine der HTTP-„Methoden“. @@ -240,16 +228,16 @@ In OpenAPI wird folglich jede dieser HTTP-Methoden als „Operation“ bezeichne Wir werden sie auch „**Operationen**“ nennen. -#### Definieren eines *Pfadoperation-Dekorators* +#### Definieren eines *Pfadoperation-Dekorators* { #define-a-path-operation-decorator } {* ../../docs_src/first_steps/tutorial001.py hl[6] *} -Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter fÃŧr die Bearbeitung von Anfragen zuständig ist, die an: +Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter fÃŧr die Bearbeitung von Requests zuständig ist, die an: - * den Pfad `/` - * unter der Verwendung der get-Operation gehen +* den Pfad `/` +* unter der Verwendung der get-Operation gehen -/// info | `@decorator` Information +/// info | `@decorator` Info Diese `@something`-Syntax wird in Python „Dekorator“ genannt. @@ -269,7 +257,7 @@ Sie kÃļnnen auch die anderen Operationen verwenden: * `@app.put()` * `@app.delete()` -Oder die exotischeren: +Und die exotischeren: * `@app.options()` * `@app.head()` @@ -288,7 +276,7 @@ Wenn Sie beispielsweise GraphQL verwenden, fÃŧhren Sie normalerweise alle Aktion /// -### Schritt 4: Definieren der **Pfadoperation-Funktion** +### Schritt 4: Definieren der **Pfadoperation-Funktion** { #step-4-define-the-path-operation-function } Das ist unsere „**Pfadoperation-Funktion**“: @@ -300,7 +288,7 @@ Das ist unsere „**Pfadoperation-Funktion**“: Dies ist eine Python-Funktion. -Sie wird von **FastAPI** immer dann aufgerufen, wenn sie eine Anfrage an die URL "`/`" mittels einer `GET`-Operation erhält. +Sie wird von **FastAPI** immer dann aufgerufen, wenn sie einen Request an die URL „`/`“ mittels einer `GET`-Operation erhält. In diesem Fall handelt es sich um eine `async`-Funktion. @@ -312,11 +300,11 @@ Sie kÃļnnten sie auch als normale Funktion anstelle von `async def` definieren: /// note | Hinweis -Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../async.md#in-eile){.internal-link target=_blank}. +Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../async.md#in-a-hurry){.internal-link target=_blank}. /// -### Schritt 5: den Inhalt zurÃŧckgeben +### Schritt 5: den Inhalt zurÃŧckgeben { #step-5-return-the-content } {* ../../docs_src/first_steps/tutorial001.py hl[8] *} @@ -324,12 +312,12 @@ Sie kÃļnnen ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurÃŧ Sie kÃļnnen auch Pydantic-Modelle zurÃŧckgeben (dazu später mehr). -Es gibt viele andere Objekte und Modelle, die automatisch zu JSON konvertiert werden (einschließlich ORMs usw.). Versuchen Sie, Ihre Lieblingsobjekte zu verwenden. Es ist sehr wahrscheinlich, dass sie bereits unterstÃŧtzt werden. +Es gibt viele andere Objekte und Modelle, die automatisch zu JSON konvertiert werden (einschließlich ORMs, usw.). Versuchen Sie, Ihre Lieblingsobjekte zu verwenden. Es ist sehr wahrscheinlich, dass sie bereits unterstÃŧtzt werden. -## Zusammenfassung +## Zusammenfassung { #recap } * Importieren Sie `FastAPI`. * Erstellen Sie eine `app` Instanz. -* Schreiben Sie einen **Pfadoperation-Dekorator** (wie z. B. `@app.get("/")`). -* Schreiben Sie eine **Pfadoperation-Funktion** (wie z. B. oben `def root(): ...`). -* Starten Sie den Entwicklungsserver (z. B. `uvicorn main:app --reload`). +* Schreiben Sie einen **Pfadoperation-Dekorator** unter Verwendung von Dekoratoren wie `@app.get("/")`. +* Definieren Sie eine **Pfadoperation-Funktion**, zum Beispiel `def root(): ...`. +* Starten Sie den Entwicklungsserver mit dem Befehl `fastapi dev`. diff --git a/docs/de/docs/tutorial/handling-errors.md b/docs/de/docs/tutorial/handling-errors.md index 31bc6d328..51294f44f 100644 --- a/docs/de/docs/tutorial/handling-errors.md +++ b/docs/de/docs/tutorial/handling-errors.md @@ -1,49 +1,49 @@ -# Fehlerbehandlung +# Fehler behandeln { #handling-errors } -Es gibt viele Situationen, in denen Sie einem Client, der Ihre API benutzt, einen Fehler zurÃŧckgeben mÃŧssen. +Es gibt viele Situationen, in denen Sie einem Client, der Ihre API nutzt, einen Fehler mitteilen mÃŧssen. -Dieser Client kÃļnnte ein Browser mit einem Frontend, Code von jemand anderem, ein IoT-Gerät, usw., sein. +Dieser Client kÃļnnte ein Browser mit einem Frontend sein, ein Code von jemand anderem, ein IoT-Gerät usw. -Sie mÃŧssten beispielsweise einem Client sagen: +Sie kÃļnnten dem Client mitteilen mÃŧssen, dass: -* Dass er nicht die notwendigen Berechtigungen hat, eine Aktion auszufÃŧhren. -* Dass er zu einer Ressource keinen Zugriff hat. -* Dass die Ressource, auf die er zugreifen mÃļchte, nicht existiert. +* Der Client nicht genÃŧgend Berechtigungen fÃŧr diese Operation hat. +* Der Client keinen Zugriff auf diese Ressource hat. +* Die Ressource, auf die der Client versucht hat, zuzugreifen, nicht existiert. * usw. -In diesen Fällen geben Sie normalerweise einen **HTTP-Statuscode** im Bereich **400** (400 bis 499) zurÃŧck. +In diesen Fällen wÃŧrden Sie normalerweise einen **HTTP-Statuscode** im Bereich **400** (von 400 bis 499) zurÃŧckgeben. -Das ist vergleichbar mit den HTTP-Statuscodes im Bereich 200 (von 200 bis 299). Diese „200“er Statuscodes bedeuten, dass der Request in einem bestimmten Aspekt ein „Success“ („Erfolg“) war. +Dies ist vergleichbar mit den HTTP-Statuscodes im Bereich 200 (von 200 bis 299). Diese „200“-Statuscodes bedeuten, dass der Request in irgendeiner Weise erfolgreich war. -Die Statuscodes im 400er-Bereich bedeuten hingegen, dass es einen Fehler gab. +Die Statuscodes im Bereich 400 bedeuten hingegen, dass es einen Fehler seitens des Clients gab. -Erinnern Sie sich an all diese **404 Not Found** Fehler (und Witze)? +Erinnern Sie sich an all diese **„404 Not Found“** Fehler (und Witze)? -## `HTTPException` verwenden +## `HTTPException` verwenden { #use-httpexception } -Um HTTP-Responses mit Fehlern zum Client zurÃŧckzugeben, verwenden Sie `HTTPException`. +Um HTTP-Responses mit Fehlern an den Client zurÃŧckzugeben, verwenden Sie `HTTPException`. -### `HTTPException` importieren +### `HTTPException` importieren { #import-httpexception } {* ../../docs_src/handling_errors/tutorial001.py hl[1] *} -### Eine `HTTPException` in Ihrem Code auslÃļsen +### Eine `HTTPException` in Ihrem Code auslÃļsen { #raise-an-httpexception-in-your-code } -`HTTPException` ist eine normale Python-Exception mit einigen zusätzlichen Daten, die fÃŧr APIs relevant sind. +`HTTPException` ist eine normale Python-Exception mit zusätzlichen Daten, die fÃŧr APIs relevant sind. -Weil es eine Python-Exception ist, geben Sie sie nicht zurÃŧck, (`return`), sondern Sie lÃļsen sie aus (`raise`). +Weil es eine Python-Exception ist, geben Sie sie nicht zurÃŧck (`return`), sondern lÃļsen sie aus (`raise`). -Das bedeutet auch, wenn Sie in einer Hilfsfunktion sind, die Sie von ihrer *Pfadoperation-Funktion* aus aufrufen, und Sie lÃļsen eine `HTTPException` von innerhalb dieser Hilfsfunktion aus, dann wird der Rest der *Pfadoperation-Funktion* nicht ausgefÃŧhrt, sondern der Request wird sofort abgebrochen und der HTTP-Error der `HTTP-Exception` wird zum Client gesendet. +Das bedeutet auch, wenn Sie sich innerhalb einer Hilfsfunktion befinden, die Sie innerhalb Ihrer *Pfadoperation-Funktion* aufrufen, und Sie die `HTTPException` aus dieser Hilfsfunktion heraus auslÃļsen, wird der restliche Code in der *Pfadoperation-Funktion* nicht ausgefÃŧhrt. Der Request wird sofort abgebrochen und der HTTP-Error der `HTTPException` wird an den Client gesendet. -Der Vorteil, eine Exception auszulÃļsen (`raise`), statt sie zurÃŧckzugeben (`return`) wird im Abschnitt Ãŧber Abhängigkeiten und Sicherheit klarer werden. +Der Vorteil des AuslÃļsens einer Exception gegenÃŧber dem ZurÃŧckgeben eines Wertes wird im Abschnitt Ãŧber Abhängigkeiten und Sicherheit deutlicher werden. -Im folgenden Beispiel lÃļsen wir, wenn der Client eine ID anfragt, die nicht existiert, eine Exception mit dem Statuscode `404` aus. +In diesem Beispiel lÃļsen wir eine Exception mit einem Statuscode von `404` aus, wenn der Client einen Artikel mit einer nicht existierenden ID anfordert: {* ../../docs_src/handling_errors/tutorial001.py hl[11] *} -### Die resultierende Response +### Die resultierende Response { #the-resulting-response } -Wenn der Client `http://example.com/items/foo` anfragt (ein `item_id` `"foo"`), erhält dieser Client einen HTTP-Statuscode 200 und folgende JSON-Response: +Wenn der Client `http://example.com/items/foo` anfordert (ein `item_id` `"foo"`), erhält dieser Client einen HTTP-Statuscode 200 und diese JSON-Response: ```JSON { @@ -51,7 +51,7 @@ Wenn der Client `http://example.com/items/foo` anfragt (ein `item_id` `"foo"`), } ``` -Aber wenn der Client `http://example.com/items/bar` anfragt (ein nicht-existierendes `item_id` `"bar"`), erhält er einen HTTP-Statuscode 404 (der „Not Found“-Fehler), und eine JSON-Response wie folgt: +Aber wenn der Client `http://example.com/items/bar` anfordert (ein nicht-existierendes `item_id` `"bar"`), erhält er einen HTTP-Statuscode 404 (der „Not Found“-Error) und eine JSON-Response wie: ```JSON { @@ -61,41 +61,41 @@ Aber wenn der Client `http://example.com/items/bar` anfragt (ein nicht-existiere /// tip | Tipp -Wenn Sie eine `HTTPException` auslÃļsen, kÃļnnen Sie dem Parameter `detail` jeden Wert Ãŧbergeben, der nach JSON konvertiert werden kann, nicht nur `str`. +Wenn Sie eine `HTTPException` auslÃļsen, kÃļnnen Sie dem Parameter `detail` jeden Wert Ãŧbergeben, der in JSON konvertiert werden kann, nicht nur `str`. -Zum Beispiel ein `dict`, eine `list`, usw. +Sie kÃļnnten ein `dict`, eine `list`, usw. Ãŧbergeben. -Das wird automatisch von **FastAPI** gehandhabt und der Wert nach JSON konvertiert. +Diese werden von **FastAPI** automatisch gehandhabt und in JSON konvertiert. /// -## Benutzerdefinierte Header hinzufÃŧgen +## Benutzerdefinierte Header hinzufÃŧgen { #add-custom-headers } -Es gibt Situationen, da ist es nÃŧtzlich, dem HTTP-Error benutzerdefinierte Header hinzufÃŧgen zu kÃļnnen, etwa in einigen Sicherheitsszenarien. +Es gibt Situationen, in denen es nÃŧtzlich ist, dem HTTP-Error benutzerdefinierte Header hinzuzufÃŧgen. Zum Beispiel in einigen Sicherheitsszenarien. -Sie mÃŧssen das wahrscheinlich nicht direkt in ihrem Code verwenden. +Sie werden es wahrscheinlich nicht direkt in Ihrem Code verwenden mÃŧssen. -Aber falls es in einem fortgeschrittenen Szenario notwendig ist, kÃļnnen Sie benutzerdefinierte Header wie folgt hinzufÃŧgen: +Aber falls Sie es fÃŧr ein fortgeschrittenes Szenario benÃļtigen, kÃļnnen Sie benutzerdefinierte Header hinzufÃŧgen: {* ../../docs_src/handling_errors/tutorial002.py hl[14] *} -## Benutzerdefinierte Exceptionhandler definieren +## Benutzerdefinierte Exceptionhandler installieren { #install-custom-exception-handlers } -Sie kÃļnnen benutzerdefinierte Exceptionhandler hinzufÃŧgen, mithilfe derselben Werkzeuge fÃŧr Exceptions von Starlette. +Sie kÃļnnen benutzerdefinierte Exceptionhandler mit den gleichen Exception-Werkzeugen von Starlette hinzufÃŧgen. -Nehmen wir an, Sie haben eine benutzerdefinierte Exception `UnicornException`, die Sie (oder eine Bibliothek, die Sie verwenden) `raise`n kÃļnnten. +Angenommen, Sie haben eine benutzerdefinierte Exception `UnicornException`, die Sie (oder eine Bibliothek, die Sie verwenden) `raise`n kÃļnnten. Und Sie mÃļchten diese Exception global mit FastAPI handhaben. -Sie kÃļnnten einen benutzerdefinierten Exceptionhandler mittels `@app.exception_handler()` hinzufÃŧgen: +Sie kÃļnnten einen benutzerdefinierten Exceptionhandler mit `@app.exception_handler()` hinzufÃŧgen: {* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *} -Wenn Sie nun `/unicorns/yolo` anfragen, `raise`d die *Pfadoperation* eine `UnicornException`. +Hier, wenn Sie `/unicorns/yolo` anfordern, wird die *Pfadoperation* eine `UnicornException` `raise`n. Aber diese wird von `unicorn_exception_handler` gehandhabt. -Sie erhalten also einen sauberen Error mit einem Statuscode `418` und dem JSON-Inhalt: +Sie erhalten also einen sauberen Fehler mit einem HTTP-Statuscode von `418` und dem JSON-Inhalt: ```JSON {"message": "Oops! yolo did something. There goes a rainbow..."} @@ -103,33 +103,33 @@ Sie erhalten also einen sauberen Error mit einem Statuscode `418` und dem JSON-I /// note | Technische Details -Sie kÃļnnen auch `from starlette.requests import Request` und `from starlette.responses import JSONResponse` verwenden. +Sie kÃļnnten auch `from starlette.requests import Request` und `from starlette.responses import JSONResponse` verwenden. -**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. Das Gleiche gilt fÃŧr `Request`. +**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, nur als Annehmlichkeit fÃŧr Sie, den Entwickler. Aber die meisten verfÃŧgbaren Responses kommen direkt von Starlette. Dasselbe gilt fÃŧr `Request`. /// -## Die Default-Exceptionhandler Ãŧberschreiben +## Die Default-Exceptionhandler Ãŧberschreiben { #override-the-default-exception-handlers } **FastAPI** hat einige Default-Exceptionhandler. -Diese Handler kÃŧmmern sich darum, Default-JSON-Responses zurÃŧckzugeben, wenn Sie eine `HTTPException` `raise`n, und wenn der Request ungÃŧltige Daten enthält. +Diese Handler sind dafÃŧr verantwortlich, die Default-JSON-Responses zurÃŧckzugeben, wenn Sie eine `HTTPException` `raise`n und wenn der Request ungÃŧltige Daten enthält. -Sie kÃļnnen diese Exceptionhandler mit ihren eigenen Ãŧberschreiben. +Sie kÃļnnen diese Exceptionhandler mit Ihren eigenen Ãŧberschreiben. -### Requestvalidierung-Exceptions Ãŧberschreiben +### Überschreiben von Request-Validierungs-Exceptions { #override-request-validation-exceptions } Wenn ein Request ungÃŧltige Daten enthält, lÃļst **FastAPI** intern einen `RequestValidationError` aus. -Und bietet auch einen Default-Exceptionhandler dafÃŧr. +Und es enthält auch einen Default-Exceptionhandler fÃŧr diesen. -Um diesen zu Ãŧberschreiben, importieren Sie den `RequestValidationError` und verwenden Sie ihn in `@app.exception_handler(RequestValidationError)`, um Ihren Exceptionhandler zu dekorieren. +Um diesen zu Ãŧberschreiben, importieren Sie den `RequestValidationError` und verwenden Sie ihn mit `@app.exception_handler(RequestValidationError)`, um den Exceptionhandler zu dekorieren. -Der Exceptionhandler wird einen `Request` und die Exception entgegennehmen. +Der Exceptionhandler erhält einen `Request` und die Exception. {* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *} -Wenn Sie nun `/items/foo` besuchen, erhalten Sie statt des Default-JSON-Errors: +Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen JSON-Fehlers mit: ```JSON { @@ -146,7 +146,7 @@ Wenn Sie nun `/items/foo` besuchen, erhalten Sie statt des Default-JSON-Errors: } ``` -eine Textversion: +eine Textversion mit: ``` 1 validation error @@ -154,27 +154,27 @@ path -> item_id value is not a valid integer (type=type_error.integer) ``` -#### `RequestValidationError` vs. `ValidationError` +#### `RequestValidationError` vs. `ValidationError` { #requestvalidationerror-vs-validationerror } /// warning | Achtung -Das folgende sind technische Details, die Sie Ãŧberspringen kÃļnnen, wenn sie fÃŧr Sie nicht wichtig sind. +Dies sind technische Details, die Sie Ãŧberspringen kÃļnnen, wenn sie fÃŧr Sie jetzt nicht wichtig sind. /// -`RequestValidationError` ist eine Unterklasse von Pydantics `ValidationError`. +`RequestValidationError` ist eine Unterklasse von Pydantics `ValidationError`. -**FastAPI** verwendet diesen, sodass Sie, wenn Sie ein Pydantic-Modell fÃŧr `response_model` verwenden, und ihre Daten fehlerhaft sind, einen Fehler in ihrem Log sehen. +**FastAPI** verwendet diesen so, dass, wenn Sie ein Pydantic-Modell in `response_model` verwenden und Ihre Daten einen Fehler haben, Sie den Fehler in Ihrem Log sehen. -Aber der Client/Benutzer sieht ihn nicht. Stattdessen erhält der Client einen „Internal Server Error“ mit einem HTTP-Statuscode `500`. +Aber der Client/Benutzer wird ihn nicht sehen. Stattdessen erhält der Client einen „Internal Server Error“ mit einem HTTP-Statuscode `500`. -Das ist, wie es sein sollte, denn wenn Sie einen Pydantic-`ValidationError` in Ihrer *Response* oder irgendwo sonst in ihrem Code haben (es sei denn, im *Request* des Clients), ist das tatsächlich ein Bug in ihrem Code. +Es sollte so sein, denn wenn Sie einen Pydantic `ValidationError` in Ihrer *Response* oder irgendwo anders in Ihrem Code haben (nicht im *Request* des Clients), ist es tatsächlich ein Fehler in Ihrem Code. -Und während Sie den Fehler beheben, sollten ihre Clients/Benutzer keinen Zugriff auf interne Informationen Ãŧber den Fehler haben, da das eine SicherheitslÃŧcke aufdecken kÃļnnte. +Und während Sie den Fehler beheben, sollten Ihre Clients/Benutzer keinen Zugriff auf interne Informationen Ãŧber den Fehler haben, da das eine SicherheitslÃŧcke aufdecken kÃļnnte. -### den `HTTPException`-Handler Ãŧberschreiben +### Überschreiben des `HTTPException`-Fehlerhandlers { #override-the-httpexception-error-handler } -Genauso kÃļnnen Sie den `HTTPException`-Handler Ãŧberschreiben. +Auf die gleiche Weise kÃļnnen Sie den `HTTPException`-Handler Ãŧberschreiben. Zum Beispiel kÃļnnten Sie eine Klartext-Response statt JSON fÃŧr diese Fehler zurÃŧckgeben wollen: @@ -182,21 +182,21 @@ Zum Beispiel kÃļnnten Sie eine Klartext-Response statt JSON fÃŧr diese Fehler zu /// note | Technische Details -Sie kÃļnnen auch `from starlette.responses import PlainTextResponse` verwenden. +Sie kÃļnnten auch `from starlette.responses import PlainTextResponse` verwenden. -**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. +**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, nur als Annehmlichkeit fÃŧr Sie, den Entwickler. Aber die meisten verfÃŧgbaren Responses kommen direkt von Starlette. /// -### Den `RequestValidationError`-Body verwenden +### Verwenden des `RequestValidationError`-Bodys { #use-the-requestvalidationerror-body } Der `RequestValidationError` enthält den empfangenen `body` mit den ungÃŧltigen Daten. -Sie kÃļnnten diesen verwenden, während Sie Ihre Anwendung entwickeln, um den Body zu loggen und zu debuggen, ihn zum Benutzer zurÃŧckzugeben, usw. +Sie kÃļnnten diesen während der Entwicklung Ihrer Anwendung verwenden, um den Body zu loggen und zu debuggen, ihn an den Benutzer zurÃŧckzugeben usw. {* ../../docs_src/handling_errors/tutorial005.py hl[14] *} -Jetzt versuchen Sie, einen ungÃŧltigen Artikel zu senden: +Versuchen Sie nun, einen ungÃŧltigen Artikel zu senden: ```JSON { @@ -205,7 +205,7 @@ Jetzt versuchen Sie, einen ungÃŧltigen Artikel zu senden: } ``` -Sie erhalten eine Response, die Ihnen sagt, dass die Daten ungÃŧltig sind, und welche den empfangenen Body enthält. +Sie erhalten eine Response, die Ihnen sagt, dass die Daten ungÃŧltig sind und die den empfangenen Body enthält: ```JSON hl_lines="12-15" { @@ -226,30 +226,30 @@ Sie erhalten eine Response, die Ihnen sagt, dass die Daten ungÃŧltig sind, und w } ``` -#### FastAPIs `HTTPException` vs. Starlettes `HTTPException` +#### FastAPIs `HTTPException` vs. Starlettes `HTTPException` { #fastapis-httpexception-vs-starlettes-httpexception } **FastAPI** hat seine eigene `HTTPException`. -Und **FastAPI**s `HTTPException`-Fehlerklasse erbt von Starlettes `HTTPException`-Fehlerklasse. +Und die `HTTPException`-Fehlerklasse von **FastAPI** erbt von der `HTTPException`-Fehlerklasse von Starlette. -Der einzige Unterschied besteht darin, dass **FastAPIs** `HTTPException` alles fÃŧr das Feld `detail` akzeptiert, was nach JSON konvertiert werden kann, während Starlettes `HTTPException` nur Strings zulässt. +Der einzige Unterschied besteht darin, dass die `HTTPException` von **FastAPI** beliebige JSON-konvertierbare Daten fÃŧr das `detail`-Feld akzeptiert, während die `HTTPException` von Starlette nur Strings dafÃŧr akzeptiert. -Sie kÃļnnen also weiterhin **FastAPI**s `HTTPException` wie Ãŧblich in Ihrem Code auslÃļsen. +Sie kÃļnnen also weiterhin die `HTTPException` von **FastAPI** wie Ãŧblich in Ihrem Code auslÃļsen. -Aber wenn Sie einen Exceptionhandler registrieren, registrieren Sie ihn fÃŧr Starlettes `HTTPException`. +Aber wenn Sie einen Exceptionhandler registrieren, sollten Sie ihn fÃŧr die `HTTPException` von Starlette registrieren. -Auf diese Weise wird Ihr Handler, wenn irgendein Teil von Starlettes internem Code, oder eine Starlette-Erweiterung, oder -Plugin eine Starlette-`HTTPException` auslÃļst, in der Lage sein, diese zu fangen und zu handhaben. +Auf diese Weise, wenn irgendein Teil des internen Codes von Starlette, oder eine Starlette-Erweiterung oder ein Plug-in, eine Starlette `HTTPException` auslÃļst, wird Ihr Handler in der Lage sein, diese abzufangen und zu handhaben. -Damit wir in diesem Beispiel beide `HTTPException`s im selben Code haben kÃļnnen, benennen wir Starlettes Exception um zu `StarletteHTTPException`: +Um in diesem Beispiel beide `HTTPException`s im selben Code zu haben, wird die Exception von Starlette zu `StarletteHTTPException` umbenannt: ```Python from starlette.exceptions import HTTPException as StarletteHTTPException ``` -### **FastAPI**s Exceptionhandler wiederverwenden +### Die Exceptionhandler von **FastAPI** wiederverwenden { #reuse-fastapis-exception-handlers } -Wenn Sie die Exception zusammen mit denselben Default-Exceptionhandlern von **FastAPI** verwenden mÃļchten, kÃļnnen Sie die Default-Exceptionhandler von `fastapi.Exception_handlers` importieren und wiederverwenden: +Wenn Sie die Exception zusammen mit den gleichen Default-Exceptionhandlern von **FastAPI** verwenden mÃļchten, kÃļnnen Sie die Default-Exceptionhandler aus `fastapi.exception_handlers` importieren und wiederverwenden: {* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *} -In diesem Beispiel `print`en Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht, aber Sie sehen, worauf wir hinauswollen. Sie kÃļnnen mit der Exception etwas machen und dann einfach die Default-Exceptionhandler wiederverwenden. +In diesem Beispiel geben Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht aus, aber Sie verstehen das Prinzip. Sie kÃļnnen die Exception verwenden und dann einfach die Default-Exceptionhandler wiederverwenden. diff --git a/docs/de/docs/tutorial/header-param-models.md b/docs/de/docs/tutorial/header-param-models.md new file mode 100644 index 000000000..8c1bf61ae --- /dev/null +++ b/docs/de/docs/tutorial/header-param-models.md @@ -0,0 +1,72 @@ +# Header-Parameter-Modelle { #header-parameter-models } + +Wenn Sie eine Gruppe verwandter **Header-Parameter** haben, kÃļnnen Sie ein **Pydantic-Modell** erstellen, um diese zu deklarieren. + +Dadurch kÃļnnen Sie das **Modell an mehreren Stellen wiederverwenden** und auch Validierungen und Metadaten fÃŧr alle Parameter gleichzeitig deklarieren. 😎 + +/// note | Hinweis + +Dies wird seit FastAPI Version `0.115.0` unterstÃŧtzt. 🤓 + +/// + +## Header-Parameter mit einem Pydantic-Modell { #header-parameters-with-a-pydantic-model } + +Deklarieren Sie die erforderlichen **Header-Parameter** in einem **Pydantic-Modell** und dann den Parameter als `Header`: + +{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *} + +**FastAPI** wird die Daten fÃŧr **jedes Feld** aus den **Headern** des Request extrahieren und Ihnen das von Ihnen definierte Pydantic-Modell geben. + +## Die Dokumentation testen { #check-the-docs } + +Sie kÃļnnen die erforderlichen Header in der Dokumentationsoberfläche unter `/docs` sehen: + +
+ +
+ +## Zusätzliche Header verbieten { #forbid-extra-headers } + +In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) mÃļchten Sie mÃļglicherweise die **Header einschränken**, die Sie erhalten mÃļchten. + +Sie kÃļnnen Pydantics Modellkonfiguration verwenden, um `extra` Felder zu verbieten (`forbid`): + +{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *} + +Wenn ein Client versucht, einige **zusätzliche Header** zu senden, erhält er eine **Error-Response**. + +Zum Beispiel, wenn der Client versucht, einen `tool`-Header mit einem Wert von `plumbus` zu senden, erhält er eine **Error-Response**, die ihm mitteilt, dass der Header-Parameter `tool` nicht erlaubt ist: + +```json +{ + "detail": [ + { + "type": "extra_forbidden", + "loc": ["header", "tool"], + "msg": "Extra inputs are not permitted", + "input": "plumbus", + } + ] +} +``` + +## Automatische Umwandlung von Unterstrichen deaktivieren { #disable-convert-underscores } + +Ähnlich wie bei regulären Header-Parametern werden bei der Verwendung von Unterstrichen in den Parameternamen diese **automatisch in Bindestriche umgewandelt**. + +Wenn Sie beispielsweise einen Header-Parameter `save_data` im Code haben, wird der erwartete HTTP-Header `save-data` sein, und er wird auch so in der Dokumentation angezeigt. + +Falls Sie aus irgendeinem Grund diese automatische Umwandlung deaktivieren mÃŧssen, kÃļnnen Sie dies auch fÃŧr Pydantic-Modelle fÃŧr Header-Parameter tun. + +{* ../../docs_src/header_param_models/tutorial003_an_py310.py hl[19] *} + +/// warning | Achtung + +Bevor Sie `convert_underscores` auf `False` setzen, bedenken Sie, dass einige HTTP-Proxies und -Server die Verwendung von Headern mit Unterstrichen nicht zulassen. + +/// + +## Zusammenfassung { #summary } + +Sie kÃļnnen **Pydantic-Modelle** verwenden, um **Header** in **FastAPI** zu deklarieren. 😎 diff --git a/docs/de/docs/tutorial/header-params.md b/docs/de/docs/tutorial/header-params.md index 8283cc929..5c0bb3f87 100644 --- a/docs/de/docs/tutorial/header-params.md +++ b/docs/de/docs/tutorial/header-params.md @@ -1,50 +1,50 @@ -# Header-Parameter +# Header-Parameter { #header-parameters } -So wie `Query`-, `Path`-, und `Cookie`-Parameter kÃļnnen Sie auch Header-Parameter definieren. +Sie kÃļnnen Header-Parameter genauso definieren, wie Sie `Query`-, `Path`- und `Cookie`-Parameter definieren. -## `Header` importieren +## `Header` importieren { #import-header } Importieren Sie zuerst `Header`: {* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *} -## `Header`-Parameter deklarieren +## `Header`-Parameter deklarieren { #declare-header-parameters } -Dann deklarieren Sie Ihre Header-Parameter, auf die gleiche Weise, wie Sie auch `Path`-, `Query`-, und `Cookie`-Parameter deklarieren. +Deklarieren Sie dann die Header-Parameter mit derselben Struktur wie bei `Path`, `Query` und `Cookie`. -Der erste Wert ist der Typ. Sie kÃļnnen `Header` die gehabten Extra Validierungs- und Beschreibungsparameter hinzufÃŧgen. Danach kÃļnnen Sie einen Defaultwert vergeben: +Sie kÃļnnen den Defaultwert sowie alle zusätzlichen Validierungs- oder Annotationsparameter definieren: {* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *} /// note | Technische Details -`Header` ist eine Schwesterklasse von `Path`, `Query` und `Cookie`. Sie erbt von derselben gemeinsamen `Param`-Elternklasse. +`Header` ist eine „Schwester“-Klasse von `Path`, `Query` und `Cookie`. Sie erbt ebenfalls von der gemeinsamen `Param`-Klasse. -Aber erinnern Sie sich, dass, wenn Sie `Query`, `Path`, `Header` und andere von `fastapi` importieren, diese tatsächlich Funktionen sind, welche spezielle Klassen zurÃŧckgeben. +Aber denken Sie daran, dass bei der Nutzung von `Query`, `Path`, `Header` und anderen Importen aus `fastapi`, diese tatsächlich Funktionen sind, die spezielle Klassen zurÃŧckgeben. /// -/// info +/// info | Info -Um Header zu deklarieren, mÃŧssen Sie `Header` verwenden, da diese Parameter sonst als Query-Parameter interpretiert werden wÃŧrden. +Um Header zu deklarieren, mÃŧssen Sie `Header` verwenden, da die Parameter sonst als Query-Parameter interpretiert werden wÃŧrden. /// -## Automatische Konvertierung +## Automatische Konvertierung { #automatic-conversion } -`Header` hat weitere Funktionalität, zusätzlich zu der, die `Path`, `Query` und `Cookie` bereitstellen. +`Header` bietet etwas zusätzliche Funktionalität im Vergleich zu `Path`, `Query` und `Cookie`. -Die meisten Standard-Header benutzen als Trennzeichen einen Bindestrich, auch bekannt als das „Minus-Symbol“ (`-`). +Die meisten Standard-Header sind durch ein „Bindestrich“-Zeichen getrennt, auch bekannt als „Minus-Symbol“ (`-`). -Aber eine Variable wie `user-agent` ist in Python nicht gÃŧltig. +Aber eine Variable wie `user-agent` ist in Python ungÃŧltig. -Darum wird `Header` standardmäßig in Parameternamen den Unterstrich (`_`) zu einem Bindestrich (`-`) konvertieren. +Daher wird `Header` standardmäßig die Zeichen des Parameter-Namens von Unterstrich (`_`) zu Bindestrich (`-`) konvertieren, um die Header zu extrahieren und zu dokumentieren. -HTTP-Header sind außerdem unabhängig von Groß-/Kleinschreibung, darum kÃļnnen Sie sie mittels der Standard-Python-Schreibweise deklarieren (auch bekannt als "snake_case"). +Außerdem ist Groß-/Klein­schrei­bung in HTTP-Headern nicht relevant, daher kÃļnnen Sie sie im Standard-Python-Stil (auch bekannt als „snake_case“) deklarieren. -Sie kÃļnnen also `user_agent` schreiben, wie Sie es normalerweise in Python-Code machen wÃŧrden, statt etwa die ersten Buchstaben groß zu schreiben, wie in `User_Agent`. +Sie kÃļnnen also `user_agent` verwenden, wie Sie es normalerweise im Python-Code tun wÃŧrden, anstatt die Anfangsbuchstaben wie bei `User_Agent` großzuschreiben oder Ähnliches. -Wenn Sie aus irgendeinem Grund das automatische Konvertieren von Unterstrichen zu Bindestrichen abschalten mÃļchten, setzen Sie den Parameter `convert_underscores` auf `False`. +Wenn Sie aus irgendeinem Grund die automatische Konvertierung von Unterstrichen zu Bindestrichen deaktivieren mÃŧssen, setzen Sie den Parameter `convert_underscores` von `Header` auf `False`: {* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *} @@ -54,26 +54,26 @@ Bevor Sie `convert_underscores` auf `False` setzen, bedenken Sie, dass manche HT /// -## Doppelte Header +## Doppelte Header { #duplicate-headers } -Es ist mÃļglich, doppelte Header zu empfangen. Also den gleichen Header mit unterschiedlichen Werten. +Es ist mÃļglich, doppelte Header zu empfangen. Damit ist gemeint, denselben Header mit mehreren Werten. -Sie kÃļnnen solche Fälle deklarieren, indem Sie in der Typdeklaration eine Liste verwenden. +Sie kÃļnnen solche Fälle definieren, indem Sie in der Typdeklaration eine Liste verwenden. -Sie erhalten dann alle Werte von diesem doppelten Header als Python-`list`e. +Sie erhalten dann alle Werte von diesem doppelten Header als Python-`list`. -Um zum Beispiel einen Header `X-Token` zu deklarieren, der mehrmals vorkommen kann, schreiben Sie: +Um beispielsweise einen `X-Token`-Header zu deklarieren, der mehrmals vorkommen kann, kÃļnnen Sie schreiben: {* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *} -Wenn Sie mit einer *Pfadoperation* kommunizieren, die zwei HTTP-Header sendet, wie: +Wenn Sie mit dieser *Pfadoperation* kommunizieren und zwei HTTP-Header senden, wie: ``` X-Token: foo X-Token: bar ``` -Dann wäre die Response: +Dann wäre die Response: ```JSON { @@ -84,8 +84,8 @@ Dann wäre die Response: } ``` -## Zusammenfassung +## Zusammenfassung { #recap } -Deklarieren Sie Header mittels `Header`, auf die gleiche Weise wie bei `Query`, `Path` und `Cookie`. +Deklarieren Sie Header mit `Header`, wobei Sie dasselbe gängige Muster wie bei `Query`, `Path` und `Cookie` verwenden. -Machen Sie sich keine Sorgen um Unterstriche in ihren Variablen, **FastAPI** wird sich darum kÃŧmmern, diese zu konvertieren. +Und machen Sie sich keine Sorgen um Unterstriche in Ihren Variablen, **FastAPI** wird sich darum kÃŧmmern, sie zu konvertieren. diff --git a/docs/de/docs/tutorial/index.md b/docs/de/docs/tutorial/index.md index 3cbfe37f4..70a6b6a08 100644 --- a/docs/de/docs/tutorial/index.md +++ b/docs/de/docs/tutorial/index.md @@ -1,83 +1,95 @@ -# Tutorial – Benutzerhandbuch +# Tutorial – Benutzerhandbuch { #tutorial-user-guide } -Dieses Tutorial zeigt Ihnen Schritt fÃŧr Schritt, wie Sie **FastAPI** und die meisten seiner Funktionen verwenden kÃļnnen. +Dieses Tutorial zeigt Ihnen Schritt fÃŧr Schritt, wie Sie **FastAPI** mit den meisten seiner Funktionen verwenden kÃļnnen. -Jeder Abschnitt baut schrittweise auf den vorhergehenden auf. Diese Abschnitte sind aber nach einzelnen Themen gegliedert, sodass Sie direkt zu einem bestimmten Thema Ãŧbergehen kÃļnnen, um Ihre speziellen API-Anforderungen zu lÃļsen. +Jeder Abschnitt baut schrittweise auf den vorhergehenden auf, ist jedoch in einzelne Themen gegliedert, sodass Sie direkt zu einem bestimmten Thema Ãŧbergehen kÃļnnen, um Ihre spezifischen API-Anforderungen zu lÃļsen. -Außerdem dienen diese als zukÃŧnftige Referenz. +Es ist auch so gestaltet, dass es als zukÃŧnftige Referenz dient, sodass Sie jederzeit zurÃŧckkommen und genau das sehen, was Sie benÃļtigen. -Dadurch kÃļnnen Sie jederzeit zurÃŧckkommen und sehen genau das, was Sie benÃļtigen. +## Den Code ausfÃŧhren { #run-the-code } -## Den Code ausfÃŧhren +Alle CodeblÃļcke kÃļnnen kopiert und direkt verwendet werden (es sind tatsächlich getestete Python-Dateien). -Alle CodeblÃļcke kÃļnnen kopiert und direkt verwendet werden (da es sich um getestete Python-Dateien handelt). - -Um eines der Beispiele auszufÃŧhren, kopieren Sie den Code in eine Datei `main.py`, und starten Sie `uvicorn` mit: +Um eines der Beispiele auszufÃŧhren, kopieren Sie den Code in eine Datei `main.py` und starten Sie `fastapi dev` mit:
```console -$ uvicorn main:app --reload +$ fastapi dev main.py -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. + FastAPI Starting development server 🚀 + + Searching for package file structure from directories + with __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with + the following code: + + from main import app + + app Using import string: main:app + + server Server started at http://127.0.0.1:8000 + server Documentation at http://127.0.0.1:8000/docs + + tip Running in development mode, for production use: + fastapi run + + Logs: + + INFO Will watch for changes in these directories: + ['/home/user/code/awesomeapp'] + INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C + to quit) + INFO Started reloader process [383138] using WatchFiles + INFO Started server process [383153] + INFO Waiting for application startup. + INFO Application startup complete. ```
-Es wird **ausdrÃŧcklich empfohlen**, dass Sie den Code schreiben oder kopieren, ihn bearbeiten und lokal ausfÃŧhren. +Es wird **dringend empfohlen**, den Code zu schreiben oder zu kopieren, ihn zu bearbeiten und lokal auszufÃŧhren. Die Verwendung in Ihrem eigenen Editor zeigt Ihnen die Vorteile von FastAPI am besten, wenn Sie sehen, wie wenig Code Sie schreiben mÃŧssen, all die TypprÃŧfungen, die automatische Vervollständigung usw. --- -## FastAPI installieren +## FastAPI installieren { #install-fastapi } -Der erste Schritt besteht aus der Installation von FastAPI. +Der erste Schritt besteht darin, FastAPI zu installieren. -FÃŧr dieses Tutorial empfiehlt es sich, FastAPI mit allen optionalen Abhängigkeiten und Funktionen zu installieren: +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und dann **FastAPI installieren**:
```console -$ pip install "fastapi[all]" +$ pip install "fastapi[standard]" ---> 100% ```
-... das beinhaltet auch `uvicorn`, welchen Sie als Server verwenden kÃļnnen, der ihren Code ausfÃŧhrt. - /// note | Hinweis -Sie kÃļnnen die einzelnen Teile auch separat installieren. +Wenn Sie mit `pip install "fastapi[standard]"` installieren, werden einige optionale Standard-Abhängigkeiten mit installiert, einschließlich `fastapi-cloud-cli`, welches Ihnen das Deployment in der FastAPI Cloud ermÃļglicht. -Das folgende wÃŧrden Sie wahrscheinlich tun, wenn Sie Ihre Anwendung in der Produktion einsetzen: +Wenn Sie diese optionalen Abhängigkeiten nicht haben mÃļchten, kÃļnnen Sie stattdessen `pip install fastapi` installieren. -``` -pip install fastapi -``` - -Installieren Sie auch `uvicorn` als Server: - -``` -pip install "uvicorn[standard]" -``` - -Das gleiche gilt fÃŧr jede der optionalen Abhängigkeiten, die Sie verwenden mÃļchten. +Wenn Sie die Standard-Abhängigkeiten, aber ohne das `fastapi-cloud-cli` installieren mÃļchten, kÃļnnen Sie mit `pip install "fastapi[standard-no-fastapi-cloud-cli]"` installieren. /// -## Handbuch fÃŧr fortgeschrittene Benutzer +## Handbuch fÃŧr fortgeschrittene Benutzer { #advanced-user-guide } -Es gibt auch ein **Handbuch fÃŧr fortgeschrittene Benutzer**, welches Sie später nach diesem **Tutorial – Benutzerhandbuch** lesen kÃļnnen. +Es gibt auch ein **Handbuch fÃŧr fortgeschrittene Benutzer**, das Sie nach diesem **Tutorial – Benutzerhandbuch** lesen kÃļnnen. -Das **Handbuch fÃŧr fortgeschrittene Benutzer** baut auf diesem Tutorial auf, verwendet dieselben Konzepte und bringt Ihnen einige zusätzliche Funktionen bei. +Das **Handbuch fÃŧr fortgeschrittene Benutzer** baut hierauf auf, verwendet dieselben Konzepte und bringt Ihnen einige zusätzliche Funktionen bei. -Allerdings sollten Sie zuerst das **Tutorial – Benutzerhandbuch** lesen (was Sie hier gerade tun). +Sie sollten jedoch zuerst das **Tutorial – Benutzerhandbuch** lesen (was Sie gerade tun). -Die Dokumentation ist so konzipiert, dass Sie mit dem **Tutorial – Benutzerhandbuch** eine vollständige Anwendung erstellen kÃļnnen und diese dann je nach Bedarf mit einigen der zusätzlichen Ideen aus dem **Handbuch fÃŧr fortgeschrittene Benutzer** vervollständigen kÃļnnen. +Es ist so konzipiert, dass Sie mit dem **Tutorial – Benutzerhandbuch** eine vollständige Anwendung erstellen kÃļnnen und diese dann je nach Bedarf mit einigen der zusätzlichen Ideen aus dem **Handbuch fÃŧr fortgeschrittene Benutzer** erweitern kÃļnnen. diff --git a/docs/de/docs/tutorial/metadata.md b/docs/de/docs/tutorial/metadata.md index 4809530be..44d02e6d8 100644 --- a/docs/de/docs/tutorial/metadata.md +++ b/docs/de/docs/tutorial/metadata.md @@ -1,10 +1,10 @@ -# Metadaten und URLs der Dokumentationen +# Metadaten und Dokumentations-URLs { #metadata-and-docs-urls } -Sie kÃļnnen mehrere Metadaten-Einstellungen fÃŧr Ihre **FastAPI**-Anwendung konfigurieren. +Sie kÃļnnen mehrere Metadaten-Konfigurationen in Ihrer **FastAPI**-Anwendung anpassen. -## Metadaten fÃŧr die API +## Metadaten fÃŧr die API { #metadata-for-api } -Sie kÃļnnen die folgenden Felder festlegen, welche in der OpenAPI-Spezifikation und den Benutzeroberflächen der automatischen API-Dokumentation verwendet werden: +Sie kÃļnnen die folgenden Felder festlegen, die in der OpenAPI-Spezifikation und in den Benutzeroberflächen der automatischen API-Dokumentation verwendet werden: | Parameter | Typ | Beschreibung | |------------|------|-------------| @@ -13,16 +13,16 @@ Sie kÃļnnen die folgenden Felder festlegen, welche in der OpenAPI-Spezifikation | `description` | `str` | Eine kurze Beschreibung der API. Kann Markdown verwenden. | | `version` | `string` | Die Version der API. Das ist die Version Ihrer eigenen Anwendung, nicht die von OpenAPI. Zum Beispiel `2.5.0`. | | `terms_of_service` | `str` | Eine URL zu den Nutzungsbedingungen fÃŧr die API. Falls angegeben, muss es sich um eine URL handeln. | -| `contact` | `dict` | Die Kontaktinformationen fÃŧr die verfÃŧgbar gemachte API. Kann mehrere Felder enthalten.
contact-Felder
ParameterTypBeschreibung
namestrDer identifizierende Name der Kontaktperson/Organisation.
urlstrDie URL, die auf die Kontaktinformationen verweist. MUSS im Format einer URL vorliegen.
emailstrDie E-Mail-Adresse der Kontaktperson/Organisation. MUSS im Format einer E-Mail-Adresse vorliegen.
| -| `license_info` | `dict` | Die Lizenzinformationen fÃŧr die verfÃŧgbar gemachte API. Kann mehrere Felder enthalten.
license_info-Felder
ParameterTypBeschreibung
namestrERFORDERLICH (wenn eine license_info festgelegt ist). Der fÃŧr die API verwendete Lizenzname.
identifierstrEin SPDX-Lizenzausdruck fÃŧr die API. Das Feld identifier und das Feld url schließen sich gegenseitig aus. VerfÃŧgbar seit OpenAPI 3.1.0, FastAPI 0.99.0.
urlstrEine URL zur Lizenz, die fÃŧr die API verwendet wird. MUSS im Format einer URL vorliegen.
| +| `contact` | `dict` | Die Kontaktinformationen fÃŧr die freigegebene API. Kann mehrere Felder enthalten.
contact-Felder
ParameterTypBeschreibung
namestrDer identifizierende Name der Kontaktperson/Organisation.
urlstrDie URL, die auf die Kontaktinformationen verweist. MUSS im Format einer URL vorliegen.
emailstrDie E-Mail-Adresse der Kontaktperson/Organisation. MUSS im Format einer E-Mail-Adresse vorliegen.
| +| `license_info` | `dict` | Die Lizenzinformationen fÃŧr die freigegebene API. Kann mehrere Felder enthalten.
license_info-Felder
ParameterTypBeschreibung
namestrERFORDERLICH (wenn eine license_info festgelegt ist). Der fÃŧr die API verwendete Lizenzname.
identifierstrEin SPDX-Lizenzausdruck fÃŧr die API. Das Feld identifier und das Feld url schließen sich gegenseitig aus. VerfÃŧgbar seit OpenAPI 3.1.0, FastAPI 0.99.0.
urlstrEine URL zur Lizenz, die fÃŧr die API verwendet wird. MUSS im Format einer URL vorliegen.
| Sie kÃļnnen diese wie folgt setzen: -{* ../../docs_src/metadata/tutorial001.py hl[3:16,19:32] *} +{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *} /// tip | Tipp -Sie kÃļnnen Markdown in das Feld `description` schreiben und es wird in der Ausgabe gerendert. +Sie kÃļnnen Markdown im Feld `description` verwenden, und es wird in der Ausgabe gerendert. /// @@ -30,7 +30,7 @@ Mit dieser Konfiguration wÃŧrde die automatische API-Dokumentation wie folgt aus -## Lizenz-ID +## Lizenzkennung { #license-identifier } Seit OpenAPI 3.1.0 und FastAPI 0.99.0 kÃļnnen Sie die `license_info` auch mit einem `identifier` anstelle einer `url` festlegen. @@ -38,29 +38,29 @@ Zum Beispiel: {* ../../docs_src/metadata/tutorial001_1.py hl[31] *} -## Metadaten fÃŧr Tags +## Metadaten fÃŧr Tags { #metadata-for-tags } -Sie kÃļnnen mit dem Parameter `openapi_tags` auch zusätzliche Metadaten fÃŧr die verschiedenen Tags hinzufÃŧgen, die zum Gruppieren Ihrer Pfadoperationen verwendet werden. +Sie kÃļnnen auch zusätzliche Metadaten fÃŧr die verschiedenen Tags hinzufÃŧgen, die zum Gruppieren Ihrer Pfadoperationen verwendet werden, mit dem Parameter `openapi_tags`. -Es wird eine Liste benÃļtigt, die fÃŧr jedes Tag ein Dict enthält. +Er nimmt eine Liste entgegen, die fÃŧr jeden Tag ein Dictionary enthält. -Jedes Dict kann Folgendes enthalten: +Jedes Dictionary kann Folgendes enthalten: * `name` (**erforderlich**): ein `str` mit demselben Tag-Namen, den Sie im Parameter `tags` in Ihren *Pfadoperationen* und `APIRouter`n verwenden. * `description`: ein `str` mit einer kurzen Beschreibung fÃŧr das Tag. Sie kann Markdown enthalten und wird in der Benutzeroberfläche der Dokumentation angezeigt. * `externalDocs`: ein `dict`, das externe Dokumentation beschreibt mit: - * `description`: ein `str` mit einer kurzen Beschreibung fÃŧr die externe Dokumentation. - * `url` (**erforderlich**): ein `str` mit der URL fÃŧr die externe Dokumentation. + * `description`: ein `str` mit einer kurzen Beschreibung fÃŧr die externe Dokumentation. + * `url` (**erforderlich**): ein `str` mit der URL fÃŧr die externe Dokumentation. -### Metadaten fÃŧr Tags erstellen +### Metadaten fÃŧr Tags erstellen { #create-metadata-for-tags } -Versuchen wir das an einem Beispiel mit Tags fÃŧr `users` und `items`. +Versuchen wir es mit einem Beispiel mit Tags fÃŧr `users` und `items`. -Erstellen Sie Metadaten fÃŧr Ihre Tags und Ãŧbergeben Sie sie an den Parameter `openapi_tags`: +Erstellen Sie Metadaten fÃŧr Ihre Tags und Ãŧbergeben Sie diese an den Parameter `openapi_tags`: {* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *} -Beachten Sie, dass Sie Markdown in den Beschreibungen verwenden kÃļnnen. Beispielsweise wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt. +Beachten Sie, dass Sie Markdown innerhalb der Beschreibungen verwenden kÃļnnen. Zum Beispiel wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt. /// tip | Tipp @@ -68,31 +68,31 @@ Sie mÃŧssen nicht fÃŧr alle von Ihnen verwendeten Tags Metadaten hinzufÃŧgen. /// -### Ihre Tags verwenden +### Ihre Tags verwenden { #use-your-tags } Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n), um diese verschiedenen Tags zuzuweisen: {* ../../docs_src/metadata/tutorial004.py hl[21,26] *} -/// info +/// info | Info Lesen Sie mehr zu Tags unter [Pfadoperation-Konfiguration](path-operation-configuration.md#tags){.internal-link target=_blank}. /// -### Die Dokumentation anschauen +### Die Dokumentation testen { #check-the-docs } Wenn Sie nun die Dokumentation ansehen, werden dort alle zusätzlichen Metadaten angezeigt: -### Reihenfolge der Tags +### Reihenfolge der Tags { #order-of-tags } -Die Reihenfolge der Tag-Metadaten-Dicts definiert auch die Reihenfolge, in der diese in der Benutzeroberfläche der Dokumentation angezeigt werden. +Die Reihenfolge der Tag-Metadaten-Dictionarys definiert auch die Reihenfolge, in der diese in der Benutzeroberfläche der Dokumentation angezeigt werden. -Auch wenn beispielsweise `users` im Alphabet nach `items` kommt, wird es vor diesen angezeigt, da wir seine Metadaten als erstes Dict der Liste hinzugefÃŧgt haben. +Auch wenn beispielsweise `users` im Alphabet nach `items` kommt, wird es vor diesen angezeigt, da wir deren Metadaten als erstes Dictionary der Liste hinzugefÃŧgt haben. -## OpenAPI-URL +## OpenAPI-URL { #openapi-url } Standardmäßig wird das OpenAPI-Schema unter `/openapi.json` bereitgestellt. @@ -104,16 +104,16 @@ Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestel Wenn Sie das OpenAPI-Schema vollständig deaktivieren mÃļchten, kÃļnnen Sie `openapi_url=None` festlegen, wodurch auch die Dokumentationsbenutzeroberflächen deaktiviert werden, die es verwenden. -## URLs der Dokumentationen +## Dokumentations-URLs { #docs-urls } Sie kÃļnnen die beiden enthaltenen Dokumentationsbenutzeroberflächen konfigurieren: * **Swagger UI**: bereitgestellt unter `/docs`. - * Sie kÃļnnen deren URL mit dem Parameter `docs_url` festlegen. - * Sie kÃļnnen sie deaktivieren, indem Sie `docs_url=None` festlegen. + * Sie kÃļnnen deren URL mit dem Parameter `docs_url` festlegen. + * Sie kÃļnnen sie deaktivieren, indem Sie `docs_url=None` festlegen. * **ReDoc**: bereitgestellt unter `/redoc`. - * Sie kÃļnnen deren URL mit dem Parameter `redoc_url` festlegen. - * Sie kÃļnnen sie deaktivieren, indem Sie `redoc_url=None` festlegen. + * Sie kÃļnnen deren URL mit dem Parameter `redoc_url` festlegen. + * Sie kÃļnnen sie deaktivieren, indem Sie `redoc_url=None` festlegen. Um beispielsweise Swagger UI so einzustellen, dass sie unter `/documentation` bereitgestellt wird, und ReDoc zu deaktivieren: diff --git a/docs/de/docs/tutorial/middleware.md b/docs/de/docs/tutorial/middleware.md index d3699be1b..a1e2ba9df 100644 --- a/docs/de/docs/tutorial/middleware.md +++ b/docs/de/docs/tutorial/middleware.md @@ -1,8 +1,8 @@ -# Middleware +# Middleware { #middleware } Sie kÃļnnen Middleware zu **FastAPI**-Anwendungen hinzufÃŧgen. -Eine „Middleware“ ist eine Funktion, die mit jedem **Request** arbeitet, bevor er von einer bestimmten *Pfadoperation* verarbeitet wird. Und auch mit jeder **Response**, bevor sie zurÃŧckgegeben wird. +Eine „Middleware“ ist eine Funktion, die mit jedem **Request** arbeitet, bevor er von einer bestimmten *Pfadoperation* verarbeitet wird. Und auch mit jeder **Response**, bevor sie zurÃŧckgegeben wird. * Sie nimmt jeden **Request** entgegen, der an Ihre Anwendung gesendet wird. * Sie kann dann etwas mit diesem **Request** tun oder beliebigen Code ausfÃŧhren. @@ -15,11 +15,11 @@ Eine „Middleware“ ist eine Funktion, die mit jedem **Request** arbeitet, bev Wenn Sie Abhängigkeiten mit `yield` haben, wird der Exit-Code *nach* der Middleware ausgefÃŧhrt. -Wenn es Hintergrundaufgaben gab (später dokumentiert), werden sie *nach* allen Middlewares ausgefÃŧhrt. +Wenn es Hintergrundtasks gab (dies wird später im [Hintergrundtasks](background-tasks.md){.internal-link target=_blank}-Abschnitt behandelt), werden sie *nach* allen Middlewares ausgefÃŧhrt. /// -## Erstellung einer Middleware +## Eine Middleware erstellen { #create-a-middleware } Um eine Middleware zu erstellen, verwenden Sie den Dekorator `@app.middleware("http")` Ãŧber einer Funktion. @@ -35,9 +35,9 @@ Die Middleware-Funktion erhält: /// tip | Tipp -Beachten Sie, dass benutzerdefinierte proprietäre Header hinzugefÃŧgt werden kÃļnnen. Verwenden Sie dafÃŧr das Präfix 'X-'. +Beachten Sie, dass benutzerdefinierte proprietäre Header hinzugefÃŧgt werden kÃļnnen unter Verwendung des `X-`-Präfixes. -Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen soll, mÃŧssen Sie sie zu Ihrer CORS-Konfigurationen ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) hinzufÃŧgen, indem Sie den Parameter `expose_headers` verwenden, der in der Starlette-CORS-Dokumentation dokumentiert ist. +Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen soll, mÃŧssen Sie sie zu Ihrer CORS-Konfiguration ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) hinzufÃŧgen, indem Sie den Parameter `expose_headers` verwenden, der in der Starlettes CORS-Dokumentation dokumentiert ist. /// @@ -49,7 +49,7 @@ Sie kÃļnnten auch `from starlette.requests import Request` verwenden. /// -### Vor und nach der `response` +### Vor und nach der `response` { #before-and-after-the-response } Sie kÃļnnen Code hinzufÃŧgen, der mit dem `request` ausgefÃŧhrt wird, bevor dieser von einer beliebigen *Pfadoperation* empfangen wird. @@ -59,8 +59,37 @@ Sie kÃļnnten beispielsweise einen benutzerdefinierten Header `X-Process-Time` hi {* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *} -## Andere Middlewares +/// tip | Tipp -Sie kÃļnnen später mehr Ãŧber andere Middlewares in [Handbuch fÃŧr fortgeschrittene Benutzer: Fortgeschrittene Middleware](../advanced/middleware.md){.internal-link target=_blank} lesen. +Hier verwenden wir `time.perf_counter()` anstelle von `time.time()`, da es fÃŧr diese Anwendungsfälle präziser sein kann. 🤓 -In der nächsten Sektion erfahren Sie, wie Sie CORS mit einer Middleware behandeln kÃļnnen. +/// + +## AusfÃŧhrungsreihenfolge bei mehreren Middlewares { #multiple-middleware-execution-order } + +Wenn Sie mehrere Middlewares hinzufÃŧgen, entweder mit dem `@app.middleware()` Dekorator oder der Methode `app.add_middleware()`, umschließt jede neue Middleware die Anwendung und bildet einen Stapel. Die zuletzt hinzugefÃŧgte Middleware ist die *äußerste*, und die erste ist die *innerste*. + +Auf dem Requestpfad läuft die *äußerste* Middleware zuerst. + +Auf dem Responsepfad läuft sie zuletzt. + +Zum Beispiel: + +```Python +app.add_middleware(MiddlewareA) +app.add_middleware(MiddlewareB) +``` + +Dies fÃŧhrt zu folgender AusfÃŧhrungsreihenfolge: + +* **Request**: MiddlewareB → MiddlewareA → Route + +* **Response**: Route → MiddlewareA → MiddlewareB + +Dieses Stapelverhalten stellt sicher, dass Middlewares in einer vorhersehbaren und kontrollierbaren Reihenfolge ausgefÃŧhrt werden. + +## Andere Middlewares { #other-middlewares } + +Sie kÃļnnen später mehr Ãŧber andere Middlewares im [Handbuch fÃŧr fortgeschrittene Benutzer: Fortgeschrittene Middleware](../advanced/middleware.md){.internal-link target=_blank} lesen. + +In der nächsten Sektion erfahren Sie, wie Sie CORS mit einer Middleware behandeln kÃļnnen. diff --git a/docs/de/docs/tutorial/path-operation-configuration.md b/docs/de/docs/tutorial/path-operation-configuration.md index 7473e515b..c483f4e40 100644 --- a/docs/de/docs/tutorial/path-operation-configuration.md +++ b/docs/de/docs/tutorial/path-operation-configuration.md @@ -1,6 +1,6 @@ -# Pfadoperation-Konfiguration +# Pfadoperation-Konfiguration { #path-operation-configuration } -Es gibt mehrere Konfigurations-Parameter, die Sie Ihrem *Pfadoperation-Dekorator* Ãŧbergeben kÃļnnen. +Es gibt mehrere Parameter, die Sie Ihrem *Pfadoperation-Dekorator* Ãŧbergeben kÃļnnen, um ihn zu konfigurieren. /// warning | Achtung @@ -8,13 +8,13 @@ Beachten Sie, dass diese Parameter direkt dem *Pfadoperation-Dekorator* Ãŧbergeb /// -## Response-Statuscode +## Response-Statuscode { #response-status-code } -Sie kÃļnnen den (HTTP-)`status_code` definieren, den die Response Ihrer *Pfadoperation* verwenden soll. +Sie kÃļnnen den (HTTP-)`status_code` definieren, der in der Response Ihrer *Pfadoperation* verwendet werden soll. Sie kÃļnnen direkt den `int`-Code Ãŧbergeben, etwa `404`. -Aber falls Sie sich nicht mehr erinnern, wofÃŧr jede Nummer steht, kÃļnnen Sie die AbkÃŧrzungs-Konstanten in `status` verwenden: +Aber falls Sie sich nicht mehr erinnern, wofÃŧr jeder Nummerncode steht, kÃļnnen Sie die AbkÃŧrzungs-Konstanten in `status` verwenden: {* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *} @@ -28,9 +28,9 @@ Sie kÃļnnen auch `from starlette import status` verwenden. /// -## Tags +## Tags { #tags } -Sie kÃļnnen Ihrer *Pfadoperation* Tags hinzufÃŧgen, mittels des Parameters `tags`, dem eine `list`e von `str`s Ãŧbergeben wird (in der Regel nur ein `str`): +Sie kÃļnnen Ihrer *Pfadoperation* Tags hinzufÃŧgen, indem Sie dem Parameter `tags` eine `list`e von `str`s Ãŧbergeben (in der Regel nur ein `str`): {* ../../docs_src/path_operation_configuration/tutorial002_py310.py hl[15,20,25] *} @@ -38,47 +38,47 @@ Diese werden zum OpenAPI-Schema hinzugefÃŧgt und von den automatischen Dokumenta -### Tags mittels Enumeration +### Tags mittels Enumeration { #tags-with-enums } -Wenn Sie eine große Anwendung haben, kÃļnnen sich am Ende **viele Tags** anhäufen, und Sie mÃļchten sicherstellen, dass Sie fÃŧr verwandte *Pfadoperationen* immer den **gleichen Tag** nehmen. +Wenn Sie eine große Anwendung haben, kÃļnnen sich am Ende **viele Tags** anhäufen, und Sie mÃļchten sicherstellen, dass Sie fÃŧr verwandte *Pfadoperationen* immer den **gleichen Tag** verwenden. In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern. -**FastAPI** unterstÃŧtzt diese genauso wie einfache Strings: +**FastAPI** unterstÃŧtzt das auf die gleiche Weise wie einfache Strings: {* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *} -## Zusammenfassung und Beschreibung +## Zusammenfassung und Beschreibung { #summary-and-description } -Sie kÃļnnen eine Zusammenfassung (`summary`) und eine Beschreibung (`description`) hinzufÃŧgen: +Sie kÃļnnen eine `summary` und eine `description` hinzufÃŧgen: {* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *} -## Beschreibung mittels Docstring +## Beschreibung mittels Docstring { #description-from-docstring } Da Beschreibungen oft mehrere Zeilen lang sind, kÃļnnen Sie die Beschreibung der *Pfadoperation* im Docstring der Funktion deklarieren, und **FastAPI** wird sie daraus auslesen. -Sie kÃļnnen im Docstring Markdown schreiben, es wird korrekt interpretiert und angezeigt (die EinrÃŧckung des Docstring beachtend). +Sie kÃļnnen Markdown im Docstring schreiben, es wird korrekt interpretiert und angezeigt (unter BerÃŧcksichtigung der EinrÃŧckung des Docstring). {* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *} -In der interaktiven Dokumentation sieht das dann so aus: +Es wird in der interaktiven Dokumentation verwendet: -## Beschreibung der Response +## Beschreibung der Response { #response-description } -Die Response kÃļnnen Sie mit dem Parameter `response_description` beschreiben: +Sie kÃļnnen die Response mit dem Parameter `response_description` beschreiben: {* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *} -/// info +/// info | Info -beachten Sie, dass sich `response_description` speziell auf die Response bezieht, während `description` sich generell auf die *Pfadoperation* bezieht. +Beachten Sie, dass sich `response_description` speziell auf die Response bezieht, während `description` sich generell auf die *Pfadoperation* bezieht. /// -/// check +/// check | Testen OpenAPI verlangt, dass jede *Pfadoperation* Ãŧber eine Beschreibung der Response verfÃŧgt. @@ -88,13 +88,13 @@ Daher, wenn Sie keine vergeben, wird **FastAPI** automatisch eine fÃŧr „Erfolg -## Eine *Pfadoperation* deprecaten +## Eine *Pfadoperation* deprecaten { #deprecate-a-path-operation } -Wenn Sie eine *Pfadoperation* als deprecated kennzeichnen mÃļchten, ohne sie zu entfernen, fÃŧgen Sie den Parameter `deprecated` hinzu: +Wenn Sie eine *Pfadoperation* als deprecatet kennzeichnen mÃļchten, ohne sie zu entfernen, fÃŧgen Sie den Parameter `deprecated` hinzu: {* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *} -Sie wird in der interaktiven Dokumentation gut sichtbar als deprecated markiert werden: +Sie wird in der interaktiven Dokumentation gut sichtbar als deprecatet markiert werden: @@ -102,6 +102,6 @@ Vergleichen Sie, wie deprecatete und nicht-deprecatete *Pfadoperationen* aussehe -## Zusammenfassung +## Zusammenfassung { #recap } Sie kÃļnnen auf einfache Weise Metadaten fÃŧr Ihre *Pfadoperationen* definieren, indem Sie den *Pfadoperation-Dekoratoren* Parameter hinzufÃŧgen. diff --git a/docs/de/docs/tutorial/path-params-numeric-validations.md b/docs/de/docs/tutorial/path-params-numeric-validations.md index 1acdd5b4e..5b7474944 100644 --- a/docs/de/docs/tutorial/path-params-numeric-validations.md +++ b/docs/de/docs/tutorial/path-params-numeric-validations.md @@ -1,169 +1,154 @@ -# Pfad-Parameter und Validierung von Zahlen +# Pfad-Parameter und Validierung von Zahlen { #path-parameters-and-numeric-validations } -So wie Sie mit `Query` fÃŧr Query-Parameter zusätzliche Validierungen und Metadaten hinzufÃŧgen kÃļnnen, kÃļnnen Sie das mittels `Path` auch fÃŧr Pfad-Parameter tun. +So wie Sie mit `Query` fÃŧr Query-Parameter zusätzliche Validierungen und Metadaten deklarieren kÃļnnen, kÃļnnen Sie mit `Path` die gleichen Validierungen und Metadaten fÃŧr Pfad-Parameter deklarieren. -## `Path` importieren +## `Path` importieren { #import-path } -Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`. +Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`: {* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *} -/// info +/// info | Info -FastAPI unterstÃŧtzt (und empfiehlt die Verwendung von) `Annotated` seit Version 0.95.0. +FastAPI hat in Version 0.95.0 UnterstÃŧtzung fÃŧr `Annotated` hinzugefÃŧgt und es zur Verwendung empfohlen. -Wenn Sie eine ältere Version haben, werden Sie Fehler angezeigt bekommen, wenn Sie versuchen, `Annotated` zu verwenden. +Wenn Sie eine ältere Version haben, wÃŧrden Fehler angezeigt werden, wenn Sie versuchen, `Annotated` zu verwenden. -Bitte [aktualisieren Sie FastAPI](../deployment/versions.md#upgrade-der-fastapi-versionen){.internal-link target=_blank} daher mindestens zu Version 0.95.1, bevor Sie `Annotated` verwenden. +Stellen Sie sicher, dass Sie [FastAPI aktualisieren](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}, auf mindestens Version 0.95.1, bevor Sie `Annotated` verwenden. /// -## Metadaten deklarieren +## Metadaten deklarieren { #declare-metadata } -Sie kÃļnnen die gleichen Parameter deklarieren wie fÃŧr `Query`. +Sie kÃļnnen dieselben Parameter wie fÃŧr `Query` deklarieren. -Um zum Beispiel einen `title`-Metadaten-Wert fÃŧr den Pfad-Parameter `item_id` zu deklarieren, schreiben Sie: +Um zum Beispiel einen `title`-Metadaten-Wert fÃŧr den Pfad-Parameter `item_id` zu deklarieren, kÃļnnen Sie schreiben: {* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *} /// note | Hinweis -Ein Pfad-Parameter ist immer erforderlich, weil er Teil des Pfads sein muss. - -Sie sollten ihn daher mit `...` deklarieren, um ihn als erforderlich auszuzeichnen. - -Doch selbst wenn Sie ihn mit `None` deklarieren, oder einen Defaultwert setzen, bewirkt das nichts, er bleibt immer erforderlich. +Ein Pfad-Parameter ist immer erforderlich, da er Teil des Pfads sein muss. Selbst wenn Sie ihn mit `None` deklarieren oder einen Defaultwert setzen, wÃŧrde das nichts ändern, er wäre dennoch immer erforderlich. /// -## Sortieren Sie die Parameter, wie Sie mÃļchten +## Die Parameter sortieren, wie Sie mÃļchten { #order-the-parameters-as-you-need } /// tip | Tipp -Wenn Sie `Annotated` verwenden, ist das folgende nicht so wichtig / nicht notwendig. +Das ist wahrscheinlich nicht so wichtig oder notwendig, wenn Sie `Annotated` verwenden. /// -Nehmen wir an, Sie mÃļchten den Query-Parameter `q` als erforderlichen `str` deklarieren. +Angenommen, Sie mÃļchten den Query-Parameter `q` als erforderlichen `str` deklarieren. -Und Sie mÃŧssen sonst nichts anderes fÃŧr den Parameter deklarieren, Sie brauchen also nicht wirklich `Query`. +Und Sie mÃŧssen sonst nichts anderes fÃŧr diesen Parameter deklarieren, Sie brauchen also `Query` nicht wirklich. -Aber Sie brauchen `Path` fÃŧr den `item_id`-Pfad-Parameter. Und Sie mÃļchten aus irgendeinem Grund nicht `Annotated` verwenden. +Aber Sie mÃŧssen dennoch `Path` fÃŧr den `item_id`-Pfad-Parameter verwenden. Und aus irgendeinem Grund mÃļchten Sie `Annotated` nicht verwenden. -Python wird sich beschweren, wenn Sie einen Parameter mit Defaultwert vor einen Parameter ohne Defaultwert setzen. +Python wird sich beschweren, wenn Sie einen Wert mit einem „Default“ vor einem Wert ohne „Default“ setzen. -Aber Sie kÃļnnen die Reihenfolge der Parameter ändern, den Query-Parameter ohne Defaultwert zuerst. +Aber Sie kÃļnnen die Reihenfolge ändern und den Wert ohne Default (den Query-Parameter `q`) zuerst setzen. -FÃŧr **FastAPI** ist es nicht wichtig. Es erkennt die Parameter anhand ihres Namens, ihrer Typen, und ihrer Defaultwerte (`Query`, `Path`, usw.). Es kÃŧmmert sich nicht um die Reihenfolge. +FÃŧr **FastAPI** spielt es keine Rolle. Es erkennt die Parameter anhand ihrer Namen, Typen und Default-Deklarationen (`Query`, `Path`, usw.), es kÃŧmmert sich nicht um die Reihenfolge. Sie kÃļnnen Ihre Funktion also so deklarieren: -//// tab | Python 3.8 nicht annotiert +{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *} + +Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da es nicht darauf ankommt, dass Sie keine Funktionsparameter-Defaultwerte fÃŧr `Query()` oder `Path()` verwenden. + +{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *} + +## Die Parameter sortieren, wie Sie mÃļchten: Tricks { #order-the-parameters-as-you-need-tricks } /// tip | Tipp -Bevorzugen Sie die `Annotated`-Version, falls mÃļglich. +Das ist wahrscheinlich nicht so wichtig oder notwendig, wenn Sie `Annotated` verwenden. /// -```Python hl_lines="7" -{!> ../../docs_src/path_params_numeric_validations/tutorial002.py!} -``` +Hier ist ein **kleiner Trick**, der nÃŧtzlich sein kann, obwohl Sie ihn nicht oft benÃļtigen werden. -//// +Wenn Sie: -Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da Sie nicht die Funktions-Parameter-Defaultwerte fÃŧr `Query()` oder `Path()` verwenden. +* den `q`-Query-Parameter sowohl ohne `Query` als auch ohne Defaultwert deklarieren +* den Pfad-Parameter `item_id` mit `Path` deklarieren +* sie in einer anderen Reihenfolge haben +* nicht `Annotated` verwenden -{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py hl[10] *} +... mÃļchten, dann hat Python eine kleine Spezial-Syntax dafÃŧr. -## Sortieren Sie die Parameter wie Sie mÃļchten: Tricks +Übergeben Sie `*`, als den ersten Parameter der Funktion. -/// tip | Tipp - -Wenn Sie `Annotated` verwenden, ist das folgende nicht so wichtig / nicht notwendig. - -/// - -Hier ein **kleiner Trick**, der nÃŧtzlich sein kann, aber Sie werden ihn nicht oft brauchen. - -Wenn Sie eines der folgenden Dinge tun mÃļchten: - -* den `q`-Parameter ohne `Query` oder irgendeinem Defaultwert deklarieren -* den Pfad-Parameter `item_id` mittels `Path` deklarieren -* die Parameter in einer unterschiedlichen Reihenfolge haben -* `Annotated` nicht verwenden - -... dann hat Python eine kleine Spezial-Syntax fÃŧr Sie. - -Übergeben Sie der Funktion `*` als ersten Parameter. - -Python macht nichts mit diesem `*`, aber es wird wissen, dass alle folgenden Parameter als Keyword-Argumente (SchlÃŧssel-Wert-Paare), auch bekannt als kwargs, verwendet werden. Selbst wenn diese keinen Defaultwert haben. +Python wird nichts mit diesem `*` machen, aber es wird wissen, dass alle folgenden Parameter als SchlÃŧsselwortargumente (SchlÃŧssel-Wert-Paare) verwendet werden sollen, auch bekannt als kwargs. Selbst wenn diese keinen Defaultwert haben. {* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *} -### Besser mit `Annotated` +### Besser mit `Annotated` { #better-with-annotated } -Bedenken Sie, dass Sie, wenn Sie `Annotated` verwenden, dieses Problem nicht haben, weil Sie keine Defaultwerte fÃŧr Ihre Funktionsparameter haben. Sie mÃŧssen daher wahrscheinlich auch nicht `*` verwenden. +Bedenken Sie, dass Sie, wenn Sie `Annotated` verwenden, da Sie keine Funktionsparameter-Defaultwerte verwenden, dieses Problem nicht haben werden und wahrscheinlich nicht `*` verwenden mÃŧssen. {* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *} -## Validierung von Zahlen: GrÃļßer oder gleich +## Validierung von Zahlen: GrÃļßer oder gleich { #number-validations-greater-than-or-equal } -Mit `Query` und `Path` (und anderen, die Sie später kennenlernen), kÃļnnen Sie Zahlenbeschränkungen deklarieren. +Mit `Query` und `Path` (und anderen, die Sie später sehen werden) kÃļnnen Sie Zahlenbeschränkungen deklarieren. + +Hier, mit `ge=1`, muss `item_id` eine ganze Zahl sein, die „`g`reater than or `e`qual to“ (grÃļßer oder gleich) `1` ist. -Hier, mit `ge=1`, wird festgelegt, dass `item_id` eine Ganzzahl benÃļtigt, die grÃļßer oder gleich `1` ist (`g`reater than or `e`qual). {* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *} -## Validierung von Zahlen: GrÃļßer und kleiner oder gleich +## Validierung von Zahlen: GrÃļßer und kleiner oder gleich { #number-validations-greater-than-and-less-than-or-equal } -Das Gleiche trifft zu auf: +Das Gleiche gilt fÃŧr: -* `gt`: `g`reater `t`han – grÃļßer als -* `le`: `l`ess than or `e`qual – kleiner oder gleich +* `gt`: `g`reater `t`han (grÃļßer als) +* `le`: `l`ess than or `e`qual (kleiner oder gleich) {* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *} -## Validierung von Zahlen: Floats, grÃļßer und kleiner +## Validierung von Zahlen: Floats, grÃļßer und kleiner { #number-validations-floats-greater-than-and-less-than } -Zahlenvalidierung funktioniert auch fÃŧr `float`-Werte. +Zahlenvalidierung funktioniert auch fÃŧr `float`-Werte. -Hier wird es wichtig, in der Lage zu sein, gt zu deklarieren, und nicht nur ge, da Sie hiermit bestimmen kÃļnnen, dass ein Wert, zum Beispiel, grÃļßer als `0` sein muss, obwohl er kleiner als `1` ist. +Hier wird es wichtig, in der Lage zu sein, gt und nicht nur ge zu deklarieren. Da Sie mit dieser Option erzwingen kÃļnnen, dass ein Wert grÃļßer als `0` sein muss, selbst wenn er kleiner als `1` ist. -`0.5` wäre also ein gÃŧltiger Wert, aber nicht `0.0` oder `0`. +Also wäre `0.5` ein gÃŧltiger Wert. Aber `0.0` oder `0` nicht. -Das gleiche gilt fÃŧr lt. +Und das Gleiche gilt fÃŧr lt. {* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *} -## Zusammenfassung +## Zusammenfassung { #recap } -Mit `Query` und `Path` (und anderen, die Sie noch nicht gesehen haben) kÃļnnen Sie Metadaten und Stringvalidierungen deklarieren, so wie in [Query-Parameter und Stringvalidierungen](query-params-str-validations.md){.internal-link target=_blank} beschrieben. +Mit `Query`, `Path` (und anderen, die Sie noch nicht gesehen haben) kÃļnnen Sie Metadaten und Stringvalidierungen auf die gleichen Weisen deklarieren wie in [Query-Parameter und Stringvalidierungen](query-params-str-validations.md){.internal-link target=_blank} beschrieben. -Und Sie kÃļnnen auch Validierungen fÃŧr Zahlen deklarieren: +Und Sie kÃļnnen auch Zahlenvalidierungen deklarieren: -* `gt`: `g`reater `t`han – grÃļßer als -* `ge`: `g`reater than or `e`qual – grÃļßer oder gleich -* `lt`: `l`ess `t`han – kleiner als -* `le`: `l`ess than or `e`qual – kleiner oder gleich +* `gt`: `g`reater `t`han (grÃļßer als) +* `ge`: `g`reater than or `e`qual (grÃļßer oder gleich) +* `lt`: `l`ess `t`han (kleiner als) +* `le`: `l`ess than or `e`qual (kleiner oder gleich) -/// info +/// info | Info -`Query`, `Path`, und andere Klassen, die Sie später kennenlernen, sind Unterklassen einer allgemeinen `Param`-Klasse. +`Query`, `Path`, und andere Klassen, die Sie später sehen werden, sind Unterklassen einer gemeinsamen `Param`-Klasse. -Sie alle teilen die gleichen Parameter fÃŧr zusätzliche Validierung und Metadaten, die Sie gesehen haben. +Alle von ihnen teilen die gleichen Parameter fÃŧr zusätzliche Validierung und Metadaten, die Sie gesehen haben. /// /// note | Technische Details -`Query`, `Path` und andere, die Sie von `fastapi` importieren, sind tatsächlich Funktionen. +Wenn Sie `Query`, `Path` und andere von `fastapi` importieren, sind sie tatsächlich Funktionen. -Die, wenn sie aufgerufen werden, Instanzen der Klassen mit demselben Namen zurÃŧckgeben. +Die, wenn sie aufgerufen werden, Instanzen von Klassen mit demselben Namen zurÃŧckgeben. -Sie importieren also `Query`, welches eine Funktion ist. Aber wenn Sie es aufrufen, gibt es eine Instanz der Klasse zurÃŧck, die auch `Query` genannt wird. +Sie importieren also `Query`, was eine Funktion ist. Und wenn Sie sie aufrufen, gibt sie eine Instanz einer Klasse zurÃŧck, die auch `Query` genannt wird. Diese Funktionen existieren (statt die Klassen direkt zu verwenden), damit Ihr Editor keine Fehlermeldungen Ãŧber ihre Typen ausgibt. -Auf diese Weise kÃļnnen Sie Ihren Editor und Ihre Programmier-Tools verwenden, ohne besondere Einstellungen vornehmen zu mÃŧssen, um diese Fehlermeldungen stummzuschalten. +Auf diese Weise kÃļnnen Sie Ihren normalen Editor und Ihre Programmier-Tools verwenden, ohne besondere Einstellungen vornehmen zu mÃŧssen, um diese Fehlermeldungen stummzuschalten. /// diff --git a/docs/de/docs/tutorial/path-params.md b/docs/de/docs/tutorial/path-params.md index 123990940..1db288fb8 100644 --- a/docs/de/docs/tutorial/path-params.md +++ b/docs/de/docs/tutorial/path-params.md @@ -1,18 +1,18 @@ -# Pfad-Parameter +# Pfad-Parameter { #path-parameters } -Sie kÃļnnen Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-Format-Strings verwendet wird: +Sie kÃļnnen Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-Formatstrings verwendet wird: {* ../../docs_src/path_params/tutorial001.py hl[6:7] *} Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` Ãŧbergeben. -Wenn Sie dieses Beispiel ausfÃŧhren und auf http://127.0.0.1:8000/items/foo gehen, sehen Sie als Response: +Wenn Sie dieses Beispiel ausfÃŧhren und auf http://127.0.0.1:8000/items/foo gehen, sehen Sie als Response: ```JSON {"item_id":"foo"} ``` -## Pfad-Parameter mit Typen +## Pfad-Parameter mit Typen { #path-parameters-with-types } Sie kÃļnnen den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen: @@ -20,13 +20,13 @@ Sie kÃļnnen den Typ eines Pfad-Parameters in der Argumentliste der Funktion dekl In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl. -/// check +/// check | Testen Dadurch erhalten Sie Editor-UnterstÃŧtzung innerhalb Ihrer Funktion, mit FehlerprÃŧfungen, Codevervollständigung, usw. /// -## Daten-Konversion +## Daten-Konversion { #data-conversion } Wenn Sie dieses Beispiel ausfÃŧhren und Ihren Browser unter http://127.0.0.1:8000/items/3 Ãļffnen, sehen Sie als Response: @@ -34,15 +34,15 @@ Wenn Sie dieses Beispiel ausfÃŧhren und Ihren Browser unter „parsen“. +Sprich, mit dieser Typdeklaration wird **FastAPI** den Request automatisch „parsen“. /// -## Datenvalidierung +## Datenvalidierung { #data-validation } Wenn Sie aber im Browser http://127.0.0.1:8000/items/foo besuchen, erhalten Sie eine hÃŧbsche HTTP-Fehlermeldung: @@ -56,8 +56,7 @@ Wenn Sie aber im Browser http://127.0.0.1:8000/items/4.2 -/// check +/// check | Testen Sprich, mit der gleichen Python-Typdeklaration gibt Ihnen **FastAPI** Datenvalidierung. Beachten Sie, dass die Fehlermeldung auch direkt die Stelle anzeigt, wo die Validierung nicht erfolgreich war. -Das ist unglaublich hilfreich, wenn Sie Code entwickeln und debuggen, welcher mit ihrer API interagiert. +Das ist unglaublich hilfreich, wenn Sie Code entwickeln und debuggen, welcher mit Ihrer API interagiert. /// -## Dokumentation +## Dokumentation { #documentation } Wenn Sie die Seite http://127.0.0.1:8000/docs in Ihrem Browser Ãļffnen, sehen Sie eine automatische, interaktive API-Dokumentation: -/// check +/// check | Testen Wiederum, mit dieser gleichen Python-Typdeklaration gibt Ihnen **FastAPI** eine automatische, interaktive Dokumentation (verwendet die Swagger-Benutzeroberfläche). @@ -91,7 +90,7 @@ Beachten Sie, dass der Pfad-Parameter dort als Ganzzahl deklariert ist. /// -## NÃŧtzliche Standards. Alternative Dokumentation +## NÃŧtzliche Standards, alternative Dokumentation { #standards-based-benefits-alternative-documentation } Und weil das generierte Schema vom OpenAPI-Standard kommt, gibt es viele kompatible Tools. @@ -101,15 +100,15 @@ Zum Beispiel bietet **FastAPI** selbst eine alternative API-Dokumentation (verwe Und viele weitere kompatible Tools. Inklusive Codegenerierung fÃŧr viele Sprachen. -## Pydantic +## Pydantic { #pydantic } -Die ganze Datenvalidierung wird hinter den Kulissen von Pydantic durchgefÃŧhrt, Sie profitieren also von dessen Vorteilen. Und Sie wissen, dass Sie in guten Händen sind. +Die ganze Datenvalidierung wird hinter den Kulissen von Pydantic durchgefÃŧhrt, Sie profitieren also von dessen Vorteilen. Und Sie wissen, dass Sie in guten Händen sind. -Sie kÃļnnen fÃŧr Typ Deklarationen auch `str`, `float`, `bool` und viele andere komplexe Datentypen verwenden. +Sie kÃļnnen fÃŧr Typdeklarationen auch `str`, `float`, `bool` und viele andere komplexe Datentypen verwenden. Mehrere davon werden wir in den nächsten Kapiteln erkunden. -## Die Reihenfolge ist wichtig +## Die Reihenfolge ist wichtig { #order-matters } Wenn Sie *Pfadoperationen* erstellen, haben Sie manchmal einen fixen Pfad. @@ -129,23 +128,23 @@ Sie kÃļnnen eine Pfadoperation auch nicht erneut definieren: Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst Ãŧbereinstimmt. -## Vordefinierte Parameterwerte +## Vordefinierte Parameterwerte { #predefined-values } -Wenn Sie eine *Pfadoperation* haben, welche einen *Pfad-Parameter* hat, aber Sie wollen, dass dessen gÃŧltige Werte vordefiniert sind, kÃļnnen Sie ein Standard-Python `Enum` verwenden. +Wenn Sie eine *Pfadoperation* haben, welche einen *Pfad-Parameter* hat, aber Sie wollen, dass dessen gÃŧltige Werte vordefiniert sind, kÃļnnen Sie ein Standard-Python `Enum` verwenden. -### Erstellen Sie eine `Enum`-Klasse +### Eine `Enum`-Klasse erstellen { #create-an-enum-class } Importieren Sie `Enum` und erstellen Sie eine Unterklasse, die von `str` und `Enum` erbt. -Indem Sie von `str` erben, weiß die API Dokumentation, dass die Werte des Enums vom Typ `str` sein mÃŧssen, und wird in der Lage sein, korrekt zu rendern. +Indem Sie von `str` erben, weiß die API-Dokumentation, dass die Werte vom Typ `str` sein mÃŧssen, und wird in der Lage sein, korrekt zu rendern. Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden: {* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *} -/// info +/// info | Info -Enumerationen (oder kurz Enums) gibt es in Python seit Version 3.4. +Enumerationen (oder Enums) gibt es in Python seit Version 3.4. /// @@ -155,31 +154,31 @@ Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das /// -### Deklarieren Sie einen *Pfad-Parameter* +### Einen *Pfad-Parameter* deklarieren { #declare-a-path-parameter } Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`): {* ../../docs_src/path_params/tutorial005.py hl[16] *} -### Testen Sie es in der API-Dokumentation +### Die API-Dokumentation testen { #check-the-docs } Weil die erlaubten Werte fÃŧr den *Pfad-Parameter* nun vordefiniert sind, kann die interaktive Dokumentation sie als Auswahl-Drop-Down anzeigen: -### Mit Python-*Enums* arbeiten +### Mit Python-*Enumerationen* arbeiten { #working-with-python-enumerations } -Der *Pfad-Parameter* wird ein *Member eines Enums* sein. +Der *Pfad-Parameter* wird ein *Member einer Enumeration* sein. -#### *Enum-Member* vergleichen +#### *Enumeration-Member* vergleichen { #compare-enumeration-members } -Sie kÃļnnen ihn mit einem Member Ihres Enums `ModelName` vergleichen: +Sie kÃļnnen ihn mit einem Member Ihrer Enumeration `ModelName` vergleichen: {* ../../docs_src/path_params/tutorial005.py hl[17] *} -#### *Enum-Wert* erhalten +#### *Enumerations-Wert* erhalten { #get-the-enumeration-value } -Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `ihr_enum_member.value`: +Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `your_enum_member.value`: {* ../../docs_src/path_params/tutorial005.py hl[20] *} @@ -189,7 +188,7 @@ Sie kÃļnnen den Wert `"lenet"` außerdem mittels `ModelName.lenet.value` abrufen /// -#### *Enum-Member* zurÃŧckgeben +#### *Enumeration-Member* zurÃŧckgeben { #return-enumeration-members } Sie kÃļnnen *Enum-Member* in ihrer *Pfadoperation* zurÃŧckgeben, sogar verschachtelt in einem JSON-Body (z. B. als `dict`). @@ -206,7 +205,7 @@ In Ihrem Client erhalten Sie eine JSON-Response, wie etwa: } ``` -## Pfad Parameter die Pfade enthalten +## Pfad-Parameter, die Pfade enthalten { #path-parameters-containing-paths } Angenommen, Sie haben eine *Pfadoperation* mit einem Pfad `/files/{file_path}`. @@ -214,7 +213,7 @@ Aber `file_path` soll selbst einen *Pfad* enthalten, etwa `home/johndoe/myfile.t Sprich, die URL fÃŧr diese Datei wäre etwas wie: `/files/home/johndoe/myfile.txt`. -### OpenAPI UnterstÃŧtzung +### OpenAPI-UnterstÃŧtzung { #openapi-support } OpenAPI bietet nicht die MÃļglichkeit, dass ein *Pfad-Parameter* seinerseits einen *Pfad* enthalten kann, das wÃŧrde zu Szenarios fÃŧhren, die schwierig zu testen und zu definieren sind. @@ -222,7 +221,7 @@ Trotzdem kÃļnnen Sie das in **FastAPI** tun, indem Sie eines der internen Tools Die Dokumentation wÃŧrde weiterhin funktionieren, allerdings wird nicht dokumentiert werden, dass der Parameter ein Pfad sein sollte. -### Pfad Konverter +### Pfad-Konverter { #path-convertor } Mittels einer Option direkt von Starlette kÃļnnen Sie einen *Pfad-Parameter* deklarieren, der einen Pfad enthalten soll, indem Sie eine URL wie folgt definieren: @@ -244,12 +243,12 @@ In dem Fall wäre die URL: `/files//home/johndoe/myfile.txt`, mit einem doppelte /// -## Zusammenfassung +## Zusammenfassung { #recap } In **FastAPI** erhalten Sie mittels kurzer, intuitiver Typdeklarationen: * Editor-UnterstÃŧtzung: FehlerprÃŧfungen, Codevervollständigung, usw. -* Daten "parsen" +* Daten "parsen" * Datenvalidierung * API-Annotationen und automatische Dokumentation diff --git a/docs/de/docs/tutorial/query-param-models.md b/docs/de/docs/tutorial/query-param-models.md new file mode 100644 index 000000000..7d3f2d32e --- /dev/null +++ b/docs/de/docs/tutorial/query-param-models.md @@ -0,0 +1,68 @@ +# Query-Parameter-Modelle { #query-parameter-models } + +Wenn Sie eine Gruppe von **Query-Parametern** haben, die miteinander in Beziehung stehen, kÃļnnen Sie ein **Pydantic-Modell** erstellen, um diese zu deklarieren. + +Dadurch kÃļnnen Sie das **Modell an mehreren Stellen wiederverwenden** und gleichzeitig Validierungen und Metadaten fÃŧr alle Parameter auf einmal deklarieren. 😎 + +/// note | Hinweis + +Dies wird seit FastAPI Version `0.115.0` unterstÃŧtzt. 🤓 + +/// + +## Query-Parameter mit einem Pydantic-Modell { #query-parameters-with-a-pydantic-model } + +Deklarieren Sie die benÃļtigten **Query-Parameter** in einem **Pydantic-Modell** und dann den Parameter als `Query`: + +{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *} + +**FastAPI** wird die Daten fÃŧr **jedes Feld** aus den **Query-Parametern** des Request extrahieren und Ihnen das definierte Pydantic-Modell bereitstellen. + +## Die Dokumentation testen { #check-the-docs } + +Sie kÃļnnen die Query-Parameter in der Dokumentations-Oberfläche unter `/docs` einsehen: + +
+ +
+ +## Zusätzliche Query-Parameter verbieten { #forbid-extra-query-parameters } + +In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) mÃļchten Sie mÃļglicherweise die Query-Parameter, die Sie empfangen mÃļchten, **beschränken**. + +Sie kÃļnnen die Modellkonfiguration von Pydantic verwenden, um jegliche `extra` Felder zu `verbieten`: + +{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *} + +Wenn ein Client versucht, einige **zusätzliche** Daten in den **Query-Parametern** zu senden, erhält er eine **Error-Response**. + +Wenn der Client beispielsweise versucht, einen `tool` Query-Parameter mit dem Wert `plumbus` zu senden, wie: + +```http +https://example.com/items/?limit=10&tool=plumbus +``` + +erhält er eine **Error-Response**, die ihm mitteilt, dass der Query-Parameter `tool` nicht erlaubt ist: + +```json +{ + "detail": [ + { + "type": "extra_forbidden", + "loc": ["query", "tool"], + "msg": "Extra inputs are not permitted", + "input": "plumbus" + } + ] +} +``` + +## Zusammenfassung { #summary } + +Sie kÃļnnen **Pydantic-Modelle** verwenden, um **Query-Parameter** in **FastAPI** zu deklarieren. 😎 + +/// tip | Tipp + +Spoiler-Alarm: Sie kÃļnnen auch Pydantic-Modelle verwenden, um Cookies und Header zu deklarieren, aber darÃŧber werden Sie später im Tutorial lesen. đŸ¤Ģ + +/// diff --git a/docs/de/docs/tutorial/query-params-str-validations.md b/docs/de/docs/tutorial/query-params-str-validations.md index de8879ce8..744160baf 100644 --- a/docs/de/docs/tutorial/query-params-str-validations.md +++ b/docs/de/docs/tutorial/query-params-str-validations.md @@ -1,69 +1,49 @@ -# Query-Parameter und Stringvalidierung +# Query-Parameter und String-Validierungen { #query-parameters-and-string-validations } -**FastAPI** erlaubt es Ihnen, Ihre Parameter zusätzlich zu validieren, und zusätzliche Informationen hinzuzufÃŧgen. +**FastAPI** ermÃļglicht es Ihnen, zusätzliche Informationen und Validierungen fÃŧr Ihre Parameter zu deklarieren. -Nehmen wir als Beispiel die folgende Anwendung: +Nehmen wir diese Anwendung als Beispiel: {* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *} -Der Query-Parameter `q` hat den Typ `Union[str, None]` (oder `str | None` in Python 3.10), was bedeutet, er ist entweder ein `str` oder `None`. Der Defaultwert ist `None`, also weiß FastAPI, der Parameter ist nicht erforderlich. +Der Query-Parameter `q` hat den Typ `str | None`, das bedeutet, dass er vom Typ `str` sein kann, aber auch `None`, und tatsächlich ist der Defaultwert `None`, sodass FastAPI weiß, dass er nicht erforderlich ist. /// note | Hinweis -FastAPI weiß nur dank des definierten Defaultwertes `=None`, dass der Wert von `q` nicht erforderlich ist +FastAPI erkennt, dass der Wert von `q` nicht erforderlich ist, aufgrund des Defaultwertes `= None`. -`Union[str, None]` hingegen erlaubt ihren Editor, Sie besser zu unterstÃŧtzen und Fehler zu erkennen. +Die Verwendung von `str | None` ermÃļglicht es Ihrem Editor, Ihnen bessere UnterstÃŧtzung zu bieten und Fehler zu erkennen. /// -## Zusätzliche Validierung +## Zusätzliche Validierung { #additional-validation } -Wir werden bewirken, dass, obwohl `q` optional ist, wenn es gegeben ist, **seine Länge 50 Zeichen nicht Ãŧberschreitet**. +Wir werden sicherstellen, dass, obwohl `q` optional ist, wann immer es bereitgestellt wird, **seine Länge 50 Zeichen nicht Ãŧberschreitet**. -### `Query` und `Annotated` importieren +### `Query` und `Annotated` importieren { #import-query-and-annotated } -Importieren Sie zuerst: +Um dies zu erreichen, importieren Sie zuerst: * `Query` von `fastapi` -* `Annotated` von `typing` (oder von `typing_extensions` in Python unter 3.9) +* `Annotated` von `typing` -//// tab | Python 3.10+ +{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *} -In Python 3.9 oder darÃŧber, ist `Annotated` Teil der Standardbibliothek, also kÃļnnen Sie es von `typing` importieren. +/// info | Info -```Python hl_lines="1 3" -{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!} -``` +FastAPI hat UnterstÃŧtzung fÃŧr `Annotated` hinzugefÃŧgt (und begonnen, es zu empfehlen) in der Version 0.95.0. -//// +Wenn Sie eine ältere Version haben, wÃŧrden Sie Fehler erhalten, beim Versuch, `Annotated` zu verwenden. -//// tab | Python 3.8+ - -In Versionen unter Python 3.9 importieren Sie `Annotated` von `typing_extensions`. - -Es wird bereits mit FastAPI installiert sein. - -```Python hl_lines="3-4" -{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!} -``` - -//// - -/// info - -FastAPI unterstÃŧtzt (und empfiehlt die Verwendung von) `Annotated` seit Version 0.95.0. - -Wenn Sie eine ältere Version haben, werden Sie Fehler angezeigt bekommen, wenn Sie versuchen, `Annotated` zu verwenden. - -Bitte [aktualisieren Sie FastAPI](../deployment/versions.md#upgrade-der-fastapi-versionen){.internal-link target=_blank} daher mindestens zu Version 0.95.1, bevor Sie `Annotated` verwenden. +Stellen Sie sicher, dass Sie [die FastAPI-Version aktualisieren](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank}, auf mindestens Version 0.95.1, bevor Sie `Annotated` verwenden. /// -## `Annotated` im Typ des `q`-Parameters verwenden +## Verwenden von `Annotated` im Typ fÃŧr den `q`-Parameter { #use-annotated-in-the-type-for-the-q-parameter } -Erinnern Sie sich, wie ich in [EinfÃŧhrung in Python-Typen](../python-types.md#typhinweise-mit-metadaten-annotationen){.internal-link target=_blank} sagte, dass Sie mittels `Annotated` Metadaten zu Ihren Parametern hinzufÃŧgen kÃļnnen? +Erinnern Sie sich, dass ich Ihnen zuvor in [Python-Typen-Intro](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank} gesagt habe, dass `Annotated` verwendet werden kann, um Metadaten zu Ihren Parametern hinzuzufÃŧgen? -Jetzt ist es an der Zeit, das mit FastAPI auszuprobieren. 🚀 +Jetzt ist es soweit, dies mit FastAPI zu verwenden. 🚀 Wir hatten diese Typannotation: @@ -83,7 +63,7 @@ q: Union[str, None] = None //// -Wir wrappen das nun in `Annotated`, sodass daraus wird: +Was wir tun werden, ist, dies mit `Annotated` zu wrappen, sodass es zu: //// tab | Python 3.10+ @@ -101,101 +81,75 @@ q: Annotated[Union[str, None]] = None //// -Beide Versionen bedeuten dasselbe: `q` ist ein Parameter, der `str` oder `None` sein kann. Standardmäßig ist er `None`. +Beide dieser Versionen bedeuten dasselbe: `q` ist ein Parameter, der ein `str` oder `None` sein kann, und standardmäßig ist er `None`. -Wenden wir uns jetzt den spannenden Dingen zu. 🎉 +Jetzt springen wir zu den spannenden Dingen. 🎉 -## `Query` zu `Annotated` im `q`-Parameter hinzufÃŧgen +## `Query` zu `Annotated` im `q`-Parameter hinzufÃŧgen { #add-query-to-annotated-in-the-q-parameter } -Jetzt, da wir `Annotated` fÃŧr unsere Metadaten deklariert haben, fÃŧgen Sie `Query` hinzu, und setzen Sie den Parameter `max_length` auf `50`: +Da wir nun `Annotated` haben, in das wir mehr Informationen (in diesem Fall einige zusätzliche Validierungen) einfÃŧgen kÃļnnen, fÃŧgen Sie `Query` innerhalb von `Annotated` hinzu und setzen Sie den Parameter `max_length` auf `50`: {* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *} -Beachten Sie, dass der Defaultwert immer noch `None` ist, sodass der Parameter immer noch optional ist. +Beachten Sie, dass der Defaultwert weiterhin `None` ist, so dass der Parameter weiterhin optional ist. -Aber jetzt, mit `Query(max_length=50)` innerhalb von `Annotated`, sagen wir FastAPI, dass es diesen Wert aus den Query-Parametern extrahieren soll (das hätte es sowieso gemacht 🤷) und dass wir eine **zusätzliche Validierung** fÃŧr diesen Wert haben wollen (darum machen wir das, um die zusätzliche Validierung zu bekommen). 😎 - -FastAPI wird nun: - -* Die Daten **validieren** und sicherstellen, dass sie nicht länger als 50 Zeichen sind -* Dem Client einen **verständlichen Fehler** anzeigen, wenn die Daten ungÃŧltig sind -* Den Parameter in der OpenAPI-Schema-*Pfadoperation* **dokumentieren** (sodass er in der **automatischen Dokumentation** angezeigt wird) - -## Alternativ (alt): `Query` als Defaultwert - -FrÃŧhere Versionen von FastAPI (vor 0.95.0) benÃļtigten `Query` als Defaultwert des Parameters, statt es innerhalb von `Annotated` unterzubringen. Die Chance ist groß, dass Sie Quellcode sehen, der das immer noch so macht, darum erkläre ich es Ihnen. +Aber jetzt, mit `Query(max_length=50)` innerhalb von `Annotated`, sagen wir FastAPI, dass wir eine **zusätzliche Validierung** fÃŧr diesen Wert wÃŧnschen, wir wollen, dass er maximal 50 Zeichen hat. 😎 /// tip | Tipp -Verwenden Sie fÃŧr neuen Code, und wann immer mÃļglich, `Annotated`, wie oben erklärt. Es gibt mehrere Vorteile (unten erläutert) und keine Nachteile. 🍰 +Hier verwenden wir `Query()`, weil dies ein **Query-Parameter** ist. Später werden wir andere wie `Path()`, `Body()`, `Header()`, und `Cookie()` sehen, die auch dieselben Argumente wie `Query()` akzeptieren. /// -So wÃŧrden Sie `Query()` als Defaultwert Ihres Funktionsparameters verwenden, den Parameter `max_length` auf 50 gesetzt: +FastAPI wird nun: + +* Die Daten **validieren**, um sicherzustellen, dass die Länge maximal 50 Zeichen beträgt +* Einen **klaren Fehler** fÃŧr den Client anzeigen, wenn die Daten ungÃŧltig sind +* Den Parameter in der OpenAPI-Schema-*Pfadoperation* **dokumentieren** (sodass er in der **automatischen Dokumentation** angezeigt wird) + +## Alternative (alt): `Query` als Defaultwert { #alternative-old-query-as-the-default-value } + +FrÃŧhere Versionen von FastAPI (vor 0.95.0) erforderten, dass Sie `Query` als den Defaultwert Ihres Parameters verwendeten, anstatt es innerhalb von `Annotated` zu platzieren. Es besteht eine hohe Wahrscheinlichkeit, dass Sie Code sehen, der es so verwendet, also werde ich es Ihnen erklären. + +/// tip | Tipp + +FÃŧr neuen Code und wann immer es mÃļglich ist, verwenden Sie `Annotated` wie oben erklärt. Es gibt mehrere Vorteile (unten erläutert) und keine Nachteile. 🍰 + +/// + +So wÃŧrden Sie `Query()` als den Defaultwert Ihres Funktionsparameters verwenden und den Parameter `max_length` auf 50 setzen: {* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *} -Da wir in diesem Fall (ohne die Verwendung von `Annotated`) den Parameter-Defaultwert `None` mit `Query()` ersetzen, mÃŧssen wir nun dessen Defaultwert mit dem Parameter `Query(default=None)` deklarieren. Das dient demselben Zweck, `None` als Defaultwert fÃŧr den Funktionsparameter zu setzen (zumindest fÃŧr FastAPI). +Da wir in diesem Fall (ohne die Verwendung von `Annotated`) den Defaultwert `None` in der Funktion durch `Query()` ersetzen mÃŧssen, mÃŧssen wir nun den Defaultwert mit dem Parameter `Query(default=None)` setzen, er erfÃŧllt den gleichen Zweck, diesen Defaultwert zu definieren (zumindest fÃŧr FastAPI). -Sprich: - -```Python -q: Union[str, None] = Query(default=None) -``` - -... macht den Parameter optional, mit dem Defaultwert `None`, genauso wie: - -```Python -q: Union[str, None] = None -``` - -Und in Python 3.10 und darÃŧber macht: +Also: ```Python q: str | None = Query(default=None) ``` -... den Parameter optional, mit dem Defaultwert `None`, genauso wie: +... macht den Parameter optional mit einem Defaultwert von `None`, genauso wie: ```Python q: str | None = None ``` -Nur, dass die `Query`-Versionen den Parameter explizit als Query-Parameter deklarieren. +Aber die `Query`-Version deklariert ihn explizit als Query-Parameter. -/// info - -Bedenken Sie, dass: +Dann kÃļnnen wir mehr Parameter an `Query` Ãŧbergeben. In diesem Fall den `max_length`-Parameter, der auf Strings angewendet wird: ```Python -= None +q: str | None = Query(default=None, max_length=50) ``` -oder: +Dies wird die Daten validieren, einen klaren Fehler anzeigen, wenn die Daten nicht gÃŧltig sind, und den Parameter in der OpenAPI-Schema-*Pfadoperation* dokumentieren. -```Python -= Query(default=None) -``` +### `Query` als Defaultwert oder in `Annotated` { #query-as-the-default-value-or-in-annotated } -der wichtigste Teil ist, um einen Parameter optional zu machen, da dieses `None` der Defaultwert ist, und das ist es, was diesen Parameter **nicht erforderlich** macht. +Beachten Sie, dass wenn Sie `Query` innerhalb von `Annotated` verwenden, Sie den `default`-Parameter fÃŧr `Query` nicht verwenden dÃŧrfen. -Der Teil mit `Union[str, None]` erlaubt es Ihrem Editor, Sie besser zu unterstÃŧtzen, aber er sagt FastAPI nicht, dass dieser Parameter optional ist. - -/// - -Jetzt kÃļnnen wir `Query` weitere Parameter Ãŧbergeben. Fangen wir mit dem `max_length` Parameter an, der auf Strings angewendet wird: - -```Python -q: Union[str, None] = Query(default=None, max_length=50) -``` - -Das wird die Daten validieren, einen verständlichen Fehler ausgeben, wenn die Daten nicht gÃŧltig sind, und den Parameter in der OpenAPI-Schema-*Pfadoperation* dokumentieren. - -### `Query` als Defaultwert oder in `Annotated` - -Bedenken Sie, dass wenn Sie `Query` innerhalb von `Annotated` benutzen, Sie den `default`-Parameter fÃŧr `Query` nicht verwenden dÃŧrfen. - -Setzen Sie stattdessen den Defaultwert des Funktionsparameters, sonst wäre es inkonsistent. +Setzen Sie stattdessen den tatsächlichen Defaultwert des Funktionsparameters. Andernfalls wäre es inkonsistent. Zum Beispiel ist das nicht erlaubt: @@ -203,7 +157,7 @@ Zum Beispiel ist das nicht erlaubt: q: Annotated[str, Query(default="rick")] = "morty" ``` -... denn es wird nicht klar, ob der Defaultwert `"rick"` oder `"morty"` sein soll. +... denn es ist nicht klar, ob der Defaultwert `"rick"` oder `"morty"` sein soll. Sie wÃŧrden also (bevorzugt) schreiben: @@ -211,49 +165,49 @@ Sie wÃŧrden also (bevorzugt) schreiben: q: Annotated[str, Query()] = "rick" ``` -In älterem Code werden Sie auch finden: +... oder in älteren Codebasen finden Sie: ```Python q: str = Query(default="rick") ``` -### VorzÃŧge von `Annotated` +### VorzÃŧge von `Annotated` { #advantages-of-annotated } -**Es wird empfohlen, `Annotated` zu verwenden**, statt des Defaultwertes im Funktionsparameter, das ist aus mehreren GrÃŧnden **besser**: 🤓 +**Es wird empfohlen, `Annotated` zu verwenden**, anstelle des Defaultwertes in Funktionsparametern, es ist aus mehreren GrÃŧnden **besser**. 🤓 -Der **Default**wert des **Funktionsparameters** ist der **tatsächliche Default**wert, das spielt generell intuitiver mit Python zusammen. 😌 +Der **Default**wert des **Funktionsparameters** ist der **tatsächliche Default**wert, das ist in der Regel intuitiver mit Python. 😌 -Sie kÃļnnen die Funktion ohne FastAPI an **anderen Stellen aufrufen**, und es wird **wie erwartet funktionieren**. Wenn es einen **erforderlichen** Parameter gibt (ohne Defaultwert), und Sie fÃŧhren die Funktion ohne den benÃļtigten Parameter aus, dann wird Ihr **Editor** Sie das mit einem Fehler wissen lassen, und **Python** wird sich auch beschweren. +Sie kÃļnnten **diese gleiche Funktion** in **anderen Stellen** ohne FastAPI **aufrufen**, und es wÃŧrde **wie erwartet funktionieren**. Wenn es einen **erforderlichen** Parameter gibt (ohne Defaultwert), wird Ihr **Editor** Ihnen dies mit einem Fehler mitteilen, außerdem wird **Python** sich beschweren, wenn Sie es ausfÃŧhren, ohne den erforderlichen Parameter zu Ãŧbergeben. -Wenn Sie aber nicht `Annotated` benutzen und stattdessen die **(alte) Variante mit einem Defaultwert**, dann mÃŧssen Sie, wenn Sie die Funktion ohne FastAPI an **anderen Stellen** aufrufen, sich daran **erinnern**, die Argumente der Funktion zu Ãŧbergeben, damit es richtig funktioniert. Ansonsten erhalten Sie unerwartete Werte (z. B. `QueryInfo` oder etwas Ähnliches, statt `str`). Ihr Editor kann ihnen nicht helfen, und Python wird die Funktion ohne Beschwerden ausfÃŧhren, es sei denn, die Operationen innerhalb lÃļsen einen Fehler aus. +Wenn Sie `Annotated` nicht verwenden und stattdessen die **(alte) Defaultwert-Stilform** verwenden, mÃŧssen Sie sich daran **erinnern**, die Argumente der Funktion zu Ãŧbergeben, wenn Sie diese Funktion ohne FastAPI in **anderen Stellen** aufrufen. Ansonsten sind die Werte anders als erwartet (z. B. `QueryInfo` oder etwas Ähnliches statt `str`). Ihr Editor kann Ihnen nicht helfen, und Python wird die Funktion ohne Klagen ausfÃŧhren und sich nur beschweren wenn die Operationen innerhalb auf einen Fehler stoßen. -Da `Annotated` mehrere Metadaten haben kann, kÃļnnen Sie dieselbe Funktion auch mit anderen Tools verwenden, wie etwa Typer. 🚀 +Da `Annotated` mehr als eine Metadaten-Annotation haben kann, kÃļnnten Sie dieselbe Funktion sogar mit anderen Tools verwenden, wie z. B. Typer. 🚀 -## Mehr Validierungen hinzufÃŧgen +## Mehr Validierungen hinzufÃŧgen { #add-more-validations } -Sie kÃļnnen auch einen Parameter `min_length` hinzufÃŧgen: +Sie kÃļnnen auch einen `min_length`-Parameter hinzufÃŧgen: {* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *} -## Reguläre AusdrÃŧcke hinzufÃŧgen +## Reguläre AusdrÃŧcke hinzufÃŧgen { #add-regular-expressions } -Sie kÃļnnen einen Regulären Ausdruck `pattern` definieren, mit dem der Parameter Ãŧbereinstimmen muss: +Sie kÃļnnen einen regulären Ausdruck `pattern` definieren, mit dem der Parameter Ãŧbereinstimmen muss: {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *} -Dieses bestimmte reguläre Suchmuster prÃŧft, ob der erhaltene Parameter-Wert: +Dieses spezielle Suchmuster im regulären Ausdruck ÃŧberprÃŧft, dass der erhaltene Parameterwert: -* `^`: mit den nachfolgenden Zeichen startet, keine Zeichen davor hat. +* `^`: mit den nachfolgenden Zeichen beginnt, keine Zeichen davor hat. * `fixedquery`: den exakten Text `fixedquery` hat. -* `$`: danach endet, keine weiteren Zeichen hat als `fixedquery`. +* `$`: dort endet, keine weiteren Zeichen nach `fixedquery` hat. -Wenn Sie sich verloren fÃŧhlen bei all diesen **„Regulärer Ausdruck“**-Konzepten, keine Sorge. Reguläre AusdrÃŧcke sind fÃŧr viele Menschen ein schwieriges Thema. Sie kÃļnnen auch ohne reguläre AusdrÃŧcke eine ganze Menge machen. +Wenn Sie sich mit all diesen **„regulärer Ausdruck“**-Ideen verloren fÃŧhlen, keine Sorge. Sie sind ein schwieriges Thema fÃŧr viele Menschen. Sie kÃļnnen noch viele Dinge tun, ohne reguläre AusdrÃŧcke direkt zu benÃļtigen. -Aber wenn Sie sie brauchen und sie lernen, wissen Sie, dass Sie sie bereits direkt in **FastAPI** verwenden kÃļnnen. +Aber nun wissen Sie, dass Sie sie in **FastAPI** immer dann verwenden kÃļnnen, wenn Sie sie brauchen. -### Pydantic v1 `regex` statt `pattern` +### Pydantic v1 `regex` statt `pattern` { #pydantic-v1-regex-instead-of-pattern } -Vor Pydantic Version 2 und vor FastAPI Version 0.100.0, war der Name des Parameters `regex` statt `pattern`, aber das ist jetzt deprecated. +Vor Pydantic Version 2 und FastAPI 0.100.0, hieß der Parameter `regex` statt `pattern`, aber das ist jetzt obsolet. Sie kÃļnnten immer noch Code sehen, der den alten Namen verwendet: @@ -263,25 +217,25 @@ Sie kÃļnnten immer noch Code sehen, der den alten Namen verwendet: //// -Beachten Sie aber, dass das deprecated ist, und zum neuen Namen `pattern` geändert werden sollte. 🤓 +Beachten Sie aber, dass das obsolet ist und auf den neuen Parameter `pattern` aktualisiert werden sollte. 🤓 -## Defaultwerte +## Defaultwerte { #default-values } -Sie kÃļnnen natÃŧrlich andere Defaultwerte als `None` verwenden. +NatÃŧrlich kÃļnnen Sie Defaultwerte verwenden, die nicht `None` sind. -Beispielsweise kÃļnnten Sie den `q` Query-Parameter so deklarieren, dass er eine `min_length` von `3` hat, und den Defaultwert `"fixedquery"`: +Nehmen wir an, Sie mÃļchten, dass der `q` Query-Parameter eine `min_length` von `3` hat und einen Defaultwert von `"fixedquery"`: {* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *} /// note | Hinweis -Ein Parameter ist optional (nicht erforderlich), wenn er irgendeinen Defaultwert, auch `None`, hat. +Ein Defaultwert irgendeines Typs, einschließlich `None`, macht den Parameter optional (nicht erforderlich). /// -## Erforderliche Parameter +## Erforderliche Parameter { #required-parameters } -Wenn wir keine Validierungen oder Metadaten haben, kÃļnnen wir den `q` Query-Parameter erforderlich machen, indem wir einfach keinen Defaultwert deklarieren, wie in: +Wenn wir keine weiteren Validierungen oder Metadaten deklarieren mÃŧssen, kÃļnnen wir den `q` Query-Parameter erforderlich machen, indem wir einfach keinen Defaultwert deklarieren, wie: ```Python q: str @@ -290,56 +244,32 @@ q: str statt: ```Python -q: Union[str, None] = None +q: str | None = None ``` -Aber jetzt deklarieren wir den Parameter mit `Query`, wie in: - -//// tab | Annotiert +Aber jetzt deklarieren wir es mit `Query`, zum Beispiel so: ```Python -q: Annotated[Union[str, None], Query(min_length=3)] = None +q: Annotated[str | None, Query(min_length=3)] = None ``` -//// - -//// tab | Nicht annotiert - -```Python -q: Union[str, None] = Query(default=None, min_length=3) -``` - -//// - -Wenn Sie einen Parameter erforderlich machen wollen, während Sie `Query` verwenden, deklarieren Sie ebenfalls einfach keinen Defaultwert: +Wenn Sie einen Wert als erforderlich deklarieren mÃŧssen, während Sie `Query` verwenden, deklarieren Sie einfach keinen Defaultwert: {* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *} -### Erforderlich, kann `None` sein +### Erforderlich, kann `None` sein { #required-can-be-none } -Sie kÃļnnen deklarieren, dass ein Parameter `None` akzeptiert, aber dennoch erforderlich ist. Das zwingt Clients, den Wert zu senden, selbst wenn er `None` ist. +Sie kÃļnnen deklarieren, dass ein Parameter `None` akzeptieren kann, aber trotzdem erforderlich ist. Dadurch mÃŧssten Clients den Wert senden, selbst wenn der Wert `None` ist. -Um das zu machen, deklarieren Sie, dass `None` ein gÃŧltiger Typ ist, aber verwenden Sie dennoch `...` als Default: +Um das zu tun, kÃļnnen Sie deklarieren, dass `None` ein gÃŧltiger Typ ist, einfach indem Sie keinen Defaultwert deklarieren: {* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *} -/// tip | Tipp +## Query-Parameter-Liste / Mehrere Werte { #query-parameter-list-multiple-values } -Pydantic, welches die gesamte Datenvalidierung und Serialisierung in FastAPI antreibt, hat ein spezielles Verhalten, wenn Sie `Optional` oder `Union[Something, None]` ohne Defaultwert verwenden, Sie kÃļnnen mehr darÃŧber in der Pydantic-Dokumentation unter Required fields erfahren. +Wenn Sie einen Query-Parameter explizit mit `Query` definieren, kÃļnnen Sie ihn auch so deklarieren, dass er eine Liste von Werten empfängt, oder anders gesagt, dass er mehrere Werte empfangen kann. -/// - -/// tip | Tipp - -Denken Sie daran, dass Sie in den meisten Fällen, wenn etwas erforderlich ist, einfach den Defaultwert weglassen kÃļnnen. Sie mÃŧssen also normalerweise `...` nicht verwenden. - -/// - -## Query-Parameter-Liste / Mehrere Werte - -Wenn Sie einen Query-Parameter explizit mit `Query` auszeichnen, kÃļnnen Sie ihn auch eine Liste von Werten empfangen lassen, oder anders gesagt, mehrere Werte. - -Um zum Beispiel einen Query-Parameter `q` zu deklarieren, der mehrere Male in der URL vorkommen kann, schreiben Sie: +Um zum Beispiel einen Query-Parameter `q` zu deklarieren, der mehrmals in der URL vorkommen kann, schreiben Sie: {* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *} @@ -349,9 +279,9 @@ Dann, mit einer URL wie: http://localhost:8000/items/?q=foo&q=bar ``` -bekommen Sie alle `q`-*Query-Parameter*-Werte (`foo` und `bar`) in einer Python-Liste – `list` – in ihrer *Pfadoperation-Funktion*, im Funktionsparameter `q`, Ãŧberreicht. +wÃŧrden Sie die mehreren `q`-*Query-Parameter*-Werte (`foo` und `bar`) in einer Python-`list` in Ihrer *Pfadoperation-Funktion* im *Funktionsparameter* `q` erhalten. -Die Response fÃŧr diese URL wäre also: +So wäre die Response zu dieser URL: ```JSON { @@ -364,27 +294,27 @@ Die Response fÃŧr diese URL wäre also: /// tip | Tipp -Um einen Query-Parameter vom Typ `list` zu deklarieren, wie im Beispiel oben, mÃŧssen Sie explizit `Query` verwenden, sonst wÃŧrde der Parameter als Requestbody interpretiert werden. +Um einen Query-Parameter mit einem Typ `list` zu deklarieren, wie im obigen Beispiel, mÃŧssen Sie explizit `Query` verwenden, da er andernfalls als Requestbody interpretiert wÃŧrde. /// -Die interaktive API-Dokumentation wird entsprechend aktualisiert und erlaubt jetzt mehrere Werte. +Die interaktive API-Dokumentation wird entsprechend aktualisiert, um mehrere Werte zu erlauben: -### Query-Parameter-Liste / Mehrere Werte mit Defaults +### Query-Parameter-Liste / Mehrere Werte mit Defaults { #query-parameter-list-multiple-values-with-defaults } -Und Sie kÃļnnen auch eine Default-`list`e von Werten definieren, wenn keine Ãŧbergeben werden: +Sie kÃļnnen auch eine Default-`list` von Werten definieren, wenn keine bereitgestellt werden: {* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *} -Wenn Sie auf: +Wenn Sie zu: ``` http://localhost:8000/items/ ``` -gehen, wird der Default fÃŧr `q` verwendet: `["foo", "bar"]`, und als Response erhalten Sie: +gehen, wird der Default fÃŧr `q` sein: `["foo", "bar"]`, und Ihre Response wird sein: ```JSON { @@ -395,9 +325,9 @@ gehen, wird der Default fÃŧr `q` verwendet: `["foo", "bar"]`, und als Response e } ``` -#### `list` alleine verwenden +#### Nur `list` verwenden { #using-just-list } -Sie kÃļnnen auch `list` direkt verwenden, anstelle von `List[str]` (oder `list[str]` in Python 3.9+): +Sie kÃļnnen auch `list` direkt verwenden, anstelle von `list[str]`: {* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *} @@ -405,35 +335,35 @@ Sie kÃļnnen auch `list` direkt verwenden, anstelle von `List[str]` (oder `list[s Beachten Sie, dass FastAPI in diesem Fall den Inhalt der Liste nicht ÃŧberprÃŧft. -Zum Beispiel wÃŧrde `List[int]` ÃŧberprÃŧfen (und dokumentieren) dass die Liste Ganzzahlen enthält. `list` alleine macht das nicht. +Zum Beispiel wÃŧrde `list[int]` ÃŧberprÃŧfen (und dokumentieren), dass der Inhalt der Liste Ganzzahlen sind. Aber `list` alleine wÃŧrde das nicht. /// -## Deklarieren von mehr Metadaten +## Mehr Metadaten deklarieren { #declare-more-metadata } -Sie kÃļnnen mehr Informationen zum Parameter hinzufÃŧgen. +Sie kÃļnnen mehr Informationen Ãŧber den Parameter hinzufÃŧgen. -Diese Informationen werden zur generierten OpenAPI hinzugefÃŧgt, und von den Dokumentations-Oberflächen und von externen Tools verwendet. +Diese Informationen werden in das generierte OpenAPI aufgenommen und von den Dokumentationsoberflächen und externen Tools verwendet. /// note | Hinweis -Beachten Sie, dass verschiedene Tools OpenAPI mÃļglicherweise unterschiedlich gut unterstÃŧtzen. +Beachten Sie, dass verschiedene Tools mÃļglicherweise unterschiedliche UnterstÃŧtzungslevels fÃŧr OpenAPI haben. -Einige kÃļnnten noch nicht alle zusätzlichen Informationen anzeigen, die Sie deklariert haben, obwohl in den meisten Fällen geplant ist, das fehlende Feature zu implementieren. +Einige davon kÃļnnten noch nicht alle zusätzlichen Informationen anzuzeigen, die Sie erklärten, obwohl in den meisten Fällen die fehlende Funktionalität bereits in der Entwicklung geplant ist. /// -Sie kÃļnnen einen Titel hinzufÃŧgen – `title`: +Sie kÃļnnen einen `title` hinzufÃŧgen: {* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *} -Und eine Beschreibung – `description`: +Und eine `description`: {* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *} -## Alias-Parameter +## Alias-Parameter { #alias-parameters } -Stellen Sie sich vor, der Parameter soll `item-query` sein. +Stellen Sie sich vor, Sie mÃļchten, dass der Parameter `item-query` ist. Wie in: @@ -443,37 +373,99 @@ http://127.0.0.1:8000/items/?item-query=foobaritems Aber `item-query` ist kein gÃŧltiger Name fÃŧr eine Variable in Python. -Am ähnlichsten wäre `item_query`. +Der am ähnlichsten wäre `item_query`. -Aber Sie mÃļchten dennoch exakt `item-query` verwenden. +Aber Sie benÃļtigen dennoch, dass er genau `item-query` ist ... -Dann kÃļnnen Sie einen `alias` deklarieren, und dieser Alias wird verwendet, um den Parameter-Wert zu finden: +Dann kÃļnnen Sie ein `alias` deklarieren, und dieser Alias wird verwendet, um den Parameterwert zu finden: {* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *} -## Parameter als deprecated ausweisen +## Parameter als deprecatet ausweisen { #deprecating-parameters } -Nehmen wir an, Sie mÃļgen diesen Parameter nicht mehr. +Nehmen wir an, Ihnen gefällt dieser Parameter nicht mehr. -Sie mÃŧssen ihn eine Weile dort belassen, weil Clients ihn benutzen, aber Sie mÃļchten, dass die Dokumentation klar anzeigt, dass er deprecated ist. +Sie mÃŧssen ihn eine Weile dort belassen, da es Clients gibt, die ihn verwenden, aber Sie mÃļchten, dass die Dokumentation ihn klar als deprecatet anzeigt. -In diesem Fall fÃŧgen Sie den Parameter `deprecated=True` zu `Query` hinzu. +Dann Ãŧbergeben Sie den Parameter `deprecated=True` an `Query`: {* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *} -Die Dokumentation wird das so anzeigen: +Die Dokumentation wird es so anzeigen: -## Parameter von OpenAPI ausschließen +## Parameter von OpenAPI ausschließen { #exclude-parameters-from-openapi } -Um einen Query-Parameter vom generierten OpenAPI-Schema auszuschließen (und daher von automatischen Dokumentations-Systemen), setzen Sie den Parameter `include_in_schema` in `Query` auf `False`. +Um einen Query-Parameter aus dem generierten OpenAPI-Schema auszuschließen (und somit aus den automatischen Dokumentationssystemen), setzen Sie den Parameter `include_in_schema` von `Query` auf `False`: {* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *} -## Zusammenfassung +## Benutzerdefinierte Validierung { #custom-validation } -Sie kÃļnnen zusätzliche Validierungen und Metadaten zu ihren Parametern hinzufÃŧgen. +Es kann Fälle geben, in denen Sie eine **benutzerdefinierte Validierung** durchfÃŧhren mÃŧssen, die nicht mit den oben gezeigten Parametern durchgefÃŧhrt werden kann. + +In diesen Fällen kÃļnnen Sie eine **benutzerdefinierte Validierungsfunktion** verwenden, die nach der normalen Validierung angewendet wird (z. B. nach der Validierung, dass der Wert ein `str` ist). + +Sie kÃļnnen dies mit Pydantic's `AfterValidator` innerhalb von `Annotated` erreichen. + +/// tip | Tipp + +Pydantic unterstÃŧtzt auch `BeforeValidator` und andere. 🤓 + +/// + +Zum Beispiel ÃŧberprÃŧft dieser benutzerdefinierte Validator, ob die Artikel-ID mit `isbn-` fÃŧr eine ISBN-Buchnummer oder mit `imdb-` fÃŧr eine IMDB-Film-URL-ID beginnt: + +{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *} + +/// info | Info + +Dies ist verfÃŧgbar seit Pydantic Version 2 oder hÃļher. 😎 + +/// + +/// tip | Tipp + +Wenn Sie irgendeine Art von Validierung durchfÃŧhren mÃŧssen, die eine Kommunikation mit einer **externen Komponente** erfordert, wie z. B. einer Datenbank oder einer anderen API, sollten Sie stattdessen **FastAPI-Abhängigkeiten** verwenden. Sie werden diese später kennenlernen. + +Diese benutzerdefinierten Validatoren sind fÃŧr Dinge gedacht, die einfach mit denselben **Daten** ÃŧberprÃŧft werden kÃļnnen, die im Request bereitgestellt werden. + +/// + +### Dieses Codebeispiel verstehen { #understand-that-code } + +Der wichtige Punkt ist einfach die Verwendung von **`AfterValidator` mit einer Funktion innerhalb von `Annotated`**. FÃŧhlen Sie sich frei, diesen Teil zu Ãŧberspringen. 🤸 + +--- + +Aber wenn Sie neugierig auf dieses spezielle Codebeispiel sind und immer noch Spaß haben, hier sind einige zusätzliche Details. + +#### Zeichenkette mit `value.startswith()` { #string-with-value-startswith } + +Haben Sie bemerkt? Eine Zeichenkette mit `value.startswith()` kann ein Tuple Ãŧbernehmen, und es wird jeden Wert im Tuple ÃŧberprÃŧfen: + +{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *} + +#### Ein zufälliges Item { #a-random-item } + +Mit `data.items()` erhalten wir ein iterierbares Objekt mit Tupeln, die SchlÃŧssel und Wert fÃŧr jedes Dictionary-Element enthalten. + +Wir konvertieren dieses iterierbare Objekt mit `list(data.items())` in eine richtige `list`. + +Dann kÃļnnen wir mit `random.choice()` einen **zufälligen Wert** aus der Liste erhalten, also bekommen wir ein Tuple mit `(id, name)`. Es wird etwas wie `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")` sein. + +Dann **weisen wir diese beiden Werte** des Tupels den Variablen `id` und `name` zu. + +Wenn der Benutzer also keine Artikel-ID bereitgestellt hat, erhält er trotzdem einen zufälligen Vorschlag. + +... wir tun all dies in einer **einzelnen einfachen Zeile**. đŸ¤¯ Lieben Sie nicht auch Python? 🐍 + +{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *} + +## Zusammenfassung { #recap } + +Sie kÃļnnen zusätzliche Validierungen und Metadaten fÃŧr Ihre Parameter deklarieren. Allgemeine Validierungen und Metadaten: @@ -482,12 +474,14 @@ Allgemeine Validierungen und Metadaten: * `description` * `deprecated` -Validierungen spezifisch fÃŧr Strings: +Validierungen, die spezifisch fÃŧr Strings sind: * `min_length` * `max_length` * `pattern` -In diesen Beispielen haben Sie gesehen, wie Sie Validierungen fÃŧr Strings hinzufÃŧgen. +Benutzerdefinierte Validierungen mit `AfterValidator`. -In den nächsten Kapiteln sehen wir, wie man Validierungen fÃŧr andere Typen hinzufÃŧgt, etwa fÃŧr Zahlen. +In diesen Beispielen haben Sie gesehen, wie Sie Validierungen fÃŧr `str`-Werte deklarieren. + +Sehen Sie sich die nächsten Kapitel an, um zu erfahren, wie Sie Validierungen fÃŧr andere Typen, wie z. B. Zahlen, deklarieren. diff --git a/docs/de/docs/tutorial/query-params.md b/docs/de/docs/tutorial/query-params.md index 0b0f473e2..e46f31ad0 100644 --- a/docs/de/docs/tutorial/query-params.md +++ b/docs/de/docs/tutorial/query-params.md @@ -1,10 +1,10 @@ -# Query-Parameter +# Query-Parameter { #query-parameters } -Wenn Sie in ihrer Funktion Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert. +Wenn Sie in Ihrer Funktion andere Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert. {* ../../docs_src/query_params/tutorial001.py hl[9] *} -Query-Parameter (Deutsch: Abfrage-Parameter) sind die SchlÃŧssel-Wert-Paare, die nach dem `?` in einer URL aufgelistet sind, getrennt durch `&`-Zeichen. +Die Query ist die Menge von SchlÃŧssel-Wert-Paaren, die nach dem `?` in einer URL folgen und durch `&`-Zeichen getrennt sind. Zum Beispiel sind in der URL: @@ -19,18 +19,18 @@ http://127.0.0.1:8000/items/?skip=0&limit=10 Da sie Teil der URL sind, sind sie „naturgemäß“ Strings. -Aber wenn Sie sie mit Python-Typen deklarieren (im obigen Beispiel als `int`), werden sie zu diesem Typ konvertiert, und gegen diesen validiert. +Aber wenn Sie sie mit Python-Typen deklarieren (im obigen Beispiel als `int`), werden sie zu diesem Typ konvertiert und gegen diesen validiert. -Die gleichen Prozesse, die fÃŧr Pfad-Parameter stattfinden, werden auch auf Query-Parameter angewendet: +Die gleichen Prozesse, die fÃŧr Pfad-Parameter gelten, werden auch auf Query-Parameter angewendet: * Editor UnterstÃŧtzung (natÃŧrlich) -* „Parsen“ der Daten +* Daten-„Parsen“ * Datenvalidierung * Automatische Dokumentation -## Defaultwerte +## Defaultwerte { #defaults } -Da Query-Parameter nicht ein festgelegter Teil des Pfades sind, kÃļnnen sie optional sein und Defaultwerte haben. +Da Query-Parameter kein fester Teil eines Pfades sind, kÃļnnen sie optional sein und Defaultwerte haben. Im obigen Beispiel haben sie die Defaultwerte `skip=0` und `limit=10`. @@ -52,28 +52,28 @@ Aber wenn Sie zum Beispiel zu: http://127.0.0.1:8000/items/?skip=20 ``` -gehen, werden die Parameter-Werte Ihrer Funktion sein: +gehen, werden die Parameterwerte Ihrer Funktion sein: * `skip=20`: da Sie das in der URL gesetzt haben * `limit=10`: weil das der Defaultwert ist -## Optionale Parameter +## Optionale Parameter { #optional-parameters } Auf die gleiche Weise kÃļnnen Sie optionale Query-Parameter deklarieren, indem Sie deren Defaultwert auf `None` setzen: {* ../../docs_src/query_params/tutorial002_py310.py hl[7] *} -In diesem Fall wird der Funktionsparameter `q` optional, und standardmäßig `None` sein. +In diesem Fall wird der Funktionsparameter `q` optional und standardmäßig `None` sein. -/// check +/// check | Testen Beachten Sie auch, dass **FastAPI** intelligent genug ist, um zu erkennen, dass `item_id` ein Pfad-Parameter ist und `q` keiner, daher muss letzteres ein Query-Parameter sein. /// -## Query-Parameter Typkonvertierung +## Query-Parameter Typkonvertierung { #query-parameter-type-conversion } -Sie kÃļnnen auch `bool`-Typen deklarieren und sie werden konvertiert: +Sie kÃļnnen auch `bool`-Typen deklarieren, und sie werden konvertiert: {* ../../docs_src/query_params/tutorial003_py310.py hl[7] *} @@ -109,9 +109,9 @@ http://127.0.0.1:8000/items/foo?short=yes gehen, oder zu irgendeiner anderen Variante der Groß-/Kleinschreibung (Alles groß, Anfangsbuchstabe groß, usw.), dann wird Ihre Funktion den Parameter `short` mit dem `bool`-Wert `True` sehen, ansonsten mit dem Wert `False`. -## Mehrere Pfad- und Query-Parameter +## Mehrere Pfad- und Query-Parameter { #multiple-path-and-query-parameters } -Sie kÃļnnen mehrere Pfad-Parameter und Query-Parameter gleichzeitig deklarieren, **FastAPI** weiß, was welches ist. +Sie kÃļnnen mehrere Pfad-Parameter und Query-Parameter gleichzeitig deklarieren, **FastAPI** weiß, welches welcher ist. Und Sie mÃŧssen sie auch nicht in einer spezifischen Reihenfolge deklarieren. @@ -119,7 +119,7 @@ Parameter werden anhand ihres Namens erkannt: {* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *} -## Erforderliche Query-Parameter +## Erforderliche Query-Parameter { #required-query-parameters } Wenn Sie einen Defaultwert fÃŧr Nicht-Pfad-Parameter deklarieren (Bis jetzt haben wir nur Query-Parameter gesehen), dann ist der Parameter nicht erforderlich. @@ -149,8 +149,7 @@ http://127.0.0.1:8000/items/foo-item "needy" ], "msg": "Field required", - "input": null, - "url": "https://errors.pydantic.dev/2.1/v/missing" + "input": null } ] } @@ -183,6 +182,6 @@ In diesem Fall gibt es drei Query-Parameter: /// tip | Tipp -Sie kÃļnnen auch `Enum`s verwenden, auf die gleiche Weise wie mit [Pfad-Parametern](path-params.md#vordefinierte-parameterwerte){.internal-link target=_blank}. +Sie kÃļnnen auch `Enum`s verwenden, auf die gleiche Weise wie mit [Pfad-Parametern](path-params.md#predefined-values){.internal-link target=_blank}. /// diff --git a/docs/de/docs/tutorial/request-files.md b/docs/de/docs/tutorial/request-files.md index 1f01b0d1e..0aee898b9 100644 --- a/docs/de/docs/tutorial/request-files.md +++ b/docs/de/docs/tutorial/request-files.md @@ -1,40 +1,44 @@ -# Dateien im Request +# Dateien im Request { #request-files } -Mit `File` kÃļnnen sie vom Client hochzuladende Dateien definieren. +Sie kÃļnnen Dateien, die vom Client hochgeladen werden, mithilfe von `File` definieren. -/// info +/// info | Info -Um hochgeladene Dateien zu empfangen, installieren Sie zuerst `python-multipart`. +Um hochgeladene Dateien zu empfangen, installieren Sie zuerst `python-multipart`. -Z. B. `pip install python-multipart`. +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und dann das Paket installieren, zum Beispiel: -Das, weil hochgeladene Dateien als „Formulardaten“ gesendet werden. +```console +$ pip install python-multipart +``` + +Das liegt daran, dass hochgeladene Dateien als „Formulardaten“ gesendet werden. /// -## `File` importieren +## `File` importieren { #import-file } Importieren Sie `File` und `UploadFile` von `fastapi`: {* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *} -## `File`-Parameter definieren +## `File`-Parameter definieren { #define-file-parameters } Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` und `Form` machen wÃŧrden: {* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *} -/// info +/// info | Info `File` ist eine Klasse, die direkt von `Form` erbt. -Aber erinnern Sie sich, dass, wenn Sie `Query`, `Path`, `File` und andere von `fastapi` importieren, diese tatsächlich Funktionen sind, welche spezielle Klassen zurÃŧckgeben +Aber erinnern Sie sich, dass, wenn Sie `Query`, `Path`, `File` und andere von `fastapi` importieren, diese tatsächlich Funktionen sind, welche spezielle Klassen zurÃŧckgeben. /// /// tip | Tipp -Um Dateibodys zu deklarieren, mÃŧssen Sie `File` verwenden, da diese Parameter sonst als Query-Parameter oder Body(-JSON)-Parameter interpretiert werden wÃŧrden. +Um Dateibodys zu deklarieren, mÃŧssen Sie `File` verwenden, da diese Parameter sonst als Query-Parameter oder Body (JSON)-Parameter interpretiert werden wÃŧrden. /// @@ -46,7 +50,7 @@ Bedenken Sie, dass das bedeutet, dass sich der gesamte Inhalt der Datei im Arbei Aber es gibt viele Fälle, in denen Sie davon profitieren, `UploadFile` zu verwenden. -## Datei-Parameter mit `UploadFile` +## Datei-Parameter mit `UploadFile` { #file-parameters-with-uploadfile } Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`: @@ -55,20 +59,20 @@ Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`: `UploadFile` zu verwenden, hat mehrere VorzÃŧge gegenÃŧber `bytes`: * Sie mÃŧssen `File()` nicht als Parameter-Defaultwert verwenden. -* Es wird eine „Spool“-Datei verwendet: +* Es wird eine „gespoolte“ Datei verwendet: * Eine Datei, die bis zu einem bestimmten GrÃļßen-Limit im Arbeitsspeicher behalten wird, und wenn das Limit Ãŧberschritten wird, auf der Festplatte gespeichert wird. * Das bedeutet, es wird fÃŧr große Dateien wie Bilder, Videos, große Binärdateien, usw. gut funktionieren, ohne den ganzen Arbeitsspeicher aufzubrauchen. * Sie kÃļnnen Metadaten aus der hochgeladenen Datei auslesen. -* Es hat eine file-like `async`hrone Schnittstelle. -* Es stellt ein tatsächliches Python-`SpooledTemporaryFile`-Objekt bereit, welches Sie direkt anderen Bibliotheken Ãŧbergeben kÃļnnen, die ein dateiartiges Objekt erwarten. +* Es hat eine dateiartige `async`hrone Schnittstelle. +* Es stellt ein tatsächliches Python-`SpooledTemporaryFile`-Objekt bereit, welches Sie direkt anderen Bibliotheken Ãŧbergeben kÃļnnen, die ein dateiartiges Objekt erwarten. -### `UploadFile` +### `UploadFile` { #uploadfile } `UploadFile` hat die folgenden Attribute: * `filename`: Ein `str` mit dem ursprÃŧnglichen Namen der hochgeladenen Datei (z. B. `meinbild.jpg`). * `content_type`: Ein `str` mit dem Inhaltstyp (MIME-Typ / Medientyp) (z. B. `image/jpeg`). -* `file`: Ein `SpooledTemporaryFile` (ein file-like Objekt). Das ist das tatsächliche Python-Objekt, das Sie direkt anderen Funktionen oder Bibliotheken Ãŧbergeben kÃļnnen, welche ein „file-like“-Objekt erwarten. +* `file`: Ein `SpooledTemporaryFile` (ein dateiartiges Objekt). Das ist das tatsächliche Python-Objekt, das Sie direkt anderen Funktionen oder Bibliotheken Ãŧbergeben kÃļnnen, welche ein „file-like“-Objekt erwarten. `UploadFile` hat die folgenden `async`hronen Methoden. Sie alle rufen die entsprechenden Methoden des darunterliegenden Datei-Objekts auf (wobei intern `SpooledTemporaryFile` verwendet wird). @@ -79,7 +83,7 @@ Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`: * Das ist besonders dann nÃŧtzlich, wenn Sie `await myfile.read()` einmal ausfÃŧhren und dann diese Inhalte erneut auslesen mÃŧssen. * `close()`: Schließt die Datei. -Da alle diese Methoden `async`hron sind, mÃŧssen Sie sie `await`en („erwarten“). +Da alle diese Methoden `async`hron sind, mÃŧssen Sie sie „await“en („erwarten“). Zum Beispiel kÃļnnen Sie innerhalb einer `async` *Pfadoperation-Funktion* den Inhalt wie folgt auslesen: @@ -105,9 +109,9 @@ Wenn Sie die `async`-Methoden verwenden, fÃŧhrt **FastAPI** die Datei-Methoden i /// -## Was sind „Formulardaten“ +## Was sind „Formulardaten“ { #what-is-form-data } -HTML-Formulare (`
`) senden die Daten in einer „speziellen“ Kodierung zum Server, welche sich von JSON unterscheidet. +Der Weg, wie HTML-Formulare (`
`) die Daten zum Server senden, verwendet normalerweise eine „spezielle“ Kodierung fÃŧr diese Daten. Diese unterscheidet sich von JSON. **FastAPI** stellt sicher, dass diese Daten korrekt ausgelesen werden, statt JSON zu erwarten. @@ -117,31 +121,31 @@ Daten aus Formularen werden, wenn es keine Dateien sind, normalerweise mit dem < Sollte das Formular aber Dateien enthalten, dann werden diese mit `multipart/form-data` kodiert. Wenn Sie `File` verwenden, wird **FastAPI** wissen, dass es die Dateien vom korrekten Teil des Bodys holen muss. -Wenn Sie mehr Ãŧber Formularfelder und ihre Kodierungen lesen mÃļchten, besuchen Sie die MDN-Webdokumentation fÃŧr POST. +Wenn Sie mehr Ãŧber diese Kodierungen und Formularfelder lesen mÃļchten, besuchen Sie die MDN-Webdokumentation fÃŧr POST. /// /// warning | Achtung -Sie kÃļnnen mehrere `File`- und `Form`-Parameter in einer *Pfadoperation* deklarieren, aber Sie kÃļnnen nicht gleichzeitig auch `Body`-Felder deklarieren, welche Sie als JSON erwarten, da der Request den Body mittels `multipart/form-data` statt `application/json` kodiert. +Sie kÃļnnen mehrere `File`- und `Form`-Parameter in einer *Pfadoperation* deklarieren, aber Sie kÃļnnen nicht gleichzeitig auch `Body`-Felder deklarieren, welche Sie als JSON erwarten, da der Request den Body mittels `multipart/form-data` statt `application/json` kodiert. Das ist keine Limitation von **FastAPI**, sondern Teil des HTTP-Protokolls. /// -## Optionaler Datei-Upload +## Optionaler Datei-Upload { #optional-file-upload } Sie kÃļnnen eine Datei optional machen, indem Sie Standard-Typannotationen verwenden und den Defaultwert auf `None` setzen: {* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *} -## `UploadFile` mit zusätzlichen Metadaten +## `UploadFile` mit zusätzlichen Metadaten { #uploadfile-with-additional-metadata } -Sie kÃļnnen auch `File()` zusammen mit `UploadFile` verwenden, um zum Beispiel zusätzliche Metadaten zu setzen: +Sie kÃļnnen auch `File()` mit `UploadFile` verwenden, um zum Beispiel zusätzliche Metadaten zu setzen: {* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *} -## Mehrere Datei-Uploads +## Mehrere Datei-Uploads { #multiple-file-uploads } Es ist auch mÃļglich, mehrere Dateien gleichzeitig hochzuladen. @@ -151,22 +155,22 @@ Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s: {* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *} -Sie erhalten, wie deklariert, eine `list`e von `bytes` oder `UploadFile`s. +Sie erhalten, wie deklariert, eine `list` von `bytes` oder `UploadFile`s. /// note | Technische Details Sie kÃļnnen auch `from starlette.responses import HTMLResponse` verwenden. -**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. +**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Die meisten verfÃŧgbaren Responses kommen aber direkt von Starlette. /// -### Mehrere Datei-Uploads mit zusätzlichen Metadaten +### Mehrere Datei-Uploads mit zusätzlichen Metadaten { #multiple-file-uploads-with-additional-metadata } Und so wie zuvor kÃļnnen Sie `File()` verwenden, um zusätzliche Parameter zu setzen, sogar fÃŧr `UploadFile`: {* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *} -## Zusammenfassung +## Zusammenfassung { #recap } Verwenden Sie `File`, `bytes` und `UploadFile`, um hochladbare Dateien im Request zu deklarieren, die als Formulardaten gesendet werden. diff --git a/docs/de/docs/tutorial/request-form-models.md b/docs/de/docs/tutorial/request-form-models.md new file mode 100644 index 000000000..fbc6c094c --- /dev/null +++ b/docs/de/docs/tutorial/request-form-models.md @@ -0,0 +1,78 @@ +# Formularmodelle { #form-models } + +Sie kÃļnnen **Pydantic-Modelle** verwenden, um **Formularfelder** in FastAPI zu deklarieren. + +/// info | Info + +Um Formulare zu verwenden, installieren Sie zuerst `python-multipart`. + +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und es dann installieren, zum Beispiel: + +```console +$ pip install python-multipart +``` + +/// + +/// note | Hinweis + +Dies wird seit FastAPI Version `0.113.0` unterstÃŧtzt. 🤓 + +/// + +## Pydantic-Modelle fÃŧr Formulare { #pydantic-models-for-forms } + +Sie mÃŧssen nur ein **Pydantic-Modell** mit den Feldern deklarieren, die Sie als **Formularfelder** erhalten mÃļchten, und dann den Parameter als `Form` deklarieren: + +{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *} + +**FastAPI** wird die Daten fÃŧr **jedes Feld** aus den **Formulardaten** im Request **extrahieren** und Ihnen das von Ihnen definierte Pydantic-Modell Ãŧbergeben. + +## Die Dokumentation testen { #check-the-docs } + +Sie kÃļnnen dies in der Dokumentations-UI unter `/docs` testen: + +
+ +
+ +## Zusätzliche Formularfelder verbieten { #forbid-extra-form-fields } + +In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) mÃļchten Sie mÃļglicherweise die Formularfelder auf nur diejenigen beschränken, die im Pydantic-Modell deklariert sind, und jegliche **zusätzlichen** Felder **verbieten**. + +/// note | Hinweis + +Dies wird seit FastAPI Version `0.114.0` unterstÃŧtzt. 🤓 + +/// + +Sie kÃļnnen die Modellkonfiguration von Pydantic verwenden, um jegliche `extra` Felder zu `verbieten`: + +{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *} + +Wenn ein Client versucht, einige zusätzliche Daten zu senden, erhält er eine **Error-Response**. + +Zum Beispiel, wenn der Client versucht, folgende Formularfelder zu senden: + +* `username`: `Rick` +* `password`: `Portal Gun` +* `extra`: `Mr. Poopybutthole` + +erhält er eine Error-Response, die ihm mitteilt, dass das Feld `extra` nicht erlaubt ist: + +```json +{ + "detail": [ + { + "type": "extra_forbidden", + "loc": ["body", "extra"], + "msg": "Extra inputs are not permitted", + "input": "Mr. Poopybutthole" + } + ] +} +``` + +## Zusammenfassung { #summary } + +Sie kÃļnnen Pydantic-Modelle verwenden, um Formularfelder in FastAPI zu deklarieren. 😎 diff --git a/docs/de/docs/tutorial/request-forms-and-files.md b/docs/de/docs/tutorial/request-forms-and-files.md index 3c5e11adf..cda38bcc2 100644 --- a/docs/de/docs/tutorial/request-forms-and-files.md +++ b/docs/de/docs/tutorial/request-forms-and-files.md @@ -1,22 +1,26 @@ -# Formulardaten und Dateien im Request +# Formulardaten und Dateien im Request { #request-forms-and-files } Sie kÃļnnen gleichzeitig Dateien und Formulardaten mit `File` und `Form` definieren. -/// info +/// info | Info -Um hochgeladene Dateien und/oder Formulardaten zu empfangen, installieren Sie zuerst `python-multipart`. +Um hochgeladene Dateien und/oder Formulardaten zu empfangen, installieren Sie zuerst `python-multipart`. -Z. B. `pip install python-multipart`. +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, diese aktivieren und es dann installieren, z. B.: + +```console +$ pip install python-multipart +``` /// -## `File` und `Form` importieren +## `File` und `Form` importieren { #import-file-and-form } {* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *} -## `File` und `Form`-Parameter definieren +## `File` und `Form`-Parameter definieren { #define-file-and-form-parameters } -Erstellen Sie Datei- und Formularparameter, so wie Sie es auch mit `Body` und `Query` machen wÃŧrden: +Erstellen Sie Datei- und Formularparameter, so wie Sie es auch mit `Body` oder `Query` machen wÃŧrden: {* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *} @@ -26,12 +30,12 @@ Und Sie kÃļnnen einige der Dateien als `bytes` und einige als `UploadFile` dekla /// warning | Achtung -Sie kÃļnnen mehrere `File`- und `Form`-Parameter in einer *Pfadoperation* deklarieren, aber Sie kÃļnnen nicht gleichzeitig auch `Body`-Felder deklarieren, welche Sie als JSON erwarten, da der Request den Body mittels `multipart/form-data` statt `application/json` kodiert. +Sie kÃļnnen mehrere `File`- und `Form`-Parameter in einer *Pfadoperation* deklarieren, aber Sie kÃļnnen nicht auch `Body`-Felder deklarieren, die Sie als JSON erwarten, da der Body des Request mittels `multipart/form-data` statt `application/json` kodiert sein wird. Das ist keine Limitation von **FastAPI**, sondern Teil des HTTP-Protokolls. /// -## Zusammenfassung +## Zusammenfassung { #recap } Verwenden Sie `File` und `Form` zusammen, wenn Sie Daten und Dateien zusammen im selben Request empfangen mÃŧssen. diff --git a/docs/de/docs/tutorial/request-forms.md b/docs/de/docs/tutorial/request-forms.md index 2f88caaba..5c2ace67b 100644 --- a/docs/de/docs/tutorial/request-forms.md +++ b/docs/de/docs/tutorial/request-forms.md @@ -1,34 +1,38 @@ -# Formulardaten +# Formulardaten { #form-data } Wenn Sie Felder aus Formularen statt JSON empfangen mÃŧssen, kÃļnnen Sie `Form` verwenden. -/// info +/// info | Info -Um Formulare zu verwenden, installieren Sie zuerst `python-multipart`. +Um Formulare zu verwenden, installieren Sie zuerst `python-multipart`. -Z. B. `pip install python-multipart`. +Erstellen Sie unbedingt eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank}, aktivieren Sie diese und installieren Sie dann das Paket, zum Beispiel: + +```console +$ pip install python-multipart +``` /// -## `Form` importieren +## `Form` importieren { #import-form } Importieren Sie `Form` von `fastapi`: {* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *} -## `Form`-Parameter definieren +## `Form`-Parameter definieren { #define-form-parameters } Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` und `Query` machen wÃŧrden: {* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *} -Zum Beispiel stellt eine der MÃļglichkeiten, die OAuth2 Spezifikation zu verwenden (genannt „password flow“), die Bedingung, einen `username` und ein `password` als Formularfelder zu senden. +Zum Beispiel stellt eine der MÃļglichkeiten, die OAuth2-Spezifikation zu verwenden (genannt „password flow“), die Bedingung, einen `username` und ein `password` als Formularfelder zu senden. Die Spec erfordert, dass die Felder exakt `username` und `password` genannt werden und als Formularfelder, nicht JSON, gesendet werden. Mit `Form` haben Sie die gleichen KonfigurationsmÃļglichkeiten wie mit `Body` (und `Query`, `Path`, `Cookie`), inklusive Validierung, Beispielen, einem Alias (z. B. `user-name` statt `username`), usw. -/// info +/// info | Info `Form` ist eine Klasse, die direkt von `Body` erbt. @@ -36,34 +40,34 @@ Mit `Form` haben Sie die gleichen KonfigurationsmÃļglichkeiten wie mit `Body` (u /// tip | Tipp -Um Formularbodys zu deklarieren, verwenden Sie explizit `Form`, da diese Parameter sonst als Query-Parameter oder Body(-JSON)-Parameter interpretiert werden wÃŧrden. +Um Formularbodys zu deklarieren, verwenden Sie explizit `Form`, da diese Parameter sonst als Query-Parameter oder Body (JSON)-Parameter interpretiert werden wÃŧrden. /// -## Über „Formularfelder“ +## Über „Formularfelder“ { #about-form-fields } -HTML-Formulare (`
`) senden die Daten in einer „speziellen“ Kodierung zum Server, welche sich von JSON unterscheidet. +HTML-Formulare (`
`) senden die Daten in einer „speziellen“ Kodierung zum Server, die sich von JSON unterscheidet. **FastAPI** stellt sicher, dass diese Daten korrekt ausgelesen werden, statt JSON zu erwarten. /// note | Technische Details -Daten aus Formularen werden normalerweise mit dem „media type“ `application/x-www-form-urlencoded` kodiert. +Daten aus Formularen werden normalerweise mit dem „media type“ `application/x-www-form-urlencoded` kodiert. Wenn das Formular stattdessen Dateien enthält, werden diese mit `multipart/form-data` kodiert. Im nächsten Kapitel erfahren Sie mehr Ãŧber die Handhabung von Dateien. -Wenn Sie mehr Ãŧber Formularfelder und ihre Kodierungen lesen mÃļchten, besuchen Sie die MDN-Webdokumentation fÃŧr POST. +Wenn Sie mehr Ãŧber Formularfelder und ihre Kodierungen lesen mÃļchten, besuchen Sie die MDN-Webdokumentation fÃŧr POST. /// /// warning | Achtung -Sie kÃļnnen mehrere `Form`-Parameter in einer *Pfadoperation* deklarieren, aber Sie kÃļnnen nicht gleichzeitig auch `Body`-Felder deklarieren, welche Sie als JSON erwarten, da der Request den Body mittels `application/x-www-form-urlencoded` statt `application/json` kodiert. +Sie kÃļnnen mehrere `Form`-Parameter in einer *Pfadoperation* deklarieren, aber Sie kÃļnnen nicht gleichzeitig auch `Body`-Felder deklarieren, welche Sie als JSON erwarten, da der Request den Body mittels `application/x-www-form-urlencoded` statt `application/json` kodiert. Das ist keine Limitation von **FastAPI**, sondern Teil des HTTP-Protokolls. /// -## Zusammenfassung +## Zusammenfassung { #recap } Verwenden Sie `Form`, um Eingabe-Parameter fÃŧr Formulardaten zu deklarieren. diff --git a/docs/de/docs/tutorial/response-model.md b/docs/de/docs/tutorial/response-model.md index faf9be516..7b77125cb 100644 --- a/docs/de/docs/tutorial/response-model.md +++ b/docs/de/docs/tutorial/response-model.md @@ -1,6 +1,6 @@ -# Responsemodell – RÃŧckgabetyp +# Responsemodell – RÃŧckgabetyp { #response-model-return-type } -Sie kÃļnnen den Typ der Response deklarieren, indem Sie den **RÃŧckgabetyp** der *Pfadoperation* annotieren. +Sie kÃļnnen den Typ der Response deklarieren, indem Sie den **RÃŧckgabetyp** der *Pfadoperation* annotieren. Hierbei kÃļnnen Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten von Funktions-**Parametern** machen; verwenden Sie Pydantic-Modelle, Listen, Dicts und skalare Werte wie Nummern, Booleans, usw. @@ -9,7 +9,7 @@ Hierbei kÃļnnen Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten FastAPI wird diesen RÃŧckgabetyp verwenden, um: * Die zurÃŧckzugebenden Daten zu **validieren**. - * Wenn die Daten ungÃŧltig sind (Sie haben z. B. ein Feld vergessen), bedeutet das, *Ihr* Anwendungscode ist fehlerhaft, er gibt nicht zurÃŧck, was er sollte, und daher wird ein Server-Error ausgegeben, statt falscher Daten. So kÃļnnen Sie und ihre Clients sicher sein, dass diese die erwarteten Daten, in der richtigen Form erhalten. + * Wenn die Daten ungÃŧltig sind (Sie haben z. B. ein Feld vergessen), bedeutet das, *Ihr* Anwendungscode ist fehlerhaft, er gibt nicht zurÃŧck, was er sollte, und daher wird ein Server-Error ausgegeben, statt falscher Daten. So kÃļnnen Sie und Ihre Clients sicher sein, dass diese die erwarteten Daten, in der richtigen Form erhalten. * In der OpenAPI *Pfadoperation* ein **JSON-Schema** fÃŧr die Response hinzuzufÃŧgen. * Dieses wird von der **automatischen Dokumentation** verwendet. * Es wird auch von automatisch Client-Code-generierenden Tools verwendet. @@ -19,11 +19,11 @@ Aber am wichtigsten: * Es wird die Ausgabedaten auf das **limitieren und filtern**, was im RÃŧckgabetyp definiert ist. * Das ist insbesondere fÃŧr die **Sicherheit** wichtig, mehr dazu unten. -## `response_model`-Parameter +## `response_model`-Parameter { #response-model-parameter } Es gibt Fälle, da mÃļchten oder mÃŧssen Sie Daten zurÃŧckgeben, die nicht genau dem entsprechen, was der Typ deklariert. -Zum Beispiel kÃļnnten Sie **ein Dict zurÃŧckgeben** wollen, oder ein Datenbank-Objekt, aber **es als Pydantic-Modell deklarieren**. Auf diese Weise Ãŧbernimmt das Pydantic-Modell alle Datendokumentation, -validierung, usw. fÃŧr das Objekt, welches Sie zurÃŧckgeben (z. B. ein Dict oder ein Datenbank-Objekt). +Zum Beispiel kÃļnnten Sie **ein Dictionary zurÃŧckgeben** wollen, oder ein Datenbank-Objekt, aber **es als Pydantic-Modell deklarieren**. Auf diese Weise Ãŧbernimmt das Pydantic-Modell alle Datendokumentation, -validierung, usw. fÃŧr das Objekt, welches Sie zurÃŧckgeben (z. B. ein Dictionary oder ein Datenbank-Objekt). WÃŧrden Sie eine hierfÃŧr eine RÃŧckgabetyp-Annotation verwenden, dann wÃŧrden Tools und Editoren (korrekterweise) Fehler ausgeben, die Ihnen sagen, dass Ihre Funktion einen Typ zurÃŧckgibt (z. B. ein Dict), der sich unterscheidet von dem, was Sie deklariert haben (z. B. ein Pydantic-Modell). @@ -41,7 +41,7 @@ Sie kÃļnnen `response_model` in jeder mÃļglichen *Pfadoperation* verwenden: /// note | Hinweis -Beachten Sie, dass `response_model` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht der *Pfadoperation-Funktion*, so wie die anderen Parameter. +Beachten Sie, dass `response_model` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht der *Pfadoperation-Funktion*, so wie die anderen Parameter und der Body. /// @@ -51,32 +51,41 @@ FastAPI wird dieses `response_model` nehmen, um die Daten zu dokumentieren, vali /// tip | Tipp -Wenn Sie in Ihrem Editor strikte Typchecks haben, mypy, usw., kÃļnnen Sie den Funktions-RÃŧckgabetyp als `Any` deklarieren. +Wenn Sie in Ihrem Editor strikte Typchecks haben, mypy, usw., kÃļnnen Sie den Funktions-RÃŧckgabetyp als `Any` deklarieren. So sagen Sie dem Editor, dass Sie absichtlich *irgendetwas* zurÃŧckgeben. Aber FastAPI wird trotzdem die Dokumentation, Validierung, Filterung, usw. der Daten Ãŧbernehmen, via `response_model`. /// -### `response_model`-Priorität +### `response_model`-Priorität { #response-model-priority } Wenn sowohl RÃŧckgabetyp als auch `response_model` deklariert sind, hat `response_model` die Priorität und wird von FastAPI bevorzugt verwendet. -So kÃļnnen Sie korrekte Typannotationen zu ihrer Funktion hinzufÃŧgen, die von ihrem Editor und Tools wie mypy verwendet werden. Und dennoch Ãŧbernimmt FastAPI die Validierung und Dokumentation, usw., der Daten anhand von `response_model`. +So kÃļnnen Sie korrekte Typannotationen zu Ihrer Funktion hinzufÃŧgen, die von Ihrem Editor und Tools wie mypy verwendet werden. Und dennoch Ãŧbernimmt FastAPI die Validierung und Dokumentation, usw., der Daten anhand von `response_model`. -Sie kÃļnnen auch `response_model=None` verwenden, um das Erstellen eines Responsemodells fÃŧr diese *Pfadoperation* zu unterbinden. Sie kÃļnnten das tun wollen, wenn sie Dinge annotieren, die nicht gÃŧltige Pydantic-Felder sind. Ein Beispiel dazu werden Sie in einer der Abschnitte unten sehen. +Sie kÃļnnen auch `response_model=None` verwenden, um das Erstellen eines Responsemodells fÃŧr diese *Pfadoperation* zu unterbinden. Sie kÃļnnten das tun wollen, wenn Sie Dinge annotieren, die nicht gÃŧltige Pydantic-Felder sind. Ein Beispiel dazu werden Sie in einer der Abschnitte unten sehen. -## Dieselben Eingabedaten zurÃŧckgeben +## Dieselben Eingabedaten zurÃŧckgeben { #return-the-same-input-data } Im Folgenden deklarieren wir ein `UserIn`-Modell; es enthält ein Klartext-Passwort: {* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *} -/// info +/// info | Info Um `EmailStr` zu verwenden, installieren Sie zuerst `email-validator`. -Z. B. `pip install email-validator` -oder `pip install pydantic[email]`. +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und es dann installieren, zum Beispiel: + +```console +$ pip install email-validator +``` + +oder mit: + +```console +$ pip install "pydantic[email]" +``` /// @@ -96,7 +105,7 @@ Speichern Sie niemals das Klartext-Passwort eines Benutzers, oder versenden Sie /// -## Ausgabemodell hinzufÃŧgen +## Ausgabemodell hinzufÃŧgen { #add-an-output-model } Wir kÃļnnen stattdessen ein Eingabemodell mit dem Klartext-Passwort, und ein Ausgabemodell ohne das Passwort erstellen: @@ -112,7 +121,7 @@ Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zur Darum wird **FastAPI** sich darum kÃŧmmern, dass alle Daten, die nicht im Ausgabemodell deklariert sind, herausgefiltert werden (mittels Pydantic). -### `response_model` oder RÃŧckgabewert +### `response_model` oder RÃŧckgabewert { #response-model-or-return-type } Da unsere zwei Modelle in diesem Fall unterschiedlich sind, wÃŧrde, wenn wir den RÃŧckgabewert der Funktion als `UserOut` deklarieren, der Editor sich beschweren, dass wir einen ungÃŧltigen Typ zurÃŧckgeben, weil das unterschiedliche Klassen sind. @@ -120,11 +129,11 @@ Darum mÃŧssen wir es in diesem Fall im `response_model`-Parameter deklarieren. ... aber lesen Sie weiter, um zu sehen, wie man das anders lÃļsen kann. -## RÃŧckgabewert und Datenfilterung +## RÃŧckgabewert und Datenfilterung { #return-type-and-data-filtering } -FÃŧhren wir unser vorheriges Beispiel fort. Wir wollten **die Funktion mit einem Typ annotieren**, aber etwas zurÃŧckgeben, das **weniger Daten** enthält. +FÃŧhren wir unser vorheriges Beispiel fort. Wir wollten **die Funktion mit einem Typ annotieren**, aber wir wollten in der Funktion tatsächlich etwas zurÃŧckgeben, das **mehr Daten** enthält. -Wir mÃļchten auch, dass FastAPI die Daten weiterhin, dem Responsemodell entsprechend, **filtert**. +Wir mÃļchten, dass FastAPI die Daten weiterhin mithilfe des Responsemodells **filtert**. Selbst wenn die Funktion mehr Daten zurÃŧckgibt, soll die Response nur die Felder enthalten, die im Responsemodell deklariert sind. Im vorherigen Beispiel mussten wir den `response_model`-Parameter verwenden, weil die Klassen unterschiedlich waren. Das bedeutet aber auch, wir bekommen keine UnterstÃŧtzung vom Editor und anderen Tools, die den Funktions-RÃŧckgabewert ÃŧberprÃŧfen. @@ -138,17 +147,17 @@ Damit erhalten wir Tool-UnterstÃŧtzung, vom Editor und mypy, da dieser Code hins Wie funktioniert das? Schauen wir uns das mal an. 🤓 -### Typannotationen und Tooling +### Typannotationen und Tooling { #type-annotations-and-tooling } Sehen wir uns zunächst an, wie Editor, mypy und andere Tools dies sehen wÃŧrden. -`BaseUser` verfÃŧgt Ãŧber die Basis-Felder. Dann erbt `UserIn` von `BaseUser` und fÃŧgt das Feld `Passwort` hinzu, sodass dass es nun alle Felder beider Modelle hat. +`BaseUser` verfÃŧgt Ãŧber die Basis-Felder. Dann erbt `UserIn` von `BaseUser` und fÃŧgt das Feld `password` hinzu, sodass es nun alle Felder beider Modelle hat. Wir annotieren den FunktionsrÃŧckgabetyp als `BaseUser`, geben aber tatsächlich eine `UserIn`-Instanz zurÃŧck. FÃŧr den Editor, mypy und andere Tools ist das kein Problem, da `UserIn` eine Unterklasse von `BaseUser` ist (Salopp: `UserIn` ist ein `BaseUser`). Es handelt sich um einen *gÃŧltigen* Typ, solange irgendetwas Ãŧberreicht wird, das ein `BaseUser` ist. -### FastAPI Datenfilterung +### FastAPI Datenfilterung { #fastapi-data-filtering } FastAPI seinerseits wird den RÃŧckgabetyp sehen und sicherstellen, dass das, was zurÃŧckgegeben wird, **nur** diejenigen Felder enthält, welche im Typ deklariert sind. @@ -156,7 +165,7 @@ FastAPI macht intern mehrere Dinge mit Pydantic, um sicherzustellen, dass obige Auf diese Weise erhalten Sie das beste beider Welten: Sowohl Typannotationen mit **Tool-UnterstÃŧtzung** als auch **Datenfilterung**. -## Anzeige in der Dokumentation +## Anzeige in der Dokumentation { #see-it-in-the-docs } Wenn Sie sich die automatische Dokumentation betrachten, kÃļnnen Sie sehen, dass Eingabe- und Ausgabemodell beide ihr eigenes JSON-Schema haben: @@ -166,11 +175,11 @@ Und beide Modelle werden auch in der interaktiven API-Dokumentation verwendet: -## Andere RÃŧckgabetyp-Annotationen +## Andere RÃŧckgabetyp-Annotationen { #other-return-type-annotations } Es kann Fälle geben, bei denen Sie etwas zurÃŧckgeben, das kein gÃŧltiges Pydantic-Feld ist, und Sie annotieren es in der Funktion nur, um UnterstÃŧtzung von Tools zu erhalten (Editor, mypy, usw.). -### Eine Response direkt zurÃŧckgeben +### Eine Response direkt zurÃŧckgeben { #return-a-response-directly } Der häufigste Anwendungsfall ist, wenn Sie [eine Response direkt zurÃŧckgeben, wie es später im Handbuch fÃŧr fortgeschrittene Benutzer erläutert wird](../advanced/response-directly.md){.internal-link target=_blank}. @@ -180,7 +189,7 @@ Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Und Tools werden auch glÃŧcklich sein, weil sowohl `RedirectResponse` als auch `JSONResponse` Unterklassen von `Response` sind, die Typannotation ist daher korrekt. -### Eine Unterklasse von Response annotieren +### Eine Unterklasse von Response annotieren { #annotate-a-response-subclass } Sie kÃļnnen auch eine Unterklasse von `Response` in der Typannotation verwenden. @@ -188,17 +197,17 @@ Sie kÃļnnen auch eine Unterklasse von `Response` in der Typannotation verwenden. Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kÃŧmmert. -### UngÃŧltige RÃŧckgabetyp-Annotationen +### UngÃŧltige RÃŧckgabetyp-Annotationen { #invalid-return-type-annotations } Aber wenn Sie ein beliebiges anderes Objekt zurÃŧckgeben, das kein gÃŧltiger Pydantic-Typ ist (z. B. ein Datenbank-Objekt), und Sie annotieren es so in der Funktion, wird FastAPI versuchen, ein Pydantic-Responsemodell von dieser Typannotation zu erstellen, und scheitern. -Das gleiche wird passieren, wenn Sie eine Union mehrerer Typen haben, und einer oder mehrere sind nicht gÃŧltige Pydantic-Typen. Zum Beispiel funktioniert folgendes nicht đŸ’Ĩ: +Das gleiche wird passieren, wenn Sie eine Union mehrerer Typen haben, und einer oder mehrere sind nicht gÃŧltige Pydantic-Typen. Zum Beispiel funktioniert folgendes nicht đŸ’Ĩ: {* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *} ... das scheitert, da die Typannotation kein Pydantic-Typ ist, und auch keine einzelne `Response`-Klasse, oder -Unterklasse, es ist eine Union (eines von beiden) von `Response` und `dict`. -### Responsemodell deaktivieren +### Responsemodell deaktivieren { #disable-response-model } Beim Beispiel oben fortsetzend, mÃļgen Sie vielleicht die standardmäßige Datenvalidierung, -Dokumentation, -Filterung, usw., die von FastAPI durchgefÃŧhrt wird, nicht haben. @@ -210,7 +219,7 @@ In diesem Fall kÃļnnen Sie die Generierung des Responsemodells abschalten, indem Das bewirkt, dass FastAPI die Generierung des Responsemodells unterlässt, und damit kÃļnnen Sie jede gewÃŧnschte RÃŧckgabetyp-Annotation haben, ohne dass es Ihre FastAPI-Anwendung beeinflusst. 🤓 -## Parameter fÃŧr die Enkodierung des Responsemodells +## Parameter fÃŧr die Enkodierung des Responsemodells { #response-model-encoding-parameters } Ihr Responsemodell kÃļnnte Defaultwerte haben, wie: @@ -224,7 +233,7 @@ Aber Sie mÃļchten diese vielleicht vom Resultat ausschließen, wenn Sie gar nich Wenn Sie zum Beispiel Modelle mit vielen optionalen Attributen in einer NoSQL-Datenbank haben, und Sie mÃļchten nicht ellenlange JSON-Responses voller Defaultwerte senden. -### Den `response_model_exclude_unset`-Parameter verwenden +### Den `response_model_exclude_unset`-Parameter verwenden { #use-the-response-model-exclude-unset-parameter } Sie kÃļnnen den *Pfadoperation-Dekorator*-Parameter `response_model_exclude_unset=True` setzen: @@ -241,21 +250,21 @@ Wenn Sie also den Artikel mit der ID `foo` bei der *Pfadoperation* anfragen, wir } ``` -/// info +/// info | Info -In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie deprecated (aber immer noch unterstÃŧtzt) und in `.model_dump()` umbenannt. +In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie deprecatet (aber immer noch unterstÃŧtzt) und in `.model_dump()` umbenannt. Die Beispiele hier verwenden `.dict()` fÃŧr die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden kÃļnnen. /// -/// info +/// info | Info FastAPI verwendet `.dict()` von Pydantic Modellen, mit dessen `exclude_unset`-Parameter, um das zu erreichen. /// -/// info +/// info | Info Sie kÃļnnen auch: @@ -266,9 +275,9 @@ verwenden, wie in der Response mit dem Parameter `status_code` in jeder der *Pfadoperationen* deklarieren: * `@app.get()` * `@app.post()` @@ -12,90 +12,90 @@ So wie ein Responsemodell, kÃļnnen Sie auch einen HTTP-Statuscode fÃŧr die Respo /// note | Hinweis -Beachten Sie, dass `status_code` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht der *Pfadoperation-Funktion*, so wie die anderen Parameter und der Body. +Beachten Sie, dass `status_code` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht der *Pfadoperation-Funktion*, wie alle anderen Parameter und der Body. /// Dem `status_code`-Parameter wird eine Zahl mit dem HTTP-Statuscode Ãŧbergeben. -/// info +/// info | Info -Alternativ kann `status_code` auch ein `IntEnum` erhalten, so wie Pythons `http.HTTPStatus`. +Alternativ kann `status_code` auch ein `IntEnum` erhalten, wie etwa Pythons `http.HTTPStatus`. /// -Das wird: +Dies wird: * Diesen Statuscode mit der Response zurÃŧcksenden. -* Ihn als solchen im OpenAPI-Schema dokumentieren (und somit in den Benutzeroberflächen): +* Diesen im OpenAPI-Schema dokumentieren (und somit in den Benutzeroberflächen): /// note | Hinweis -Einige Responsecodes (siehe nächster Abschnitt) kennzeichnen, dass die Response keinen Body hat. +Einige Responsecodes (siehe nächsten Abschnitt) kennzeichnen, dass die Response keinen Body hat. -FastAPI versteht das und wird in der OpenAPI-Dokumentation anzeigen, dass es keinen Responsebody gibt. +FastAPI erkennt dies und erstellt eine OpenAPI-Dokumentation, die zeigt, dass es keinen Responsebody gibt. /// -## Über HTTP-Statuscodes +## Über HTTP-Statuscodes { #about-http-status-codes } /// note | Hinweis -Wenn Sie bereits wissen, was HTTP-Statuscodes sind, Ãŧberspringen Sie dieses Kapitel und fahren Sie mit dem nächsten fort. +Wenn Sie bereits wissen, was HTTP-Statuscodes sind, kÃļnnen Sie diesen Abschnitt Ãŧberspringen und mit dem nächsten fortfahren. /// -In HTTP senden Sie als Teil der Response einen aus drei Ziffern bestehenden numerischen Statuscode. +In HTTP senden Sie einen numerischen Statuscode mit 3 Ziffern als Teil der Response. -Diese Statuscodes haben einen Namen zugeordnet, um sie besser zu erkennen, aber der wichtige Teil ist die Zahl. +Diese Statuscodes haben einen zugeordneten Namen, um sie leichter zu erkennen, aber der wichtige Teil ist die Zahl. -Kurz: +Kurz gefasst: -* `100` und darÃŧber stehen fÃŧr „Information“. Diese verwenden Sie selten direkt. Responses mit diesen Statuscodes kÃļnnen keinen Body haben. -* **`200`** und darÃŧber stehen fÃŧr Responses, die „Successful“ („Erfolgreich“) waren. Diese verwenden Sie am häufigsten. - * `200` ist der Default-Statuscode, welcher bedeutet, alles ist „OK“. - * Ein anderes Beispiel ist `201`, „Created“ („Erzeugt“). Wird in der Regel verwendet, wenn ein neuer Datensatz in der Datenbank erzeugt wurde. - * Ein spezieller Fall ist `204`, „No Content“ („Kein Inhalt“). Diese Response wird verwendet, wenn es keinen Inhalt gibt, der zum Client zurÃŧckgeschickt wird, diese Response hat also keinen Body. -* **`300`** und darÃŧber steht fÃŧr „Redirection“ („Umleitung“). Responses mit diesen Statuscodes kÃļnnen einen oder keinen Body haben, mit Ausnahme von `304`, „Not Modified“ („Nicht verändert“), welche keinen haben darf. -* **`400`** und darÃŧber stehen fÃŧr „Client error“-Responses („Client-Fehler“). Auch diese verwenden Sie am häufigsten. +* `100 - 199` stehen fÃŧr „Information“. Sie verwenden diese selten direkt. Responses mit diesen Statuscodes dÃŧrfen keinen Body haben. +* **`200 - 299`** stehen fÃŧr „Successful“-Responses („Erfolgreich“). Diese werden Sie am häufigsten verwenden. + * `200` ist der Default-Statuscode, was bedeutet, alles ist „OK“. + * Ein weiteres Beispiel wäre `201`, „Created“ („Erzeugt“). Dieser wird Ãŧblicherweise verwendet, nachdem ein neuer Datensatz in der Datenbank erstellt wurde. + * Ein spezieller Fall ist `204`, „No Content“ („Kein Inhalt“). Diese Response wird verwendet, wenn es keinen Inhalt gibt, der an den Client zurÃŧckgeschickt werden soll, und diese Response darf daher keinen Body haben. +* **`300 - 399`** stehen fÃŧr „Redirection“ („Umleitung“). Responses mit diesen Statuscodes kÃļnnen einen Body haben oder nicht, außer bei `304`, „Not Modified“ („Nicht verändert“), die keinen haben darf. +* **`400 - 499`** stehen fÃŧr „Client error“-Responses („Client-Fehler“). Diese sind die zweithäufigsten, die Sie vermutlich verwenden werden. * Ein Beispiel ist `404`, fÃŧr eine „Not Found“-Response („Nicht gefunden“). * FÃŧr allgemeine Fehler beim Client kÃļnnen Sie einfach `400` verwenden. -* `500` und darÃŧber stehen fÃŧr Server-Fehler. Diese verwenden Sie fast nie direkt. Wenn etwas an irgendeiner Stelle in Ihrem Anwendungscode oder im Server schiefläuft, wird automatisch einer dieser Fehler-Statuscodes zurÃŧckgegeben. +* `500 - 599` stehen fÃŧr Server-Fehler. Diese verwenden Sie fast nie direkt. Wenn in Ihrem Anwendungscode oder Server etwas schiefgeht, wird automatisch einer dieser Fehler-Statuscodes zurÃŧckgegeben. /// tip | Tipp -Um mehr Ãŧber Statuscodes zu lernen, und welcher wofÃŧr verwendet wird, lesen Sie die MDN Dokumentation Ãŧber HTTP-Statuscodes. +Um mehr Ãŧber die einzelnen Statuscodes zu erfahren und welcher wofÃŧr verwendet wird, sehen Sie sich die MDN Dokumentation Ãŧber HTTP-Statuscodes an. /// -## AbkÃŧrzung, um die Namen zu erinnern +## AbkÃŧrzung zur Erinnerung an die Namen { #shortcut-to-remember-the-names } -Schauen wir uns das vorherige Beispiel noch einmal an: +Lassen Sie uns das vorherige Beispiel noch einmal anschauen: {* ../../docs_src/response_status_code/tutorial001.py hl[6] *} `201` ist der Statuscode fÃŧr „Created“ („Erzeugt“). -Aber Sie mÃŧssen sich nicht daran erinnern, welcher dieser Codes was bedeutet. +Aber Sie mÃŧssen sich nicht merken, was jeder dieser Codes bedeutet. -Sie kÃļnnen die Hilfsvariablen von `fastapi.status` verwenden. +Sie kÃļnnen die Annehmlichkeit von Variablen aus `fastapi.status` nutzen. {* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *} -Diese sind nur eine Annehmlichkeit und enthalten dieselbe Nummer, aber auf diese Weise kÃļnnen Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden: +Diese sind nur eine Annehmlichkeit, sie enthalten dieselbe Zahl, aber so kÃļnnen Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden: /// note | Technische Details -Sie kÃļnnen auch `from starlette import status` verwenden. +Sie kÃļnnten auch `from starlette import status` verwenden. -**FastAPI** bietet dieselben `starlette.status`-Codes auch via `fastapi.status` an, als Annehmlichkeit fÃŧr Sie, den Entwickler. Sie kommen aber direkt von Starlette. +**FastAPI** bietet dieselben `starlette.status`-Codes auch via `fastapi.status` an, rein zu Ihrer Annehmlichkeit als Entwickler. Aber sie stammen direkt von Starlette. /// -## Den Defaultwert ändern +## Den Defaultwert ändern { #changing-the-default } -Später sehen Sie, im [Handbuch fÃŧr fortgeschrittene Benutzer](../advanced/response-change-status-code.md){.internal-link target=_blank}, wie Sie einen anderen Statuscode zurÃŧckgeben kÃļnnen, als den Default, den Sie hier deklarieren. +Später im [Handbuch fÃŧr fortgeschrittene Benutzer](../advanced/response-change-status-code.md){.internal-link target=_blank} werden Sie sehen, wie Sie einen anderen Statuscode zurÃŧckgeben kÃļnnen, als den Default, den Sie hier deklarieren. diff --git a/docs/de/docs/tutorial/schema-extra-example.md b/docs/de/docs/tutorial/schema-extra-example.md index f065ad4ca..e2ffed292 100644 --- a/docs/de/docs/tutorial/schema-extra-example.md +++ b/docs/de/docs/tutorial/schema-extra-example.md @@ -1,10 +1,10 @@ -# Beispiel-Request-Daten deklarieren +# Beispiel-Request-Daten deklarieren { #declare-request-example-data } -Sie kÃļnnen Beispiele fÃŧr die Daten deklarieren, die Ihre Anwendung empfangen kann. +Sie kÃļnnen Beispiele fÃŧr die Daten deklarieren, die Ihre App empfangen kann. Hier sind mehrere MÃļglichkeiten, das zu tun. -## Zusätzliche JSON-Schemadaten in Pydantic-Modellen +## Zusätzliche JSON-Schemadaten in Pydantic-Modellen { #extra-json-schema-data-in-pydantic-models } Sie kÃļnnen `examples` („Beispiele“) fÃŧr ein Pydantic-Modell deklarieren, welche dem generierten JSON-Schema hinzugefÃŧgt werden. @@ -24,7 +24,7 @@ Diese zusätzlichen Informationen werden unverändert zum fÃŧr dieses Modell aus //// tab | Pydantic v2 -In Pydantic Version 2 wÃŧrden Sie das Attribut `model_config` verwenden, das ein `dict` akzeptiert, wie beschrieben in Pydantic-Dokumentation: Configuration. +In Pydantic Version 2 wÃŧrden Sie das Attribut `model_config` verwenden, das ein `dict` akzeptiert, wie beschrieben in Pydantic-Dokumentation: Configuration. Sie kÃļnnen `json_schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`. @@ -46,23 +46,23 @@ Sie kÃļnnten das beispielsweise verwenden, um Metadaten fÃŧr eine Frontend-Benut /// -/// info +/// info | Info OpenAPI 3.1.0 (verwendet seit FastAPI 0.99.0) hat UnterstÃŧtzung fÃŧr `examples` hinzugefÃŧgt, was Teil des **JSON Schema** Standards ist. -Zuvor unterstÃŧtzte es nur das SchlÃŧsselwort `example` mit einem einzigen Beispiel. Dieses wird weiterhin von OpenAPI 3.1.0 unterstÃŧtzt, ist jedoch deprecated und nicht Teil des JSON Schema Standards. Wir empfehlen Ihnen daher, von `example` nach `examples` zu migrieren. 🤓 +Zuvor unterstÃŧtzte es nur das SchlÃŧsselwort `example` mit einem einzigen Beispiel. Dieses wird weiterhin von OpenAPI 3.1.0 unterstÃŧtzt, ist jedoch deprecatet und nicht Teil des JSON Schema Standards. Wir empfehlen Ihnen daher, von `example` nach `examples` zu migrieren. 🤓 Mehr erfahren Sie am Ende dieser Seite. /// -## Zusätzliche Argumente fÃŧr `Field` +## Zusätzliche Argumente fÃŧr `Field` { #field-additional-arguments } Wenn Sie `Field()` mit Pydantic-Modellen verwenden, kÃļnnen Sie ebenfalls zusätzliche `examples` deklarieren: {* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *} -## `examples` im JSON-Schema – OpenAPI +## `examples` im JSON-Schema – OpenAPI { #examples-in-json-schema-openapi } Bei Verwendung von: @@ -76,19 +76,19 @@ Bei Verwendung von: kÃļnnen Sie auch eine Gruppe von `examples` mit zusätzlichen Informationen deklarieren, die zu ihren **JSON-Schemas** innerhalb von **OpenAPI** hinzugefÃŧgt werden. -### `Body` mit `examples` +### `Body` mit `examples` { #body-with-examples } Hier Ãŧbergeben wir `examples`, welches ein einzelnes Beispiel fÃŧr die in `Body()` erwarteten Daten enthält: {* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *} -### Beispiel in der Dokumentations-Benutzeroberfläche +### Beispiel in der Dokumentations-Benutzeroberfläche { #example-in-the-docs-ui } Mit jeder der oben genannten Methoden wÃŧrde es in `/docs` so aussehen: -### `Body` mit mehreren `examples` +### `Body` mit mehreren `examples` { #body-with-multiple-examples } Sie kÃļnnen natÃŧrlich auch mehrere `examples` Ãŧbergeben: @@ -96,9 +96,9 @@ Sie kÃļnnen natÃŧrlich auch mehrere `examples` Ãŧbergeben: Wenn Sie das tun, werden die Beispiele Teil des internen **JSON-Schemas** fÃŧr diese Body-Daten. -Während dies geschrieben wird, unterstÃŧtzt Swagger UI, das fÃŧr die Anzeige der Dokumentations-Benutzeroberfläche zuständige Tool, jedoch nicht die Anzeige mehrerer Beispiele fÃŧr die Daten in **JSON Schema**. Aber lesen Sie unten fÃŧr einen Workaround weiter. +Während dies geschrieben wird, unterstÃŧtzt Swagger UI, das fÃŧr die Anzeige der Dokumentations-Benutzeroberfläche zuständige Tool, jedoch nicht die Anzeige mehrerer Beispiele fÃŧr die Daten in **JSON Schema**. Aber lesen Sie unten fÃŧr einen Workaround weiter. -### OpenAPI-spezifische `examples` +### OpenAPI-spezifische `examples` { #openapi-specific-examples } Schon bevor **JSON Schema** `examples` unterstÃŧtzte, unterstÃŧtzte OpenAPI ein anderes Feld, das auch `examples` genannt wurde. @@ -106,11 +106,11 @@ Diese **OpenAPI-spezifischen** `examples` finden sich in einem anderen Abschnitt Und Swagger UI unterstÃŧtzt dieses spezielle Feld `examples` schon seit einiger Zeit. Sie kÃļnnen es also verwenden, um verschiedene **Beispiele in der Benutzeroberfläche der Dokumentation anzuzeigen**. -Das Format dieses OpenAPI-spezifischen Felds `examples` ist ein `dict` mit **mehreren Beispielen** (anstelle einer `list`e), jedes mit zusätzlichen Informationen, die auch zu **OpenAPI** hinzugefÃŧgt werden. +Das Format dieses OpenAPI-spezifischen Felds `examples` ist ein `dict` mit **mehreren Beispielen** (anstelle einer `list`), jedes mit zusätzlichen Informationen, die auch zu **OpenAPI** hinzugefÃŧgt werden. Dies erfolgt nicht innerhalb jedes in OpenAPI enthaltenen JSON-Schemas, sondern außerhalb, in der *Pfadoperation*. -### Verwendung des Parameters `openapi_examples` +### Verwendung des Parameters `openapi_examples` { #using-the-openapi-examples-parameter } Sie kÃļnnen die OpenAPI-spezifischen `examples` in FastAPI mit dem Parameter `openapi_examples` deklarieren, fÃŧr: @@ -122,7 +122,7 @@ Sie kÃļnnen die OpenAPI-spezifischen `examples` in FastAPI mit dem Parameter `op * `Form()` * `File()` -Die SchlÃŧssel des `dict` identifizieren jedes Beispiel, und jeder Wert (`"value"`) ist ein weiteres `dict`. +Die SchlÃŧssel des `dict` identifizieren jedes Beispiel, und jeder Wert ist ein weiteres `dict`. Jedes spezifische Beispiel-`dict` in den `examples` kann Folgendes enthalten: @@ -135,13 +135,13 @@ Sie kÃļnnen es so verwenden: {* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *} -### OpenAPI-Beispiele in der Dokumentations-Benutzeroberfläche +### OpenAPI-Beispiele in der Dokumentations-Benutzeroberfläche { #openapi-examples-in-the-docs-ui } Wenn `openapi_examples` zu `Body()` hinzugefÃŧgt wird, wÃŧrde `/docs` so aussehen: -## Technische Details +## Technische Details { #technical-details } /// tip | Tipp @@ -177,23 +177,23 @@ OpenAPI fÃŧgte auch die Felder `example` und `examples` zu anderen Teilen der Sp * `File()` * `Form()` -/// info +/// info | Info Dieser alte, OpenAPI-spezifische `examples`-Parameter heißt seit FastAPI `0.103.0` jetzt `openapi_examples`. /// -### JSON Schemas Feld `examples` +### JSON Schemas Feld `examples` { #json-schemas-examples-field } Aber dann fÃŧgte JSON Schema ein `examples`-Feld zu einer neuen Version der Spezifikation hinzu. Und dann basierte das neue OpenAPI 3.1.0 auf der neuesten Version (JSON Schema 2020-12), die dieses neue Feld `examples` enthielt. -Und jetzt hat dieses neue `examples`-Feld Vorrang vor dem alten (und benutzerdefinierten) `example`-Feld, im Singular, das jetzt deprecated ist. +Und jetzt hat dieses neue `examples`-Feld Vorrang vor dem alten (und benutzerdefinierten) `example`-Feld, im Singular, das jetzt deprecatet ist. -Dieses neue `examples`-Feld in JSON Schema ist **nur eine `list`e** von Beispielen, kein Dict mit zusätzlichen Metadaten wie an den anderen Stellen in OpenAPI (oben beschrieben). +Dieses neue `examples`-Feld in JSON Schema ist **nur eine `list`** von Beispielen, kein Dict mit zusätzlichen Metadaten wie an den anderen Stellen in OpenAPI (oben beschrieben). -/// info +/// info | Info Selbst, nachdem OpenAPI 3.1.0 verÃļffentlicht wurde, mit dieser neuen, einfacheren Integration mit JSON Schema, unterstÃŧtzte Swagger UI, das Tool, das die automatische Dokumentation bereitstellt, eine Zeit lang OpenAPI 3.1.0 nicht (das tut es seit Version 5.0.0 🎉). @@ -201,7 +201,7 @@ Aus diesem Grund verwendeten Versionen von FastAPI vor 0.99.0 immer noch Version /// -### Pydantic- und FastAPI-`examples` +### Pydantic- und FastAPI-`examples` { #pydantic-and-fastapi-examples } Wenn Sie `examples` innerhalb eines Pydantic-Modells hinzufÃŧgen, indem Sie `schema_extra` oder `Field(examples=["something"])` verwenden, wird dieses Beispiel dem **JSON-Schema** fÃŧr dieses Pydantic-Modell hinzugefÃŧgt. @@ -211,14 +211,14 @@ In Versionen von FastAPI vor 0.99.0 (0.99.0 und hÃļher verwenden das neuere Open Aber jetzt, da FastAPI 0.99.0 und hÃļher, OpenAPI 3.1.0 verwendet, das JSON Schema 2020-12 verwendet, und Swagger UI 5.0.0 und hÃļher, ist alles konsistenter und die Beispiele sind in JSON Schema enthalten. -### Swagger-Benutzeroberfläche und OpenAPI-spezifische `examples`. +### Swagger-Benutzeroberfläche und OpenAPI-spezifische `examples` { #swagger-ui-and-openapi-specific-examples } Da die Swagger-Benutzeroberfläche derzeit nicht mehrere JSON Schema Beispiele unterstÃŧtzt (Stand: 26.08.2023), hatten Benutzer keine MÃļglichkeit, mehrere Beispiele in der Dokumentation anzuzeigen. Um dieses Problem zu lÃļsen, hat FastAPI `0.103.0` **UnterstÃŧtzung** fÃŧr die Deklaration desselben alten **OpenAPI-spezifischen** `examples`-Felds mit dem neuen Parameter `openapi_examples` hinzugefÃŧgt. 🤓 -### Zusammenfassung +### Zusammenfassung { #summary } Ich habe immer gesagt, dass ich Geschichte nicht so sehr mag ... und jetzt schauen Sie mich an, wie ich „Technikgeschichte“-Unterricht gebe. 😅 -Kurz gesagt: **Upgraden Sie auf FastAPI 0.99.0 oder hÃļher**, und die Dinge sind viel **einfacher, konsistenter und intuitiver**, und Sie mÃŧssen nicht alle diese historischen Details kennen. 😎 +Kurz gesagt: **Aktualisieren Sie auf FastAPI 0.99.0 oder hÃļher**, und die Dinge sind viel **einfacher, konsistenter und intuitiver**, und Sie mÃŧssen nicht alle diese historischen Details kennen. 😎 diff --git a/docs/de/docs/tutorial/security/first-steps.md b/docs/de/docs/tutorial/security/first-steps.md index 8fa33db7e..20fcd0c00 100644 --- a/docs/de/docs/tutorial/security/first-steps.md +++ b/docs/de/docs/tutorial/security/first-steps.md @@ -1,8 +1,8 @@ -# Sicherheit – Erste Schritte +# Sicherheit – Erste Schritte { #security-first-steps } Stellen wir uns vor, dass Sie Ihre **Backend**-API auf einer Domain haben. -Und Sie haben ein **Frontend** auf einer anderen Domain oder in einem anderen Pfad derselben Domain (oder in einer mobilen Anwendung). +Und Sie haben ein **Frontend** auf einer anderen Domain oder in einem anderen Pfad derselben Domain (oder in einer Mobile-Anwendung). Und Sie mÃļchten eine MÃļglichkeit haben, dass sich das Frontend mithilfe eines **Benutzernamens** und eines **Passworts** beim Backend authentisieren kann. @@ -12,25 +12,33 @@ Aber ersparen wir Ihnen die Zeit, die gesamte lange Spezifikation zu lesen, nur Lassen Sie uns die von **FastAPI** bereitgestellten Tools verwenden, um Sicherheit zu gewährleisten. -## Wie es aussieht +## Wie es aussieht { #how-it-looks } Lassen Sie uns zunächst einfach den Code verwenden und sehen, wie er funktioniert, und dann kommen wir zurÃŧck, um zu verstehen, was passiert. -## `main.py` erstellen +## `main.py` erstellen { #create-main-py } Kopieren Sie das Beispiel in eine Datei `main.py`: {* ../../docs_src/security/tutorial001_an_py39.py *} -## AusfÃŧhren +## AusfÃŧhren { #run-it } -/// info +/// info | Info -Um hochgeladene Dateien zu empfangen, installieren Sie zuerst `python-multipart`. +Das Paket `python-multipart` wird automatisch mit **FastAPI** installiert, wenn Sie den Befehl `pip install "fastapi[standard]"` ausfÃŧhren. -Z. B. `pip install python-multipart`. +Wenn Sie jedoch den Befehl `pip install fastapi` verwenden, ist das Paket `python-multipart` nicht standardmäßig enthalten. -Das, weil **OAuth2** „Formulardaten“ zum Senden von `username` und `password` verwendet. +Um es manuell zu installieren, stellen Sie sicher, dass Sie eine [Virtuelle Umgebung](../../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und es dann mit: + +```console +$ pip install python-multipart +``` + +installieren. + +Das liegt daran, dass **OAuth2** „Formulardaten“ zum Senden von `username` und `password` verwendet. /// @@ -39,14 +47,14 @@ FÃŧhren Sie das Beispiel aus mit:
```console -$ uvicorn main:app --reload +$ fastapi dev main.py INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ```
-## ÜberprÃŧfen +## Es testen { #check-it } Gehen Sie zu der interaktiven Dokumentation unter: http://127.0.0.1:8000/docs. @@ -80,7 +88,7 @@ Es kann von Anwendungen und Systemen Dritter verwendet werden. Und es kann auch von Ihnen selbst verwendet werden, um dieselbe Anwendung zu debuggen, zu prÃŧfen und zu testen. -## Der `password`-Flow +## Der `password`-Flow { #the-password-flow } Lassen Sie uns nun etwas zurÃŧckgehen und verstehen, was das alles ist. @@ -103,16 +111,16 @@ Betrachten wir es also aus dieser vereinfachten Sicht: * Der Benutzer klickt im Frontend, um zu einem anderen Abschnitt der Frontend-Web-Anwendung zu gelangen. * Das Frontend muss weitere Daten von der API abrufen. * Es benÃļtigt jedoch eine Authentifizierung fÃŧr diesen bestimmten Endpunkt. - * Um sich also bei unserer API zu authentifizieren, sendet es einen Header `Authorization` mit dem Wert `Bearer` plus dem Token. + * Um sich also bei unserer API zu authentifizieren, sendet es einen Header `Authorization` mit dem Wert `Bearer ` plus dem Token. * Wenn der Token `foobar` enthielte, wäre der Inhalt des `Authorization`-Headers: `Bearer foobar`. -## **FastAPI**s `OAuth2PasswordBearer` +## **FastAPI**s `OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer } **FastAPI** bietet mehrere Tools auf unterschiedlichen Abstraktionsebenen zur Implementierung dieser Sicherheitsfunktionen. In diesem Beispiel verwenden wir **OAuth2** mit dem **Password**-Flow und einem **Bearer**-Token. Wir machen das mit der Klasse `OAuth2PasswordBearer`. -/// info +/// info | Info Ein „Bearer“-Token ist nicht die einzige Option. @@ -142,7 +150,7 @@ Dieser Parameter erstellt nicht diesen Endpunkt / diese *Pfadoperation*, sondern Wir werden demnächst auch die eigentliche Pfadoperation erstellen. -/// info +/// info | Info Wenn Sie ein sehr strenger „Pythonista“ sind, missfällt Ihnen mÃļglicherweise die Schreibweise des Parameternamens `tokenUrl` anstelle von `token_url`. @@ -160,7 +168,7 @@ oauth2_scheme(some, parameters) Es kann also mit `Depends` verwendet werden. -### Verwendung +### Verwenden { #use-it } Jetzt kÃļnnen Sie dieses `oauth2_scheme` als Abhängigkeit `Depends` Ãŧbergeben. @@ -178,11 +186,11 @@ Alle Sicherheits-Werkzeuge, die in OpenAPI integriert sind (und die automatische /// -## Was es macht +## Was es macht { #what-it-does } -FastAPI wird im Request nach diesem `Authorization`-Header suchen, prÃŧfen, ob der Wert `Bearer` plus ein Token ist, und den Token als `str` zurÃŧckgeben. +FastAPI wird im Request nach diesem `Authorization`-Header suchen, prÃŧfen, ob der Wert `Bearer ` plus ein Token ist, und den Token als `str` zurÃŧckgeben. -Wenn es keinen `Authorization`-Header sieht, oder der Wert keinen `Bearer`-Token hat, antwortet es direkt mit einem 401-Statuscode-Error (`UNAUTHORIZED`). +Wenn es keinen `Authorization`-Header sieht, oder der Wert keinen `Bearer `-Token hat, antwortet es direkt mit einem 401-Statuscode-Error (`UNAUTHORIZED`). Sie mÃŧssen nicht einmal prÃŧfen, ob der Token existiert, um einen Fehler zurÃŧckzugeben. Seien Sie sicher, dass Ihre Funktion, wenn sie ausgefÃŧhrt wird, ein `str` in diesem Token enthält. @@ -192,6 +200,6 @@ Sie kÃļnnen das bereits in der interaktiven Dokumentation ausprobieren: Wir ÃŧberprÃŧfen im Moment noch nicht die GÃŧltigkeit des Tokens, aber das ist bereits ein Anfang. -## Zusammenfassung +## Zusammenfassung { #recap } -Mit nur drei oder vier zusätzlichen Zeilen haben Sie also bereits eine primitive Form der Sicherheit. +Mit nur drei oder vier zusätzlichen Zeilen haben Sie so bereits eine primitive Form der Sicherheit. diff --git a/docs/de/docs/tutorial/security/get-current-user.md b/docs/de/docs/tutorial/security/get-current-user.md index 38f7ffcbf..e32e36669 100644 --- a/docs/de/docs/tutorial/security/get-current-user.md +++ b/docs/de/docs/tutorial/security/get-current-user.md @@ -1,4 +1,4 @@ -# Aktuellen Benutzer abrufen +# Aktuellen Benutzer abrufen { #get-current-user } Im vorherigen Kapitel hat das Sicherheitssystem (das auf dem Dependency Injection System basiert) der *Pfadoperation-Funktion* einen `token` vom Typ `str` Ãŧberreicht: @@ -8,15 +8,15 @@ Aber das ist immer noch nicht so nÃŧtzlich. Lassen wir es uns den aktuellen Benutzer Ãŧberreichen. -## Ein Benutzermodell erstellen +## Ein Benutzermodell erstellen { #create-a-user-model } Erstellen wir zunächst ein Pydantic-Benutzermodell. So wie wir Pydantic zum Deklarieren von Bodys verwenden, kÃļnnen wir es auch Ãŧberall sonst verwenden: -{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *} +{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *} -## Eine `get_current_user`-Abhängigkeit erstellen +## Eine `get_current_user`-Abhängigkeit erstellen { #create-a-get-current-user-dependency } Erstellen wir eine Abhängigkeit `get_current_user`. @@ -28,13 +28,13 @@ So wie wir es zuvor in der *Pfadoperation* direkt gemacht haben, erhält unsere {* ../../docs_src/security/tutorial002_an_py310.py hl[25] *} -## Den Benutzer holen +## Den Benutzer abrufen { #get-the-user } `get_current_user` wird eine von uns erstellte (gefakte) Hilfsfunktion verwenden, welche einen Token vom Typ `str` entgegennimmt und unser Pydantic-`User`-Modell zurÃŧckgibt: {* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *} -## Den aktuellen Benutzer einfÃŧgen +## Den aktuellen Benutzer einfÃŧgen { #inject-the-current-user } Und jetzt kÃļnnen wir wiederum `Depends` mit unserem `get_current_user` in der *Pfadoperation* verwenden: @@ -46,13 +46,13 @@ Das wird uns innerhalb der Funktion bei Codevervollständigung und TypprÃŧfungen /// tip | Tipp -Sie erinnern sich vielleicht, dass Requestbodys ebenfalls mit Pydantic-Modellen deklariert werden. +Sie erinnern sich vielleicht, dass Requestbodys ebenfalls mit Pydantic-Modellen deklariert werden. Weil Sie `Depends` verwenden, wird **FastAPI** hier aber nicht verwirrt. /// -/// check +/// check | Testen Die Art und Weise, wie dieses System von Abhängigkeiten konzipiert ist, ermÃļglicht es uns, verschiedene Abhängigkeiten (verschiedene „Dependables“) zu haben, die alle ein `User`-Modell zurÃŧckgeben. @@ -60,7 +60,7 @@ Wir sind nicht darauf beschränkt, nur eine Abhängigkeit zu haben, die diesen T /// -## Andere Modelle +## Andere Modelle { #other-models } Sie kÃļnnen jetzt den aktuellen Benutzer direkt in den *Pfadoperation-Funktionen* abrufen und die Sicherheitsmechanismen auf **Dependency Injection** Ebene handhaben, mittels `Depends`. @@ -76,7 +76,7 @@ Sie haben eigentlich keine Benutzer, die sich bei Ihrer Anwendung anmelden, sond Verwenden Sie einfach jede Art von Modell, jede Art von Klasse, jede Art von Datenbank, die Sie fÃŧr Ihre Anwendung benÃļtigen. **FastAPI** deckt das alles mit seinem Dependency Injection System ab. -## CodegrÃļße +## CodegrÃļße { #code-size } Dieses Beispiel mag ausfÃŧhrlich erscheinen. Bedenken Sie, dass wir Sicherheit, Datenmodelle, Hilfsfunktionen und *Pfadoperationen* in derselben Datei vermischen. @@ -94,7 +94,7 @@ Und alle diese Tausenden von *Pfadoperationen* kÃļnnen nur drei Zeilen lang sein {* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *} -## Zusammenfassung +## Zusammenfassung { #recap } Sie kÃļnnen jetzt den aktuellen Benutzer direkt in Ihrer *Pfadoperation-Funktion* abrufen. diff --git a/docs/de/docs/tutorial/security/index.md b/docs/de/docs/tutorial/security/index.md index b01243901..39b0b93c9 100644 --- a/docs/de/docs/tutorial/security/index.md +++ b/docs/de/docs/tutorial/security/index.md @@ -1,4 +1,4 @@ -# Sicherheit +# Sicherheit { #security } Es gibt viele Wege, Sicherheit, Authentifizierung und Autorisierung zu handhaben. @@ -10,11 +10,11 @@ In vielen Frameworks und Systemen erfordert allein die Handhabung von Sicherheit Aber schauen wir uns zunächst ein paar kleine Konzepte an. -## In Eile? +## In Eile? { #in-a-hurry } Wenn Ihnen diese Begriffe egal sind und Sie einfach *jetzt* Sicherheit mit Authentifizierung basierend auf Benutzername und Passwort hinzufÃŧgen mÃŧssen, fahren Sie mit den nächsten Kapiteln fort. -## OAuth2 +## OAuth2 { #oauth2 } OAuth2 ist eine Spezifikation, die verschiedene MÃļglichkeiten zur Handhabung von Authentifizierung und Autorisierung definiert. @@ -22,9 +22,9 @@ Es handelt sich um eine recht umfangreiche Spezifikation, und sie deckt mehrere Sie umfasst MÃļglichkeiten zur Authentifizierung mithilfe eines „Dritten“ („third party“). -Das ist es, was alle diese „Login mit Facebook, Google, Twitter, GitHub“-Systeme unter der Haube verwenden. +Das ist es, was alle diese „Login mit Facebook, Google, X (Twitter), GitHub“-Systeme unter der Haube verwenden. -### OAuth 1 +### OAuth 1 { #oauth-1 } Es gab ein OAuth 1, das sich stark von OAuth2 unterscheidet und komplexer ist, da es direkte Spezifikationen enthält, wie die Kommunikation verschlÃŧsselt wird. @@ -38,7 +38,7 @@ Im Abschnitt Ãŧber **Deployment** erfahren Sie, wie Sie HTTPS mithilfe von Traef /// -## OpenID Connect +## OpenID Connect { #openid-connect } OpenID Connect ist eine weitere Spezifikation, die auf **OAuth2** basiert. @@ -48,7 +48,7 @@ Beispielsweise verwendet der Google Login OpenID Connect (welches seinerseits OA Aber der Facebook Login unterstÃŧtzt OpenID Connect nicht. Es hat seine eigene Variante von OAuth2. -### OpenID (nicht „OpenID Connect“) +### OpenID (nicht „OpenID Connect“) { #openid-not-openid-connect } Es gab auch eine „OpenID“-Spezifikation. Sie versuchte das Gleiche zu lÃļsen wie **OpenID Connect**, basierte aber nicht auf OAuth2. @@ -56,7 +56,7 @@ Es handelte sich also um ein komplett zusätzliches System. Heutzutage ist es nicht sehr populär und wird kaum verwendet. -## OpenAPI +## OpenAPI { #openapi } OpenAPI (frÃŧher bekannt als Swagger) ist die offene Spezifikation zum Erstellen von APIs (jetzt Teil der Linux Foundation). @@ -75,11 +75,11 @@ OpenAPI definiert die folgenden Sicherheitsschemas: * Einem Header. * Einem Cookie. * `http`: Standard-HTTP-Authentifizierungssysteme, einschließlich: - * `bearer`: ein Header `Authorization` mit dem Wert `Bearer` plus einem Token. Dies wird von OAuth2 geerbt. + * `bearer`: ein Header `Authorization` mit dem Wert `Bearer ` plus einem Token. Dies wird von OAuth2 geerbt. * HTTP Basic Authentication. * HTTP Digest, usw. * `oauth2`: Alle OAuth2-Methoden zum Umgang mit Sicherheit (genannt „Flows“). - * Mehrere dieser Flows eignen sich zum Aufbau eines OAuth 2.0-Authentifizierungsanbieters (wie Google, Facebook, Twitter, GitHub usw.): + * Mehrere dieser Flows eignen sich zum Aufbau eines OAuth 2.0-Authentifizierungsanbieters (wie Google, Facebook, X (Twitter), GitHub usw.): * `implicit` * `clientCredentials` * `authorizationCode` @@ -91,13 +91,13 @@ OpenAPI definiert die folgenden Sicherheitsschemas: /// tip | Tipp -Auch die Integration anderer Authentifizierungs-/Autorisierungsanbieter wie Google, Facebook, Twitter, GitHub, usw. ist mÃļglich und relativ einfach. +Auch die Integration anderer Authentifizierungs-/Autorisierungsanbieter wie Google, Facebook, X (Twitter), GitHub, usw. ist mÃļglich und relativ einfach. Das komplexeste Problem besteht darin, einen Authentifizierungs-/Autorisierungsanbieter wie solche aufzubauen, aber **FastAPI** reicht Ihnen die Tools, das einfach zu erledigen, während Ihnen die schwere Arbeit abgenommen wird. /// -## **FastAPI** Tools +## **FastAPI** Tools { #fastapi-utilities } FastAPI stellt fÃŧr jedes dieser Sicherheitsschemas im Modul `fastapi.security` verschiedene Tools bereit, die die Verwendung dieser Sicherheitsmechanismen vereinfachen. diff --git a/docs/de/docs/tutorial/security/oauth2-jwt.md b/docs/de/docs/tutorial/security/oauth2-jwt.md index 178a95d81..4b81c8069 100644 --- a/docs/de/docs/tutorial/security/oauth2-jwt.md +++ b/docs/de/docs/tutorial/security/oauth2-jwt.md @@ -1,4 +1,4 @@ -# OAuth2 mit Password (und Hashing), Bearer mit JWT-Tokens +# OAuth2 mit Passwort (und Hashing), Bearer mit JWT-Tokens { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens } Da wir nun Ãŧber den gesamten Sicherheitsablauf verfÃŧgen, machen wir die Anwendung tatsächlich sicher, indem wir JWT-Tokens und sicheres Passwort-Hashing verwenden. @@ -6,7 +6,7 @@ Diesen Code kÃļnnen Sie tatsächlich in Ihrer Anwendung verwenden, die Passwort- Wir bauen auf dem vorherigen Kapitel auf. -## Über JWT +## Über JWT { #about-jwt } JWT bedeutet „JSON Web Tokens“. @@ -26,33 +26,31 @@ Nach einer Woche läuft der Token ab und der Benutzer wird nicht autorisiert und Wenn Sie mit JWT-Tokens spielen und sehen mÃļchten, wie sie funktionieren, schauen Sie sich https://jwt.io an. -## `python-jose` installieren. +## `PyJWT` installieren { #install-pyjwt } -Wir mÃŧssen `python-jose` installieren, um die JWT-Tokens in Python zu generieren und zu verifizieren: +Wir mÃŧssen `PyJWT` installieren, um die JWT-Tokens in Python zu generieren und zu verifizieren. + +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und dann `pyjwt` installieren:
```console -$ pip install "python-jose[cryptography]" +$ pip install pyjwt ---> 100% ```
-python-jose erfordert zusätzlich ein kryptografisches Backend. +/// info | Info -Hier verwenden wir das empfohlene: pyca/cryptography. +Wenn Sie planen, digitale Signaturalgorithmen wie RSA oder ECDSA zu verwenden, sollten Sie die Kryptografie-Abhängigkeit `pyjwt[crypto]` installieren. -/// tip | Tipp - -Dieses Tutorial verwendete zuvor PyJWT. - -Es wurde jedoch aktualisiert, stattdessen python-jose zu verwenden, da dieses alle Funktionen von PyJWT sowie einige Extras bietet, die Sie später mÃļglicherweise benÃļtigen, wenn Sie Integrationen mit anderen Tools erstellen. +Weitere Informationen finden Sie in der PyJWT-Installationsdokumentation. /// -## Passwort-Hashing +## Passwort-Hashing { #password-hashing } „Hashing“ bedeutet: Konvertieren eines Inhalts (in diesem Fall eines Passworts) in eine Folge von Bytes (ein schlichter String), die wie Kauderwelsch aussieht. @@ -60,13 +58,13 @@ Immer wenn Sie genau den gleichen Inhalt (genau das gleiche Passwort) Ãŧbergeben Sie kÃļnnen jedoch nicht vom Kauderwelsch zurÃŧck zum Passwort konvertieren. -### Warum Passwort-Hashing verwenden? +### Warum Passwort-Hashing verwenden { #why-use-password-hashing } Wenn Ihre Datenbank gestohlen wird, hat der Dieb nicht die Klartext-PasswÃļrter Ihrer Benutzer, sondern nur die Hashes. Der Dieb kann also nicht versuchen, die gleichen PasswÃļrter in einem anderen System zu verwenden (da viele Benutzer Ãŧberall das gleiche Passwort verwenden, wäre dies gefährlich). -## `passlib` installieren +## `passlib` installieren { #install-passlib } PassLib ist ein großartiges Python-Package, um Passwort-Hashes zu handhaben. @@ -74,7 +72,7 @@ Es unterstÃŧtzt viele sichere Hashing-Algorithmen und Werkzeuge, um mit diesen z Der empfohlene Algorithmus ist „Bcrypt“. -Installieren Sie also PassLib mit Bcrypt: +Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren, und installieren Sie dann PassLib mit Bcrypt:
@@ -96,7 +94,7 @@ Und Ihre Benutzer kÃļnnten sich gleichzeitig Ãŧber Ihre Django-Anwendung oder Ih /// -## Die PasswÃļrter hashen und ÃŧberprÃŧfen +## Die PasswÃļrter hashen und ÃŧberprÃŧfen { #hash-and-verify-the-passwords } Importieren Sie die benÃļtigten Tools aus `passlib`. @@ -104,7 +102,7 @@ Erstellen Sie einen PassLib-„Kontext“. Der wird fÃŧr das Hashen und Verifizi /// tip | Tipp -Der PassLib-Kontext kann auch andere Hashing-Algorithmen verwenden, einschließlich deprecateter Alter, um etwa nur eine Verifizierung usw. zu ermÃļglichen. +Der PassLib-Kontext kann auch andere Hashing-Algorithmen verwenden, einschließlich deprecateter Alter, um etwa nur eine Verifizierung usw. zu ermÃļglichen. Sie kÃļnnten ihn beispielsweise verwenden, um von einem anderen System (wie Django) generierte PasswÃļrter zu lesen und zu verifizieren, aber alle neuen PasswÃļrter mit einem anderen Algorithmus wie Bcrypt zu hashen. @@ -118,7 +116,7 @@ Und eine weitere, um zu ÃŧberprÃŧfen, ob ein empfangenes Passwort mit dem gespei Und noch eine, um einen Benutzer zu authentifizieren und zurÃŧckzugeben. -{* ../../docs_src/security/tutorial004_an_py310.py hl[7,48,55:56,59:60,69:75] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *} /// note | Hinweis @@ -126,7 +124,7 @@ Wenn Sie sich die neue (gefakte) Datenbank `fake_users_db` anschauen, sehen Sie, /// -## JWT-Token verarbeiten +## JWT-Token verarbeiten { #handle-jwt-tokens } Importieren Sie die installierten Module. @@ -150,13 +148,13 @@ Erstellen Sie eine Variable `ALGORITHM` fÃŧr den Algorithmus, der zum Signieren Erstellen Sie eine Variable fÃŧr das Ablaufdatum des Tokens. -Definieren Sie ein Pydantic-Modell, das im Token-Endpunkt fÃŧr die Response verwendet wird. +Definieren Sie ein Pydantic-Modell, das im Token-Endpunkt fÃŧr die Response verwendet wird. Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren. -{* ../../docs_src/security/tutorial004_an_py310.py hl[6,12:14,28:30,78:86] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *} -## Die Abhängigkeiten aktualisieren +## Die Abhängigkeiten aktualisieren { #update-the-dependencies } Aktualisieren Sie `get_current_user`, um den gleichen Token wie zuvor zu erhalten, dieses Mal jedoch unter Verwendung von JWT-Tokens. @@ -164,17 +162,17 @@ Dekodieren Sie den empfangenen Token, validieren Sie ihn und geben Sie den aktue Wenn der Token ungÃŧltig ist, geben Sie sofort einen HTTP-Fehler zurÃŧck. -{* ../../docs_src/security/tutorial004_an_py310.py hl[89:106] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *} -## Die *Pfadoperation* `/token` aktualisieren +## Die *Pfadoperation* `/token` aktualisieren { #update-the-token-path-operation } Erstellen Sie ein `timedelta` mit der Ablaufzeit des Tokens. Erstellen Sie einen echten JWT-Zugriffstoken und geben Sie ihn zurÃŧck. -{* ../../docs_src/security/tutorial004_an_py310.py hl[117:132] *} +{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *} -### Technische Details zum JWT-„Subjekt“ `sub` +### Technische Details zum JWT-„Subjekt“ `sub` { #technical-details-about-the-jwt-subject-sub } Die JWT-Spezifikation besagt, dass es einen SchlÃŧssel `sub` mit dem Subjekt des Tokens gibt. @@ -196,7 +194,7 @@ Deshalb, um ID-Kollisionen zu vermeiden, kÃļnnten Sie beim Erstellen des JWT-Tok Der wesentliche Punkt ist, dass der `sub`-SchlÃŧssel in der gesamten Anwendung eine eindeutige Kennung haben sollte, und er sollte ein String sein. -## Es testen +## Es testen { #check-it } FÃŧhren Sie den Server aus und gehen Sie zur Dokumentation: http://127.0.0.1:8000/docs. @@ -209,11 +207,11 @@ Melden Sie sich bei der Anwendung auf die gleiche Weise wie zuvor an. Verwenden Sie die Anmeldeinformationen: Benutzername: `johndoe` -Passwort: `secret`. +Passwort: `secret` -/// check +/// check | Testen -Beachten Sie, dass im Code nirgendwo das Klartext-Passwort "`secret`" steht, wir haben nur die gehashte Version. +Beachten Sie, dass im Code nirgendwo das Klartext-Passwort „`secret`“ steht, wir haben nur die gehashte Version. /// @@ -232,17 +230,17 @@ Rufen Sie den Endpunkt `/users/me/` auf, Sie erhalten die Response: -Wenn Sie die Developer Tools Ãļffnen, kÃļnnen Sie sehen, dass die gesendeten Daten nur den Token enthalten. Das Passwort wird nur bei der ersten Anfrage gesendet, um den Benutzer zu authentisieren und diesen Zugriffstoken zu erhalten, aber nicht mehr danach: +Wenn Sie die Developer Tools Ãļffnen, kÃļnnen Sie sehen, dass die gesendeten Daten nur den Token enthalten. Das Passwort wird nur beim ersten Request gesendet, um den Benutzer zu authentisieren und diesen Zugriffstoken zu erhalten, aber nicht mehr danach: /// note | Hinweis -Beachten Sie den Header `Authorization` mit einem Wert, der mit `Bearer` beginnt. +Beachten Sie den Header `Authorization` mit einem Wert, der mit `Bearer ` beginnt. /// -## Fortgeschrittene Verwendung mit `scopes` +## Fortgeschrittene Verwendung mit `scopes` { #advanced-usage-with-scopes } OAuth2 hat ein Konzept von „Scopes“. @@ -252,7 +250,7 @@ Anschließend kÃļnnen Sie diesen Token einem Benutzer direkt oder einem Dritten Wie Sie sie verwenden und wie sie in **FastAPI** integriert sind, erfahren Sie später im **Handbuch fÃŧr fortgeschrittene Benutzer**. -## Zusammenfassung +## Zusammenfassung { #recap } Mit dem, was Sie bis hier gesehen haben, kÃļnnen Sie eine sichere **FastAPI**-Anwendung mithilfe von Standards wie OAuth2 und JWT einrichten. @@ -266,10 +264,10 @@ Viele Packages, die es stark vereinfachen, mÃŧssen viele Kompromisse beim Datenm Es gibt Ihnen die volle Flexibilität, diejenigen auszuwählen, die am besten zu Ihrem Projekt passen. -Und Sie kÃļnnen viele gut gepflegte und weit verbreitete Packages wie `passlib` und `python-jose` direkt verwenden, da **FastAPI** keine komplexen Mechanismen zur Integration externer Pakete erfordert. +Und Sie kÃļnnen viele gut gepflegte und weit verbreitete Packages wie `passlib` und `PyJWT` direkt verwenden, da **FastAPI** keine komplexen Mechanismen zur Integration externer Pakete erfordert. Aber es bietet Ihnen die Werkzeuge, um den Prozess so weit wie mÃļglich zu vereinfachen, ohne Kompromisse bei Flexibilität, Robustheit oder Sicherheit einzugehen. Und Sie kÃļnnen sichere Standardprotokolle wie OAuth2 auf relativ einfache Weise verwenden und implementieren. -Im **Handbuch fÃŧr fortgeschrittene Benutzer** erfahren Sie mehr darÃŧber, wie Sie OAuth2-„Scopes“ fÃŧr ein feingranuliertes Berechtigungssystem verwenden, das denselben Standards folgt. OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, Twitter, usw. verwendet wird, um Drittanbieteranwendungen zu autorisieren, im Namen ihrer Benutzer mit ihren APIs zu interagieren. +Im **Handbuch fÃŧr fortgeschrittene Benutzer** erfahren Sie mehr darÃŧber, wie Sie OAuth2-„Scopes“ fÃŧr ein feingranuliertes Berechtigungssystem verwenden, das denselben Standards folgt. OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, X (Twitter), usw. verwendet wird, um Drittanbieteranwendungen zu autorisieren, im Namen ihrer Benutzer mit ihren APIs zu interagieren. diff --git a/docs/de/docs/tutorial/security/simple-oauth2.md b/docs/de/docs/tutorial/security/simple-oauth2.md index c0c93cd26..28cb83ba9 100644 --- a/docs/de/docs/tutorial/security/simple-oauth2.md +++ b/docs/de/docs/tutorial/security/simple-oauth2.md @@ -1,8 +1,8 @@ -# Einfaches OAuth2 mit Password und Bearer +# Einfaches OAuth2 mit Password und Bearer { #simple-oauth2-with-password-and-bearer } Lassen Sie uns nun auf dem vorherigen Kapitel aufbauen und die fehlenden Teile hinzufÃŧgen, um einen vollständigen Sicherheits-Flow zu erhalten. -## `username` und `password` entgegennehmen +## `username` und `password` entgegennehmen { #get-the-username-and-password } Wir werden **FastAPIs** Sicherheits-Werkzeuge verwenden, um den `username` und das `password` entgegenzunehmen. @@ -18,7 +18,7 @@ Aber fÃŧr die Login-*Pfadoperation* mÃŧssen wir diese Namen verwenden, um mit de Die Spezifikation besagt auch, dass `username` und `password` als Formulardaten gesendet werden mÃŧssen (hier also kein JSON). -### `scope` +### `scope` { #scope } Ferner sagt die Spezifikation, dass der Client ein weiteres Formularfeld "`scope`" („Geltungsbereich“) senden kann. @@ -32,7 +32,7 @@ Diese werden normalerweise verwendet, um bestimmte Sicherheitsberechtigungen zu * `instagram_basic` wird von Facebook / Instagram verwendet. * `https://www.googleapis.com/auth/drive` wird von Google verwendet. -/// info +/// info | Info In OAuth2 ist ein „Scope“ nur ein String, der eine bestimmte erforderliche Berechtigung deklariert. @@ -44,11 +44,11 @@ FÃŧr OAuth2 sind es einfach nur Strings. /// -## Code, um `username` und `password` entgegenzunehmen. +## Code, um `username` und `password` entgegenzunehmen { #code-to-get-the-username-and-password } Lassen Sie uns nun die von **FastAPI** bereitgestellten Werkzeuge verwenden, um das zu erledigen. -### `OAuth2PasswordRequestForm` +### `OAuth2PasswordRequestForm` { #oauth2passwordrequestform } Importieren Sie zunächst `OAuth2PasswordRequestForm` und verwenden Sie es als Abhängigkeit mit `Depends` in der *Pfadoperation* fÃŧr `/token`: @@ -59,7 +59,7 @@ Importieren Sie zunächst `OAuth2PasswordRequestForm` und verwenden Sie es als A * Dem `username`. * Dem `password`. * Einem optionalen `scope`-Feld als langem String, bestehend aus durch Leerzeichen getrennten Strings. -* Einem optionalen `grant_type` („Art der Anmeldung“). +* Einem optionalen `grant_type`. /// tip | Tipp @@ -72,7 +72,7 @@ Wenn Sie es erzwingen mÃŧssen, verwenden Sie `OAuth2PasswordRequestFormStrict` a * Eine optionale `client_id` (benÃļtigen wir fÃŧr unser Beispiel nicht). * Ein optionales `client_secret` (benÃļtigen wir fÃŧr unser Beispiel nicht). -/// info +/// info | Info `OAuth2PasswordRequestForm` ist keine spezielle Klasse fÃŧr **FastAPI**, so wie `OAuth2PasswordBearer`. @@ -84,7 +84,7 @@ Da es sich jedoch um einen häufigen Anwendungsfall handelt, wird er zur Vereinf /// -### Die Formulardaten verwenden +### Die Formulardaten verwenden { #use-the-form-data } /// tip | Tipp @@ -102,7 +102,7 @@ FÃŧr den Fehler verwenden wir die Exception `HTTPException`: {* ../../docs_src/security/tutorial003_an_py310.py hl[3,79:81] *} -### Das Passwort ÃŧberprÃŧfen +### Das Passwort ÃŧberprÃŧfen { #check-the-password } Zu diesem Zeitpunkt liegen uns die Benutzerdaten aus unserer Datenbank vor, das Passwort haben wir jedoch noch nicht ÃŧberprÃŧft. @@ -112,7 +112,7 @@ Sie sollten niemals Klartext-PasswÃļrter speichern, daher verwenden wir ein (gef Wenn die PasswÃļrter nicht Ãŧbereinstimmen, geben wir denselben Fehler zurÃŧck. -#### Passwort-Hashing +#### Passwort-Hashing { #password-hashing } „Hashing“ bedeutet: Konvertieren eines Inhalts (in diesem Fall eines Passworts) in eine Folge von Bytes (ein schlichter String), die wie Kauderwelsch aussieht. @@ -120,7 +120,7 @@ Immer wenn Sie genau den gleichen Inhalt (genau das gleiche Passwort) Ãŧbergeben Sie kÃļnnen jedoch nicht vom Kauderwelsch zurÃŧck zum Passwort konvertieren. -##### Warum Passwort-Hashing verwenden? +##### Warum Passwort-Hashing verwenden? { #why-use-password-hashing } Wenn Ihre Datenbank gestohlen wird, hat der Dieb nicht die Klartext-PasswÃļrter Ihrer Benutzer, sondern nur die Hashes. @@ -128,7 +128,7 @@ Der Dieb kann also nicht versuchen, die gleichen PasswÃļrter in einem anderen Sy {* ../../docs_src/security/tutorial003_an_py310.py hl[82:85] *} -#### Über `**user_dict` +#### Über `**user_dict` { #about-user-dict } `UserInDB(**user_dict)` bedeutet: @@ -144,15 +144,15 @@ UserInDB( ) ``` -/// info +/// info | Info -Eine ausfÃŧhrlichere Erklärung von `**user_dict` finden Sie in [der Dokumentation fÃŧr **Extra Modelle**](../extra-models.md#uber-user_indict){.internal-link target=_blank}. +Eine ausfÃŧhrlichere Erklärung von `**user_dict` finden Sie in [der Dokumentation fÃŧr **Extra Modelle**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}. /// -## Den Token zurÃŧckgeben +## Den Token zurÃŧckgeben { #return-the-token } -Die Response des `token`-Endpunkts muss ein JSON-Objekt sein. +Die Response des `token`-Endpunkts muss ein JSON-Objekt sein. Es sollte einen `token_type` haben. Da wir in unserem Fall „Bearer“-Token verwenden, sollte der Token-Typ "`bearer`" sein. @@ -182,7 +182,7 @@ Den Rest erledigt **FastAPI** fÃŧr Sie. /// -## Die Abhängigkeiten aktualisieren +## Die Abhängigkeiten aktualisieren { #update-the-dependencies } Jetzt werden wir unsere Abhängigkeiten aktualisieren. @@ -196,7 +196,7 @@ In unserem Endpunkt erhalten wir also nur dann einen Benutzer, wenn der Benutzer {* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *} -/// info +/// info | Info Der zusätzliche Header `WWW-Authenticate` mit dem Wert `Bearer`, den wir hier zurÃŧckgeben, ist ebenfalls Teil der Spezifikation. @@ -214,11 +214,11 @@ Das ist der Vorteil von Standards ... /// -## Es in Aktion sehen +## Es in Aktion sehen { #see-it-in-action } Öffnen Sie die interaktive Dokumentation: http://127.0.0.1:8000/docs. -### Authentifizieren +### Authentifizieren { #authenticate } Klicken Sie auf den Button „Authorize“. @@ -234,7 +234,7 @@ Nach der Authentifizierung im System sehen Sie Folgendes: -### Die eigenen Benutzerdaten ansehen +### Die eigenen Benutzerdaten ansehen { #get-your-own-user-data } Verwenden Sie nun die Operation `GET` mit dem Pfad `/users/me`. @@ -260,7 +260,7 @@ Wenn Sie auf das Schlosssymbol klicken und sich abmelden und dann den gleichen V } ``` -### Inaktiver Benutzer +### Inaktiver Benutzer { #inactive-user } Versuchen Sie es nun mit einem inaktiven Benutzer und authentisieren Sie sich mit: @@ -278,7 +278,7 @@ Sie erhalten die Fehlermeldung „Inactive user“: } ``` -## Zusammenfassung +## Zusammenfassung { #recap } Sie verfÃŧgen jetzt Ãŧber die Tools, um ein vollständiges Sicherheitssystem basierend auf `username` und `password` fÃŧr Ihre API zu implementieren. diff --git a/docs/de/docs/tutorial/sql-databases.md b/docs/de/docs/tutorial/sql-databases.md new file mode 100644 index 000000000..cf9731aee --- /dev/null +++ b/docs/de/docs/tutorial/sql-databases.md @@ -0,0 +1,357 @@ +# SQL (Relationale) Datenbanken { #sql-relational-databases } + +**FastAPI** erfordert nicht, dass Sie eine SQL (relationale) Datenbank verwenden. Sondern Sie kÃļnnen **jede beliebige Datenbank** verwenden, die Sie mÃļchten. + +Hier werden wir ein Beispiel mit SQLModel sehen. + +**SQLModel** basiert auf SQLAlchemy und Pydantic. Es wurde vom selben Autor wie **FastAPI** entwickelt, um die perfekte Ergänzung fÃŧr FastAPI-Anwendungen zu sein, die **SQL-Datenbanken** verwenden mÃŧssen. + +/// tip | Tipp + +Sie kÃļnnten jede andere SQL- oder NoSQL-Datenbankbibliothek verwenden, die Sie mÃļchten (in einigen Fällen als „ORMs“ bezeichnet), FastAPI zwingt Sie nicht, irgendetwas zu verwenden. 😎 + +/// + +Da SQLModel auf SQLAlchemy basiert, kÃļnnen Sie problemlos **jede von SQLAlchemy unterstÃŧtzte Datenbank** verwenden (was auch bedeutet, dass sie von SQLModel unterstÃŧtzt werden), wie: + +* PostgreSQL +* MySQL +* SQLite +* Oracle +* Microsoft SQL Server, usw. + +In diesem Beispiel verwenden wir **SQLite**, da es eine einzelne Datei verwendet und Python integrierte UnterstÃŧtzung bietet. Sie kÃļnnen also dieses Beispiel kopieren und direkt ausfÃŧhren. + +Später, fÃŧr Ihre Produktionsanwendung, mÃļchten Sie mÃļglicherweise einen Datenbankserver wie **PostgreSQL** verwenden. + +/// tip | Tipp + +Es gibt einen offiziellen Projektgenerator mit **FastAPI** und **PostgreSQL**, einschließlich eines Frontends und weiterer Tools: https://github.com/fastapi/full-stack-fastapi-template + +/// + +Dies ist ein sehr einfaches und kurzes Tutorial. Wenn Sie mehr Ãŧber Datenbanken im Allgemeinen, Ãŧber SQL oder fortgeschrittenere Funktionen erfahren mÃļchten, besuchen Sie die SQLModel-Dokumentation. + +## `SQLModel` installieren { #install-sqlmodel } + +Stellen Sie zunächst sicher, dass Sie Ihre [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} erstellen, sie aktivieren und dann `sqlmodel` installieren: + +
+ +```console +$ pip install sqlmodel +---> 100% +``` + +
+ +## Die App mit einem einzelnen Modell erstellen { #create-the-app-with-a-single-model } + +Wir erstellen zuerst die einfachste erste Version der App mit einem einzigen **SQLModel**-Modell. + +Später werden wir sie verbessern, indem wir unter der Haube **mehrere Modelle** verwenden, um Sicherheit und Vielseitigkeit zu erhÃļhen. 🤓 + +### Modelle erstellen { #create-models } + +Importieren Sie `SQLModel` und erstellen Sie ein Datenbankmodell: + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} + +Die `Hero`-Klasse ist einem Pydantic-Modell sehr ähnlich (faktisch ist sie darunter tatsächlich *ein Pydantic-Modell*). + +Es gibt ein paar Unterschiede: + +* `table=True` sagt SQLModel, dass dies ein *Tabellenmodell* ist, es soll eine **Tabelle** in der SQL-Datenbank darstellen, es ist nicht nur ein *Datenmodell* (wie es jede andere reguläre Pydantic-Klasse wäre). + +* `Field(primary_key=True)` sagt SQLModel, dass die `id` der **PrimärschlÃŧssel** in der SQL-Datenbank ist (Sie kÃļnnen mehr Ãŧber SQL-PrimärschlÃŧssel in der SQLModel-Dokumentation erfahren). + + Durch das Festlegen des Typs als `int | None` wird SQLModel wissen, dass diese Spalte ein `INTEGER` in der SQL-Datenbank sein sollte und dass sie `NULLABLE` sein sollte. + +* `Field(index=True)` sagt SQLModel, dass es einen **SQL-Index** fÃŧr diese Spalte erstellen soll, was schnelleres Suchen in der Datenbank ermÃļglicht, wenn Daten mittels dieser Spalte gefiltert werden. + + SQLModel wird verstehen, dass etwas, das als `str` deklariert ist, eine SQL-Spalte des Typs `TEXT` (oder `VARCHAR`, abhängig von der Datenbank) sein wird. + +### Eine Engine erstellen { #create-an-engine } + +Eine SQLModel-`engine` (darunter ist es tatsächlich eine SQLAlchemy-`engine`) ist das, was die **Verbindungen** zur Datenbank hält. + +Sie hätten **ein einziges `engine`-Objekt** fÃŧr Ihren gesamten Code, um sich mit derselben Datenbank zu verbinden. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} + +Die Verwendung von `check_same_thread=False` erlaubt FastAPI, dieselbe SQLite-Datenbank in verschiedenen Threads zu verwenden. Dies ist notwendig, da **ein einzelner Request** **mehr als einen Thread** verwenden kÃļnnte (zum Beispiel in Abhängigkeiten). + +Keine Sorge, so wie der Code strukturiert ist, werden wir später sicherstellen, dass wir **eine einzige SQLModel-*Session* pro Request** verwenden, das ist eigentlich das, was `check_same_thread` erreichen mÃļchte. + +### Die Tabellen erstellen { #create-the-tables } + +Dann fÃŧgen wir eine Funktion hinzu, die `SQLModel.metadata.create_all(engine)` verwendet, um die **Tabellen fÃŧr alle *Tabellenmodelle* zu erstellen**. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} + +### Eine Session-Abhängigkeit erstellen { #create-a-session-dependency } + +Eine **`Session`** speichert die **Objekte im Speicher** und verfolgt alle Änderungen, die an den Daten vorgenommen werden mÃŧssen, dann **verwendet sie die `engine`**, um mit der Datenbank zu kommunizieren. + +Wir werden eine FastAPI **Abhängigkeit** mit `yield` erstellen, die eine neue `Session` fÃŧr jeden Request bereitstellt. Das ist es, was sicherstellt, dass wir eine einzige Session pro Request verwenden. 🤓 + +Dann erstellen wir eine `Annotated`-Abhängigkeit `SessionDep`, um den Rest des Codes zu vereinfachen, der diese Abhängigkeit nutzen wird. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *} + +### Die Datenbanktabellen beim Start erstellen { #create-database-tables-on-startup } + +Wir werden die Datenbanktabellen erstellen, wenn die Anwendung startet. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} + +Hier erstellen wir die Tabellen bei einem Anwendungsstart-Event. + +FÃŧr die Produktion wÃŧrden Sie wahrscheinlich ein Migrationsskript verwenden, das ausgefÃŧhrt wird, bevor Sie Ihre App starten. 🤓 + +/// tip | Tipp + +SQLModel wird Migrationstools haben, die Alembic wrappen, aber im Moment kÃļnnen Sie Alembic direkt verwenden. + +/// + +### Einen Helden erstellen { #create-a-hero } + +Da jedes SQLModel-Modell auch ein Pydantic-Modell ist, kÃļnnen Sie es in denselben **Typannotationen** verwenden, die Sie fÃŧr Pydantic-Modelle verwenden kÃļnnten. + +Wenn Sie beispielsweise einen Parameter vom Typ `Hero` deklarieren, wird er aus dem **JSON-Body** gelesen. + +Auf die gleiche Weise kÃļnnen Sie es als **RÃŧckgabetyp** der Funktion deklarieren, und dann wird die Form der Daten in der automatischen API-Dokumentation angezeigt. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} + +Hier verwenden wir die `SessionDep`-Abhängigkeit (eine `Session`), um den neuen `Hero` zur `Session`-Instanz hinzuzufÃŧgen, die Änderungen an der Datenbank zu committen, die Daten im `hero` zu aktualisieren und ihn anschließend zurÃŧckzugeben. + +### Helden lesen { #read-heroes } + +Wir kÃļnnen `Hero`s aus der Datenbank mit einem `select()` **lesen**. Wir kÃļnnen ein `limit` und `offset` hinzufÃŧgen, um die Ergebnisse zu paginieren. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} + +### Einen Helden lesen { #read-one-hero } + +Wir kÃļnnen einen einzelnen `Hero` **lesen**. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} + +### Einen Helden lÃļschen { #delete-a-hero } + +Wir kÃļnnen auch einen `Hero` **lÃļschen**. + +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} + +### Die App ausfÃŧhren { #run-the-app } + +Sie kÃļnnen die App ausfÃŧhren: + +
+ +```console +$ fastapi dev main.py + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +Gehen Sie dann zur `/docs`-UI, Sie werden sehen, dass **FastAPI** diese **Modelle** verwendet, um die API zu **dokumentieren**, und es wird sie auch verwenden, um die Daten zu **serialisieren** und zu **validieren**. + +
+ +
+ +## Die App mit mehreren Modellen aktualisieren { #update-the-app-with-multiple-models } + +Jetzt lassen Sie uns diese App ein wenig **refaktorisieren**, um die **Sicherheit** und **Vielseitigkeit** zu erhÃļhen. + +Wenn Sie die vorherige App ÃŧberprÃŧfen, kÃļnnen Sie in der UI sehen, dass sie bis jetzt dem Client erlaubt, die `id` des zu erstellenden `Hero` zu bestimmen. 😱 + +Das sollten wir nicht zulassen, sie kÃļnnten eine `id` Ãŧberschreiben, die wir bereits in der DB zugewiesen haben. Die Entscheidung Ãŧber die `id` sollte vom **Backend** oder der **Datenbank** getroffen werden, **nicht vom Client**. + +Außerdem erstellen wir einen `secret_name` fÃŧr den Helden, aber bisher geben wir ihn Ãŧberall zurÃŧck, das ist nicht sehr **geheim** ... 😅 + +Wir werden diese Dinge beheben, indem wir ein paar **zusätzliche Modelle** hinzufÃŧgen. Hier wird SQLModel glänzen. ✨ + +### Mehrere Modelle erstellen { #create-multiple-models } + +In **SQLModel** ist jede Modellklasse, die `table=True` hat, ein **Tabellenmodell**. + +Und jede Modellklasse, die `table=True` nicht hat, ist ein **Datenmodell**, diese sind tatsächlich nur Pydantic-Modelle (mit ein paar kleinen zusätzlichen Funktionen). 🤓 + +Mit SQLModel kÃļnnen wir **Vererbung** verwenden, um **doppelte Felder** in allen Fällen zu **vermeiden**. + +#### `HeroBase` – die Basisklasse { #herobase-the-base-class } + +Fangen wir mit einem `HeroBase`-Modell an, das alle **Felder hat, die von allen Modellen geteilt werden**: + +* `name` +* `age` + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} + +#### `Hero` – das *Tabellenmodell* { #hero-the-table-model } + +Dann erstellen wir `Hero`, das tatsächliche *Tabellenmodell*, mit den **zusätzlichen Feldern**, die nicht immer in den anderen Modellen enthalten sind: + +* `id` +* `secret_name` + +Da `Hero` von `HeroBase` erbt, hat es **auch** die **Felder**, die in `HeroBase` deklariert sind, also sind alle Felder von `Hero`: + +* `id` +* `name` +* `age` +* `secret_name` + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} + +#### `HeroPublic` – das Ãļffentliche *Datenmodell* { #heropublic-the-public-data-model } + +Als nächstes erstellen wir ein `HeroPublic`-Modell, das an die API-Clients **zurÃŧckgegeben** wird. + +Es hat dieselben Felder wie `HeroBase`, sodass es `secret_name` nicht enthält. + +Endlich ist die Identität unserer Helden geschÃŧtzt! đŸĨˇ + +Es deklariert auch `id: int` erneut. Indem wir dies tun, machen wir einen **Vertrag** mit den API-Clients, damit sie immer damit rechnen kÃļnnen, dass die `id` vorhanden ist und ein `int` ist (sie wird niemals `None` sein). + +/// tip | Tipp + +Es ist sehr nÃŧtzlich fÃŧr die API-Clients, wenn das RÃŧckgabemodell sicherstellt, dass ein Wert immer verfÃŧgbar und immer `int` (nicht `None`) ist, sie kÃļnnen viel einfacheren Code schreiben, wenn sie diese Sicherheit haben. + +Auch **automatisch generierte Clients** werden einfachere Schnittstellen haben, damit die Entwickler, die mit Ihrer API kommunizieren, viel mehr Freude an der Arbeit mit Ihrer API haben kÃļnnen. 😎 + +/// + +Alle Felder in `HeroPublic` sind dieselben wie in `HeroBase`, mit `id`, das als `int` (nicht `None`) deklariert ist: + +* `id` +* `name` +* `age` + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} + +#### `HeroCreate` – das *Datenmodell* zum Erstellen eines Helden { #herocreate-the-data-model-to-create-a-hero } + +Nun erstellen wir ein `HeroCreate`-Modell, das die Daten der Clients **validiert**. + +Es hat dieselben Felder wie `HeroBase`, und es hat auch `secret_name`. + +Wenn die Clients **einen neuen Helden erstellen**, senden sie jetzt den `secret_name`, er wird in der Datenbank gespeichert, aber diese geheimen Namen werden den API-Clients nicht zurÃŧckgegeben. + +/// tip | Tipp + +So wÃŧrden Sie **PasswÃļrter** handhaben. Empfangen Sie sie, aber geben Sie sie nicht in der API zurÃŧck. + +Sie wÃŧrden auch die Werte der PasswÃļrter **hashen**, bevor Sie sie speichern, und sie **niemals im Klartext** speichern. + +/// + +Die Felder von `HeroCreate` sind: + +* `name` +* `age` +* `secret_name` + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} + +#### `HeroUpdate` – das *Datenmodell* zum Aktualisieren eines Helden { #heroupdate-the-data-model-to-update-a-hero } + +In der vorherigen Version der App hatten wir keine MÃļglichkeit, einen Helden **zu aktualisieren**, aber jetzt mit **mehreren Modellen** kÃļnnen wir es. 🎉 + +Das `HeroUpdate`-*Datenmodell* ist etwas Besonderes, es hat **die selben Felder**, die benÃļtigt werden, um einen neuen Helden zu erstellen, aber alle Felder sind **optional** (sie haben alle einen Defaultwert). Auf diese Weise, wenn Sie einen Helden aktualisieren, kÃļnnen Sie nur die Felder senden, die Sie aktualisieren mÃļchten. + +Da sich tatsächlich **alle Felder ändern** (der Typ enthält jetzt `None` und sie haben jetzt einen Standardwert von `None`), mÃŧssen wir sie erneut **deklarieren**. + +Wir mÃŧssen wirklich nicht von `HeroBase` erben, weil wir alle Felder neu deklarieren. Ich lasse es aus KonsistenzgrÃŧnden erben, aber das ist nicht notwendig. Es ist mehr eine Frage des persÃļnlichen Geschmacks. 🤷 + +Die Felder von `HeroUpdate` sind: + +* `name` +* `age` +* `secret_name` + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} + +### Mit `HeroCreate` erstellen und ein `HeroPublic` zurÃŧckgeben { #create-with-herocreate-and-return-a-heropublic } + +Nun, da wir **mehrere Modelle** haben, kÃļnnen wir die Teile der App aktualisieren, die sie verwenden. + +Wir empfangen im Request ein `HeroCreate`-*Datenmodell* und daraus erstellen wir ein `Hero`-*Tabellenmodell*. + +Dieses neue *Tabellenmodell* `Hero` wird die vom Client gesendeten Felder haben und zusätzlich eine `id`, die von der Datenbank generiert wird. + +Dann geben wir das gleiche *Tabellenmodell* `Hero` von der Funktion zurÃŧck. Aber da wir das `response_model` mit dem `HeroPublic`-*Datenmodell* deklarieren, wird **FastAPI** `HeroPublic` verwenden, um die Daten zu validieren und zu serialisieren. + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} + +/// tip | Tipp + +Jetzt verwenden wir `response_model=HeroPublic` anstelle der **RÃŧckgabetyp-Annotation** `-> HeroPublic`, weil der Wert, den wir zurÃŧckgeben, tatsächlich *kein* `HeroPublic` ist. + +Wenn wir `-> HeroPublic` deklariert hätten, wÃŧrden Ihr Editor und Linter (zu Recht) reklamieren, dass Sie ein `Hero` anstelle eines `HeroPublic` zurÃŧckgeben. + +Durch die Deklaration in `response_model` sagen wir **FastAPI**, dass es seine Aufgabe erledigen soll, ohne die Typannotationen und die Hilfe von Ihrem Editor und anderen Tools zu beeinträchtigen. + +/// + +### Helden mit `HeroPublic` lesen { #read-heroes-with-heropublic } + +Wir kÃļnnen dasselbe wie zuvor tun, um `Hero`s zu **lesen**, und erneut verwenden wir `response_model=list[HeroPublic]`, um sicherzustellen, dass die Daten ordnungsgemäß validiert und serialisiert werden. + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} + +### Einen einzelnen Helden mit `HeroPublic` lesen { #read-one-hero-with-heropublic } + +Wir kÃļnnen einen einzelnen Helden **lesen**: + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} + +### Einen Helden mit `HeroUpdate` aktualisieren { #update-a-hero-with-heroupdate } + +Wir kÃļnnen einen Helden **aktualisieren**. DafÃŧr verwenden wir eine HTTP-`PATCH`-Operation. + +Und im Code erhalten wir ein `dict` mit allen Daten, die vom Client gesendet wurden, **nur die Daten, die vom Client gesendet wurden**, unter Ausschluss von Werten, die dort nur als Defaultwerte vorhanden wären. Um dies zu tun, verwenden wir `exclude_unset=True`. Das ist der Haupttrick. đŸĒ„ + +Dann verwenden wir `hero_db.sqlmodel_update(hero_data)`, um die `hero_db` mit den Daten aus `hero_data` zu aktualisieren. + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} + +### Einen Helden wieder lÃļschen { #delete-a-hero-again } + +Das **LÃļschen** eines Helden bleibt ziemlich gleich. + +Wir werden dieses Mal nicht dem Wunsch nachgeben, alles zu refaktorisieren. 😅 + +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} + +### Die App erneut ausfÃŧhren { #run-the-app-again } + +Sie kÃļnnen die App erneut ausfÃŧhren: + +
+ +```console +$ fastapi dev main.py + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +Wenn Sie zur `/docs`-API-UI gehen, werden Sie sehen, dass sie jetzt aktualisiert ist und nicht mehr erwarten wird, die `id` vom Client beim Erstellen eines Helden zu erhalten, usw. + +
+ +
+ +## Zusammenfassung { #recap } + +Sie kÃļnnen **SQLModel** verwenden, um mit einer SQL-Datenbank zu interagieren und den Code mit *Datenmodellen* und *Tabellenmodellen* zu vereinfachen. + +Sie kÃļnnen viel mehr in der **SQLModel**-Dokumentation lernen, es gibt ein längeres Mini-Tutorial zur Verwendung von SQLModel mit **FastAPI**. 🚀 diff --git a/docs/de/docs/tutorial/static-files.md b/docs/de/docs/tutorial/static-files.md index 50e86d68e..5a6cfcb2b 100644 --- a/docs/de/docs/tutorial/static-files.md +++ b/docs/de/docs/tutorial/static-files.md @@ -1,8 +1,8 @@ -# Statische Dateien +# Statische Dateien { #static-files } Mit `StaticFiles` kÃļnnen Sie statische Dateien aus einem Verzeichnis automatisch bereitstellen. -## `StaticFiles` verwenden +## `StaticFiles` verwenden { #use-staticfiles } * Importieren Sie `StaticFiles`. * „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad. @@ -17,7 +17,7 @@ Sie kÃļnnten auch `from starlette.staticfiles import StaticFiles` verwenden. /// -### Was ist „Mounten“? +### Was ist „Mounten“ { #what-is-mounting } „Mounten“ bedeutet das HinzufÃŧgen einer vollständigen „unabhängigen“ Anwendung an einem bestimmten Pfad, die sich dann um die Handhabung aller Unterpfade kÃŧmmert. @@ -25,7 +25,7 @@ Dies unterscheidet sich von der Verwendung eines `APIRouter`, da eine gemountete Weitere Informationen hierzu finden Sie im [Handbuch fÃŧr fortgeschrittene Benutzer](../advanced/index.md){.internal-link target=_blank}. -## Einzelheiten +## Einzelheiten { #details } Das erste `"/static"` bezieht sich auf den Unterpfad, auf dem diese „Unteranwendung“ „gemountet“ wird. Daher wird jeder Pfad, der mit `"/static"` beginnt, von ihr verarbeitet. @@ -33,8 +33,8 @@ Das `directory="static"` bezieht sich auf den Namen des Verzeichnisses, das Ihre Das `name="static"` gibt dieser Unteranwendung einen Namen, der intern von **FastAPI** verwendet werden kann. -Alle diese Parameter kÃļnnen anders als "`static`" lauten, passen Sie sie an die BedÃŧrfnisse und spezifischen Details Ihrer eigenen Anwendung an. +Alle diese Parameter kÃļnnen anders als „`static`“ lauten, passen Sie sie an die BedÃŧrfnisse und spezifischen Details Ihrer eigenen Anwendung an. -## Weitere Informationen +## Weitere Informationen { #more-info } Weitere Details und Optionen finden Sie in der Dokumentation von Starlette zu statischen Dateien. diff --git a/docs/de/docs/tutorial/testing.md b/docs/de/docs/tutorial/testing.md index e7c1dda95..75ee9fade 100644 --- a/docs/de/docs/tutorial/testing.md +++ b/docs/de/docs/tutorial/testing.md @@ -1,18 +1,22 @@ -# Testen +# Testen { #testing } Dank Starlette ist das Testen von **FastAPI**-Anwendungen einfach und macht Spaß. -Es basiert auf HTTPX, welches wiederum auf der Grundlage von requests konzipiert wurde, es ist also sehr vertraut und intuitiv. +Es basiert auf HTTPX, welches wiederum auf der Grundlage von Requests konzipiert wurde, es ist also sehr vertraut und intuitiv. Damit kÃļnnen Sie pytest direkt mit **FastAPI** verwenden. -## Verwendung von `TestClient` +## `TestClient` verwenden { #using-testclient } -/// info +/// info | Info Um `TestClient` zu verwenden, installieren Sie zunächst `httpx`. -Z. B. `pip install httpx`. +Erstellen Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank}, aktivieren Sie sie und installieren Sie es dann, z. B.: + +```console +$ pip install httpx +``` /// @@ -48,17 +52,17 @@ Sie kÃļnnten auch `from starlette.testclient import TestClient` verwenden. /// tip | Tipp -Wenn Sie in Ihren Tests neben dem Senden von Anfragen an Ihre FastAPI-Anwendung auch `async`-Funktionen aufrufen mÃļchten (z. B. asynchrone Datenbankfunktionen), werfen Sie einen Blick auf die [Async-Tests](../advanced/async-tests.md){.internal-link target=_blank} im Handbuch fÃŧr fortgeschrittene Benutzer. +Wenn Sie in Ihren Tests neben dem Senden von Requests an Ihre FastAPI-Anwendung auch `async`-Funktionen aufrufen mÃļchten (z. B. asynchrone Datenbankfunktionen), werfen Sie einen Blick auf die [Async-Tests](../advanced/async-tests.md){.internal-link target=_blank} im Handbuch fÃŧr fortgeschrittene Benutzer. /// -## Tests separieren +## Tests separieren { #separating-tests } In einer echten Anwendung wÃŧrden Sie Ihre Tests wahrscheinlich in einer anderen Datei haben. Und Ihre **FastAPI**-Anwendung kÃļnnte auch aus mehreren Dateien/Modulen, usw. bestehen. -### **FastAPI** Anwendungsdatei +### **FastAPI** Anwendungsdatei { #fastapi-app-file } Nehmen wir an, Sie haben eine Dateistruktur wie in [GrÃļßere Anwendungen](bigger-applications.md){.internal-link target=_blank} beschrieben: @@ -75,7 +79,7 @@ In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung: {* ../../docs_src/app_testing/main.py *} -### Testdatei +### Testdatei { #testing-file } Dann kÃļnnten Sie eine Datei `test_main.py` mit Ihren Tests haben. Sie kÃļnnte sich im selben Python-Package befinden (dasselbe Verzeichnis mit einer `__init__.py`-Datei): @@ -94,11 +98,11 @@ Da sich diese Datei im selben Package befindet, kÃļnnen Sie relative Importe ver ... und haben den Code fÃŧr die Tests wie zuvor. -## Testen: erweitertes Beispiel +## Testen: erweitertes Beispiel { #testing-extended-example } Nun erweitern wir dieses Beispiel und fÃŧgen weitere Details hinzu, um zu sehen, wie verschiedene Teile getestet werden. -### Erweiterte **FastAPI**-Anwendungsdatei +### Erweiterte **FastAPI**-Anwendungsdatei { #extended-fastapi-app-file } Fahren wir mit der gleichen Dateistruktur wie zuvor fort: @@ -170,7 +174,7 @@ Bevorzugen Sie die `Annotated`-Version, falls mÃļglich. //// -### Erweiterte Testdatei +### Erweiterte Testdatei { #extended-testing-file } Anschließend kÃļnnten Sie `test_main.py` mit den erweiterten Tests aktualisieren: @@ -184,14 +188,14 @@ Dann machen Sie in Ihren Tests einfach das gleiche. Z. B.: * Um einen *Pfad*- oder *Query*-Parameter zu Ãŧbergeben, fÃŧgen Sie ihn der URL selbst hinzu. -* Um einen JSON-Body zu Ãŧbergeben, Ãŧbergeben Sie ein Python-Objekt (z. B. ein `dict`) an den Parameter `json`. +* Um einen JSON-Body zu Ãŧbergeben, Ãŧbergeben Sie ein Python-Objekt (z. B. ein `dict`) an den Parameter `json`. * Wenn Sie *Formulardaten* anstelle von JSON senden mÃŧssen, verwenden Sie stattdessen den `data`-Parameter. * Um *Header* zu Ãŧbergeben, verwenden Sie ein `dict` im `headers`-Parameter. * FÃŧr *Cookies* ein `dict` im `cookies`-Parameter. Weitere Informationen zum Übergeben von Daten an das Backend (mithilfe von `httpx` oder dem `TestClient`) finden Sie in der HTTPX-Dokumentation. -/// info +/// info | Info Beachten Sie, dass der `TestClient` Daten empfängt, die nach JSON konvertiert werden kÃļnnen, keine Pydantic-Modelle. @@ -199,9 +203,11 @@ Wenn Sie ein Pydantic-Modell in Ihrem Test haben und dessen Daten während des T /// -## Tests ausfÃŧhren +## Tests ausfÃŧhren { #run-it } -Danach mÃŧssen Sie nur noch `pytest` installieren: +Danach mÃŧssen Sie nur noch `pytest` installieren. + +Erstellen Sie eine [virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank}, aktivieren Sie sie und installieren Sie es dann, z. B.:
diff --git a/docs/de/docs/virtual-environments.md b/docs/de/docs/virtual-environments.md new file mode 100644 index 000000000..497f1b44d --- /dev/null +++ b/docs/de/docs/virtual-environments.md @@ -0,0 +1,842 @@ +# Virtuelle Umgebungen { #virtual-environments } + +Wenn Sie an Python-Projekten arbeiten, sollten Sie wahrscheinlich eine **virtuelle Umgebung** (oder einen ähnlichen Mechanismus) verwenden, um die Packages, die Sie fÃŧr jedes Projekt installieren, zu isolieren. + +/// info | Info + +Wenn Sie bereits Ãŧber virtuelle Umgebungen Bescheid wissen, wie man sie erstellt und verwendet, mÃļchten Sie diesen Abschnitt vielleicht Ãŧberspringen. 🤓 + +/// + +/// tip | Tipp + +Eine **virtuelle Umgebung** unterscheidet sich von einer **Umgebungsvariable**. + +Eine **Umgebungsvariable** ist eine Variable im System, die von Programmen verwendet werden kann. + +Eine **virtuelle Umgebung** ist ein Verzeichnis mit einigen Dateien darin. + +/// + +/// info | Info + +Diese Seite wird Ihnen beibringen, wie Sie **virtuelle Umgebungen** verwenden und wie sie funktionieren. + +Wenn Sie bereit sind, ein **Tool zu verwenden, das alles fÃŧr Sie verwaltet** (einschließlich der Installation von Python), probieren Sie uv. + +/// + +## Ein Projekt erstellen { #create-a-project } + +Erstellen Sie zuerst ein Verzeichnis fÃŧr Ihr Projekt. + +Was ich normalerweise mache, ist, dass ich ein Verzeichnis namens `code` in meinem Home/Benutzerverzeichnis erstelle. + +Und darin erstelle ich ein Verzeichnis pro Projekt. + +
+ +```console +// Gehe zum Home-Verzeichnis +$ cd +// Erstelle ein Verzeichnis fÃŧr alle Ihre Code-Projekte +$ mkdir code +// Gehe in dieses Code-Verzeichnis +$ cd code +// Erstelle ein Verzeichnis fÃŧr dieses Projekt +$ mkdir awesome-project +// Gehe in dieses Projektverzeichnis +$ cd awesome-project +``` + +
+ +## Eine virtuelle Umgebung erstellen { #create-a-virtual-environment } + +Wenn Sie zum **ersten Mal** an einem Python-Projekt arbeiten, erstellen Sie eine virtuelle Umgebung **innerhalb Ihres Projekts**. + +/// tip | Tipp + +Sie mÃŧssen dies nur **einmal pro Projekt** tun, nicht jedes Mal, wenn Sie daran arbeiten. + +/// + +//// tab | `venv` + +Um eine virtuelle Umgebung zu erstellen, kÃļnnen Sie das `venv`-Modul verwenden, das mit Python geliefert wird. + +
+ +```console +$ python -m venv .venv +``` + +
+ +/// details | Was dieser Befehl bedeutet + +* `python`: das Programm namens `python` verwenden +* `-m`: ein Modul als Skript aufrufen, wir geben als nächstes an, welches Modul +* `venv`: das Modul namens `venv` verwenden, das normalerweise mit Python installiert wird +* `.venv`: die virtuelle Umgebung im neuen Verzeichnis `.venv` erstellen + +/// + +//// + +//// tab | `uv` + +Wenn Sie `uv` installiert haben, kÃļnnen Sie es verwenden, um eine virtuelle Umgebung zu erstellen. + +
+ +```console +$ uv venv +``` + +
+ +/// tip | Tipp + +Standardmäßig erstellt `uv` eine virtuelle Umgebung in einem Verzeichnis namens `.venv`. + +Aber Sie kÃļnnten es anpassen, indem Sie ein zusätzliches Argument mit dem Verzeichnisnamen Ãŧbergeben. + +/// + +//// + +Dieser Befehl erstellt eine neue virtuelle Umgebung in einem Verzeichnis namens `.venv`. + +/// details | `.venv` oder ein anderer Name + +Sie kÃļnnten die virtuelle Umgebung in einem anderen Verzeichnis erstellen, aber es ist eine Konvention, sie `.venv` zu nennen. + +/// + +## Die virtuelle Umgebung aktivieren { #activate-the-virtual-environment } + +Aktivieren Sie die neue virtuelle Umgebung, damit jeder Python-Befehl, den Sie ausfÃŧhren oder jedes Paket, das Sie installieren, diese Umgebung verwendet. + +/// tip | Tipp + +Tun Sie dies **jedes Mal**, wenn Sie eine **neue Terminalsitzung** starten, um an dem Projekt zu arbeiten. + +/// + +//// tab | Linux, macOS + +
+ +```console +$ source .venv/bin/activate +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +$ .venv\Scripts\Activate.ps1 +``` + +
+ +//// + +//// tab | Windows Bash + +Oder wenn Sie Bash fÃŧr Windows verwenden (z. B. Git Bash): + +
+ +```console +$ source .venv/Scripts/activate +``` + +
+ +//// + +/// tip | Tipp + +Jedes Mal, wenn Sie ein **neues Paket** in dieser Umgebung installieren, aktivieren Sie die Umgebung erneut. + +So stellen Sie sicher, dass, wenn Sie ein **Terminalprogramm (CLI)** verwenden, das durch dieses Paket installiert wurde, Sie das aus Ihrer virtuellen Umgebung verwenden und nicht eines, das global installiert ist, wahrscheinlich mit einer anderen Version als der, die Sie benÃļtigen. + +/// + +## Testen, ob die virtuelle Umgebung aktiv ist { #check-the-virtual-environment-is-active } + +Testen Sie, dass die virtuelle Umgebung aktiv ist (der vorherige Befehl funktioniert hat). + +/// tip | Tipp + +Dies ist **optional**, aber es ist eine gute MÃļglichkeit, **zu ÃŧberprÃŧfen**, ob alles wie erwartet funktioniert und Sie die beabsichtigte virtuelle Umgebung verwenden. + +/// + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +$ which python + +/home/user/code/awesome-project/.venv/bin/python +``` + +
+ +Wenn es das `python`-Binary in `.venv/bin/python` anzeigt, innerhalb Ihres Projekts (in diesem Fall `awesome-project`), dann hat es funktioniert. 🎉 + +//// + +//// tab | Windows PowerShell + +
+ +```console +$ Get-Command python + +C:\Users\user\code\awesome-project\.venv\Scripts\python +``` + +
+ +Wenn es das `python`-Binary in `.venv\Scripts\python` anzeigt, innerhalb Ihres Projekts (in diesem Fall `awesome-project`), dann hat es funktioniert. 🎉 + +//// + +## `pip` aktualisieren { #upgrade-pip } + +/// tip | Tipp + +Wenn Sie `uv` verwenden, wÃŧrden Sie das verwenden, um Dinge zu installieren anstelle von `pip`, sodass Sie `pip` nicht aktualisieren mÃŧssen. 😎 + +/// + +Wenn Sie `pip` verwenden, um Pakete zu installieren (es wird standardmäßig mit Python geliefert), sollten Sie es auf die neueste Version **aktualisieren**. + +Viele exotische Fehler beim Installieren eines Pakets werden einfach dadurch gelÃļst, dass zuerst `pip` aktualisiert wird. + +/// tip | Tipp + +Normalerweise wÃŧrden Sie dies **einmal** tun, unmittelbar nachdem Sie die virtuelle Umgebung erstellt haben. + +/// + +Stellen Sie sicher, dass die virtuelle Umgebung aktiv ist (mit dem obigen Befehl) und fÃŧhren Sie dann aus: + +
+ +```console +$ python -m pip install --upgrade pip + +---> 100% +``` + +
+ +## `.gitignore` hinzufÃŧgen { #add-gitignore } + +Wenn Sie **Git** verwenden (was Sie sollten), fÃŧgen Sie eine `.gitignore`-Datei hinzu, um alles in Ihrem `.venv` von Git auszuschließen. + +/// tip | Tipp + +Wenn Sie `uv` verwendet haben, um die virtuelle Umgebung zu erstellen, hat es dies bereits fÃŧr Sie getan, Sie kÃļnnen diesen Schritt Ãŧberspringen. 😎 + +/// + +/// tip | Tipp + +Tun Sie dies **einmal**, unmittelbar nachdem Sie die virtuelle Umgebung erstellt haben. + +/// + +
+ +```console +$ echo "*" > .venv/.gitignore +``` + +
+ +/// details | Was dieser Befehl bedeutet + +* `echo "*"`: wird den Text `*` im Terminal „drucken“ (der nächste Teil ändert das ein wenig) +* `>`: alles, was durch den Befehl links von `>` im Terminal ausgegeben wird, sollte nicht gedruckt, sondern stattdessen in die Datei geschrieben werden, die rechts von `>` kommt +* `.gitignore`: der Name der Datei, in die der Text geschrieben werden soll + +Und `*` bedeutet fÃŧr Git „alles“. Also wird alles im `.venv`-Verzeichnis ignoriert. + +Dieser Befehl erstellt eine Datei `.gitignore` mit dem Inhalt: + +```gitignore +* +``` + +/// + +## Pakete installieren { #install-packages } + +Nachdem Sie die Umgebung aktiviert haben, kÃļnnen Sie Pakete darin installieren. + +/// tip | Tipp + +Tun Sie dies **einmal**, wenn Sie die Pakete installieren oder aktualisieren, die Ihr Projekt benÃļtigt. + +Wenn Sie eine Version aktualisieren oder ein neues Paket hinzufÃŧgen mÃŧssen, wÃŧrden Sie **dies erneut tun**. + +/// + +### Pakete direkt installieren { #install-packages-directly } + +Wenn Sie es eilig haben und keine Datei verwenden mÃļchten, um die Paketanforderungen Ihres Projekts zu deklarieren, kÃļnnen Sie sie direkt installieren. + +/// tip | Tipp + +Es ist eine (sehr) gute Idee, die Pakete und Versionen, die Ihr Programm benÃļtigt, in einer Datei zu speichern (zum Beispiel `requirements.txt` oder `pyproject.toml`). + +/// + +//// tab | `pip` + +
+ +```console +$ pip install "fastapi[standard]" + +---> 100% +``` + +
+ +//// + +//// tab | `uv` + +Wenn Sie `uv` haben: + +
+ +```console +$ uv pip install "fastapi[standard]" +---> 100% +``` + +
+ +//// + +### Installation von `requirements.txt` { #install-from-requirements-txt } + +Wenn Sie eine `requirements.txt` haben, kÃļnnen Sie diese nun verwenden, um deren Pakete zu installieren. + +//// tab | `pip` + +
+ +```console +$ pip install -r requirements.txt +---> 100% +``` + +
+ +//// + +//// tab | `uv` + +Wenn Sie `uv` haben: + +
+ +```console +$ uv pip install -r requirements.txt +---> 100% +``` + +
+ +//// + +/// details | `requirements.txt` + +Eine `requirements.txt` mit einigen Paketen kÃļnnte folgendermaßen aussehen: + +```requirements.txt +fastapi[standard]==0.113.0 +pydantic==2.8.0 +``` + +/// + +## Ihr Programm ausfÃŧhren { #run-your-program } + +Nachdem Sie die virtuelle Umgebung aktiviert haben, kÃļnnen Sie Ihr Programm ausfÃŧhren, und es wird das Python innerhalb Ihrer virtuellen Umgebung mit den Paketen verwenden, die Sie dort installiert haben. + +
+ +```console +$ python main.py + +Hello World +``` + +
+ +## Ihren Editor konfigurieren { #configure-your-editor } + +Sie wÃŧrden wahrscheinlich einen Editor verwenden, stellen Sie sicher, dass Sie ihn so konfigurieren, dass er dieselbe virtuelle Umgebung verwendet, die Sie erstellt haben (er wird sie wahrscheinlich automatisch erkennen), sodass Sie Autovervollständigungen und Inline-Fehler erhalten kÃļnnen. + +Zum Beispiel: + +* VS Code +* PyCharm + +/// tip | Tipp + +Normalerweise mÃŧssen Sie dies nur **einmal** tun, wenn Sie die virtuelle Umgebung erstellen. + +/// + +## Die virtuelle Umgebung deaktivieren { #deactivate-the-virtual-environment } + +Sobald Sie mit der Arbeit an Ihrem Projekt fertig sind, kÃļnnen Sie die virtuelle Umgebung **deaktivieren**. + +
+ +```console +$ deactivate +``` + +
+ +Auf diese Weise, wenn Sie `python` ausfÃŧhren, wird nicht versucht, es aus dieser virtuellen Umgebung mit den dort installierten Paketen auszufÃŧhren. + +## Bereit zu arbeiten { #ready-to-work } + +Jetzt sind Sie bereit, mit Ihrem Projekt zu arbeiten. + +/// tip | Tipp + +MÃļchten Sie verstehen, was das alles oben bedeutet? + +Lesen Sie weiter. 👇🤓 + +/// + +## Warum virtuelle Umgebungen { #why-virtual-environments } + +Um mit FastAPI zu arbeiten, mÃŧssen Sie Python installieren. + +Danach mÃŧssen Sie FastAPI und alle anderen Pakete, die Sie verwenden mÃļchten, **installieren**. + +Um Pakete zu installieren, wÃŧrden Sie normalerweise den `pip`-Befehl verwenden, der mit Python geliefert wird (oder ähnliche Alternativen). + +Wenn Sie jedoch `pip` direkt verwenden, werden die Pakete in Ihrer **globalen Python-Umgebung** (der globalen Installation von Python) installiert. + +### Das Problem { #the-problem } + +Was ist also das Problem beim Installieren von Paketen in der globalen Python-Umgebung? + +Irgendwann werden Sie wahrscheinlich viele verschiedene Programme schreiben, die von **verschiedenen Paketen** abhängen. Und einige dieser Projekte, an denen Sie arbeiten, werden von **verschiedenen Versionen** desselben Pakets abhängen. 😱 + +Zum Beispiel kÃļnnten Sie ein Projekt namens `philosophers-stone` erstellen, dieses Programm hängt von einem anderen Paket namens **`harry`, Version `1`** ab. Also mÃŧssen Sie `harry` installieren. + +```mermaid +flowchart LR + stone(philosophers-stone) -->|benÃļtigt| harry-1[harry v1] +``` + +Dann erstellen Sie zu einem späteren Zeitpunkt ein weiteres Projekt namens `prisoner-of-azkaban`, und dieses Projekt hängt ebenfalls von `harry` ab, aber dieses Projekt benÃļtigt **`harry` Version `3`**. + +```mermaid +flowchart LR + azkaban(prisoner-of-azkaban) --> |benÃļtigt| harry-3[harry v3] +``` + +Aber jetzt ist das Problem, wenn Sie die Pakete global (in der globalen Umgebung) installieren anstatt in einer lokalen **virtuellen Umgebung**, mÃŧssen Sie wählen, welche Version von `harry` zu installieren ist. + +Wenn Sie `philosophers-stone` ausfÃŧhren mÃļchten, mÃŧssen Sie zuerst `harry` Version `1` installieren, zum Beispiel mit: + +
+ +```console +$ pip install "harry==1" +``` + +
+ +Und dann hätten Sie `harry` Version `1` in Ihrer globalen Python-Umgebung installiert. + +```mermaid +flowchart LR + subgraph global[globale Umgebung] + harry-1[harry v1] + end + subgraph stone-project[philosophers-stone-Projekt] + stone(philosophers-stone) -->|benÃļtigt| harry-1 + end +``` + +Aber dann, wenn Sie `prisoner-of-azkaban` ausfÃŧhren mÃļchten, mÃŧssen Sie `harry` Version `1` deinstallieren und `harry` Version `3` installieren (oder einfach die Version `3` installieren, was die Version `1` automatisch deinstallieren wÃŧrde). + +
+ +```console +$ pip install "harry==3" +``` + +
+ +Und dann hätten Sie `harry` Version `3` in Ihrer globalen Python-Umgebung installiert. + +Und wenn Sie versuchen, `philosophers-stone` erneut auszufÃŧhren, besteht die MÃļglichkeit, dass es **nicht funktioniert**, weil es `harry` Version `1` benÃļtigt. + +```mermaid +flowchart LR + subgraph global[globale Umgebung] + harry-1[harry v1] + style harry-1 fill:#ccc,stroke-dasharray: 5 5 + harry-3[harry v3] + end + subgraph stone-project[philosophers-stone-Projekt] + stone(philosophers-stone) -.-x|â›”ī¸| harry-1 + end + subgraph azkaban-project[prisoner-of-azkaban-Projekt] + azkaban(prisoner-of-azkaban) --> |benÃļtigt| harry-3 + end +``` + +/// tip | Tipp + +Es ist sehr Ãŧblich in Python-Paketen, alles zu versuchen, **Breaking Changes** in **neuen Versionen** zu vermeiden, aber es ist besser, auf Nummer sicher zu gehen und neue Versionen absichtlich zu installieren und wenn Sie die Tests ausfÃŧhren kÃļnnen, sicherzustellen, dass alles korrekt funktioniert. + +/// + +Stellen Sie sich das jetzt mit **vielen** anderen **Paketen** vor, von denen alle Ihre **Projekte abhängen**. Das ist sehr schwierig zu verwalten. Und Sie wÃŧrden wahrscheinlich einige Projekte mit einigen **inkompatiblen Versionen** der Pakete ausfÃŧhren und nicht wissen, warum etwas nicht funktioniert. + +DarÃŧber hinaus kÃļnnte es je nach Ihrem Betriebssystem (z. B. Linux, Windows, macOS) bereits mit installiertem Python geliefert worden sein. Und in diesem Fall hatte es wahrscheinlich einige Pakete mit bestimmten Versionen **installiert**, die von Ihrem System benÃļtigt werden. Wenn Sie Pakete in der globalen Python-Umgebung installieren, kÃļnnten Sie einige der Programme, die mit Ihrem Betriebssystem geliefert wurden, **kaputtmachen**. + +## Wo werden Pakete installiert { #where-are-packages-installed } + +Wenn Sie Python installieren, werden einige Verzeichnisse mit einigen Dateien auf Ihrem Rechner erstellt. + +Einige dieser Verzeichnisse sind dafÃŧr zuständig, alle Pakete, die Sie installieren, aufzunehmen. + +Wenn Sie ausfÃŧhren: + +
+ +```console +// FÃŧhren Sie dies jetzt nicht aus, es ist nur ein Beispiel 🤓 +$ pip install "fastapi[standard]" +---> 100% +``` + +
+ +Das lädt eine komprimierte Datei mit dem FastAPI-Code herunter, normalerweise von PyPI. + +Es wird auch Dateien fÃŧr andere Pakete **herunterladen**, von denen FastAPI abhängt. + +Dann wird es all diese Dateien **extrahieren** und sie in ein Verzeichnis auf Ihrem Rechner legen. + +Standardmäßig werden diese heruntergeladenen und extrahierten Dateien in das Verzeichnis gelegt, das mit Ihrer Python-Installation kommt, das ist die **globale Umgebung**. + +## Was sind virtuelle Umgebungen { #what-are-virtual-environments } + +Die LÃļsung fÃŧr die Probleme, alle Pakete in der globalen Umgebung zu haben, besteht darin, eine **virtuelle Umgebung fÃŧr jedes Projekt** zu verwenden, an dem Sie arbeiten. + +Eine virtuelle Umgebung ist ein **Verzeichnis**, sehr ähnlich zu dem globalen, in dem Sie die Pakete fÃŧr ein Projekt installieren kÃļnnen. + +Auf diese Weise hat jedes Projekt seine eigene virtuelle Umgebung (`.venv`-Verzeichnis) mit seinen eigenen Paketen. + +```mermaid +flowchart TB + subgraph stone-project[philosophers-stone-Projekt] + stone(philosophers-stone) --->|benÃļtigt| harry-1 + subgraph venv1[.venv] + harry-1[harry v1] + end + end + subgraph azkaban-project[prisoner-of-azkaban-Projekt] + azkaban(prisoner-of-azkaban) --->|benÃļtigt| harry-3 + subgraph venv2[.venv] + harry-3[harry v3] + end + end + stone-project ~~~ azkaban-project +``` + +## Was bedeutet das Aktivieren einer virtuellen Umgebung { #what-does-activating-a-virtual-environment-mean } + +Wenn Sie eine virtuelle Umgebung aktivieren, zum Beispiel mit: + +//// tab | Linux, macOS + +
+ +```console +$ source .venv/bin/activate +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +$ .venv\Scripts\Activate.ps1 +``` + +
+ +//// + +//// tab | Windows Bash + +Oder wenn Sie Bash fÃŧr Windows verwenden (z. B. Git Bash): + +
+ +```console +$ source .venv/Scripts/activate +``` + +
+ +//// + +Dieser Befehl erstellt oder ändert einige [Umgebungsvariablen](environment-variables.md){.internal-link target=_blank}, die fÃŧr die nächsten Befehle verfÃŧgbar sein werden. + +Eine dieser Variablen ist die `PATH`-Variable. + +/// tip | Tipp + +Sie kÃļnnen mehr Ãŧber die `PATH`-Umgebungsvariable im Abschnitt [Umgebungsvariablen](environment-variables.md#path-environment-variable){.internal-link target=_blank} erfahren. + +/// + +Das Aktivieren einer virtuellen Umgebung fÃŧgt deren Pfad `.venv/bin` (auf Linux und macOS) oder `.venv\Scripts` (auf Windows) zur `PATH`-Umgebungsvariable hinzu. + +Angenommen, die `PATH`-Variable sah vor dem Aktivieren der Umgebung so aus: + +//// tab | Linux, macOS + +```plaintext +/usr/bin:/bin:/usr/sbin:/sbin +``` + +Das bedeutet, dass das System nach Programmen sucht in: + +* `/usr/bin` +* `/bin` +* `/usr/sbin` +* `/sbin` + +//// + +//// tab | Windows + +```plaintext +C:\Windows\System32 +``` + +Das bedeutet, dass das System nach Programmen sucht in: + +* `C:\Windows\System32` + +//// + +Nach dem Aktivieren der virtuellen Umgebung wÃŧrde die `PATH`-Variable folgendermaßen aussehen: + +//// tab | Linux, macOS + +```plaintext +/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin +``` + +Das bedeutet, dass das System nun zuerst nach Programmen sucht in: + +```plaintext +/home/user/code/awesome-project/.venv/bin +``` + +bevor es in den anderen Verzeichnissen sucht. + +Wenn Sie also `python` im Terminal eingeben, wird das System das Python-Programm in + +```plaintext +/home/user/code/awesome-project/.venv/bin/python +``` + +finden und dieses verwenden. + +//// + +//// tab | Windows + +```plaintext +C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32 +``` + +Das bedeutet, dass das System nun zuerst nach Programmen sucht in: + +```plaintext +C:\Users\user\code\awesome-project\.venv\Scripts +``` + +bevor es in den anderen Verzeichnissen sucht. + +Wenn Sie also `python` im Terminal eingeben, wird das System das Python-Programm in + +```plaintext +C:\Users\user\code\awesome-project\.venv\Scripts\python +``` + +finden und dieses verwenden. + +//// + +Ein wichtiger Punkt ist, dass es den Pfad der virtuellen Umgebung am **Anfang** der `PATH`-Variable platziert. Das System wird es **vor** allen anderen verfÃŧgbaren Pythons finden. Auf diese Weise, wenn Sie `python` ausfÃŧhren, wird das Python **aus der virtuellen Umgebung** verwendet anstelle eines anderen `python` (zum Beispiel, einem `python` aus einer globalen Umgebung). + +Das Aktivieren einer virtuellen Umgebung ändert auch ein paar andere Dinge, aber dies ist eines der wichtigsten Dinge, die es tut. + +## Testen einer virtuellen Umgebung { #checking-a-virtual-environment } + +Wenn Sie testen, ob eine virtuelle Umgebung aktiv ist, zum Beispiel mit: + +//// tab | Linux, macOS, Windows Bash + +
+ +```console +$ which python + +/home/user/code/awesome-project/.venv/bin/python +``` + +
+ +//// + +//// tab | Windows PowerShell + +
+ +```console +$ Get-Command python + +C:\Users\user\code\awesome-project\.venv\Scripts\python +``` + +
+ +//// + +bedeutet das, dass das `python`-Programm, das verwendet wird, das in der **virtuellen Umgebung** ist. + +Sie verwenden `which` auf Linux und macOS und `Get-Command` in Windows PowerShell. + +So funktioniert dieser Befehl: Er wird in der `PATH`-Umgebungsvariable nachsehen und **jeden Pfad in der Reihenfolge durchgehen**, um das Programm namens `python` zu finden. Sobald er es findet, wird er Ihnen **den Pfad** zu diesem Programm anzeigen. + +Der wichtigste Punkt ist, dass, wenn Sie `python` aufrufen, genau dieses „`python`“ ausgefÃŧhrt wird. + +So kÃļnnen Sie ÃŧberprÃŧfen, ob Sie sich in der richtigen virtuellen Umgebung befinden. + +/// tip | Tipp + +Es ist einfach, eine virtuelle Umgebung zu aktivieren, ein Python zu bekommen und dann **zu einem anderen Projekt zu wechseln**. + +Und das zweite Projekt **wÃŧrde nicht funktionieren**, weil Sie das **falsche Python** verwenden, aus einer virtuellen Umgebung fÃŧr ein anderes Projekt. + +Es ist nÃŧtzlich, ÃŧberprÃŧfen zu kÃļnnen, welches `python` verwendet wird. 🤓 + +/// + +## Warum eine virtuelle Umgebung deaktivieren { #why-deactivate-a-virtual-environment } + +Zum Beispiel kÃļnnten Sie an einem Projekt `philosophers-stone` arbeiten, diese virtuelle Umgebung **aktivieren**, Pakete installieren und mit dieser Umgebung arbeiten. + +Und dann mÃļchten Sie an **einem anderen Projekt** `prisoner-of-azkaban` arbeiten. + +Sie gehen zu diesem Projekt: + +
+ +```console +$ cd ~/code/prisoner-of-azkaban +``` + +
+ +Wenn Sie die virtuelle Umgebung fÃŧr `philosophers-stone` nicht deaktivieren, wird beim AusfÃŧhren von `python` im Terminal versucht, das Python von `philosophers-stone` zu verwenden. + +
+ +```console +$ cd ~/code/prisoner-of-azkaban + +$ python main.py + +// Fehler beim Importieren von sirius, es ist nicht installiert 😱 +Traceback (most recent call last): + File "main.py", line 1, in + import sirius +``` + +
+ +Wenn Sie jedoch die virtuelle Umgebung deaktivieren und die neue fÃŧr `prisoner-of-askaban` aktivieren, wird beim AusfÃŧhren von `python` das Python aus der virtuellen Umgebung in `prisoner-of-azkaban` verwendet. + +
+ +```console +$ cd ~/code/prisoner-of-azkaban + +// Sie mÃŧssen nicht im alten Verzeichnis sein, um zu deaktivieren, Sie kÃļnnen dies Ãŧberall tun, sogar nachdem Sie zum anderen Projekt gewechselt haben 😎 +$ deactivate + +// Die virtuelle Umgebung in prisoner-of-azkaban/.venv 🚀 aktivieren +$ source .venv/bin/activate + +// Jetzt, wenn Sie python ausfÃŧhren, wird das Paket sirius in dieser virtuellen Umgebung gefunden ✨ +$ python main.py + +I solemnly swear đŸē +``` + +
+ +## Alternativen { #alternatives } + +Dies ist ein einfacher Leitfaden, um Ihnen den Einstieg zu erleichtern und Ihnen beizubringen, wie alles **unter der Haube** funktioniert. + +Es gibt viele **Alternativen** zur Verwaltung von virtuellen Umgebungen, Paketabhängigkeiten (Anforderungen), Projekten. + +Sobald Sie bereit sind und ein Tool verwenden mÃļchten, das **das gesamte Projekt verwaltet**, Paketabhängigkeiten, virtuelle Umgebungen usw., wÃŧrde ich Ihnen vorschlagen, uv auszuprobieren. + +`uv` kann viele Dinge tun, es kann: + +* **Python fÃŧr Sie installieren**, einschließlich verschiedener Versionen +* Die **virtuelle Umgebung** fÃŧr Ihre Projekte verwalten +* **Pakete installieren** +* Paket**abhängigkeiten und Versionen** fÃŧr Ihr Projekt verwalten +* Sicherstellen, dass Sie eine **exakte** Menge an Paketen und Versionen zur Installation haben, einschließlich ihrer Abhängigkeiten, damit Sie sicher sein kÃļnnen, dass Sie Ihr Projekt in der Produktionsumgebung genauso ausfÃŧhren kÃļnnen wie auf Ihrem Rechner während der Entwicklung, dies wird **Locking** genannt +* Und viele andere Dinge + +## Fazit { #conclusion } + +Wenn Sie das alles gelesen und verstanden haben, wissen Sie jetzt **viel mehr** Ãŧber virtuelle Umgebungen als viele Entwickler da draußen. 🤓 + +Das Wissen Ãŧber diese Details wird in Zukunft wahrscheinlich nÃŧtzlich sein, wenn Sie etwas debuggen, das komplex erscheint, aber Sie werden wissen, **wie alles unter der Haube funktioniert**. 😎 diff --git a/docs/de/llm-prompt.md b/docs/de/llm-prompt.md new file mode 100644 index 000000000..23c111d2d --- /dev/null +++ b/docs/de/llm-prompt.md @@ -0,0 +1,338 @@ +### Target language + +Translate to German (Deutsch). + +Language code: de. + + +### Definitions + +"hyphen" + The character ÂĢ-Âģ + Unicode U+002D (HYPHEN-MINUS) + Alternative names: hyphen, dash, minus sign + +"dash" + The character ÂĢ–Âģ + Unicode U+2013 (EN DASH) + German name: Halbgeviertstrich + + +### Grammar to use when talking to the reader + +Use the formal grammar (use ÂĢSieÂģ instead of ÂĢDuÂģ). + + +### Quotes + +1) Convert neutral double quotes (ÂĢ"Âģ) and English double typographic quotes (ÂĢ“Âģ and ÂĢ”Âģ) to German double typographic quotes (ÂĢ„Âģ and ÂĢ“Âģ). Convert neutral single quotes (ÂĢ'Âģ) and English single typographic quotes (ÂĢ‘Âģ and ÂĢ’Âģ) to German single typographic quotes (ÂĢ‚Âģ and ÂĢ‘Âģ). Do NOT convert ÂĢ`"Âģ to ÂĢ„Âģ, do NOT convert ÂĢ"`Âģ to ÂĢ“Âģ. + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + "Hello world" + “Hello Universe” + "He said: 'Hello'" + “my name is ‘Nils’” + `"__main__"` + `"items"` + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + „Hallo Welt“ + „Hallo Universum“ + „Er sagte: ‚Hallo‘“ + „Mein Name ist ‚Nils‘“ + `"__main__"` + `"items"` + ÂģÂģÂģ + + +### Ellipsis + +1) Make sure there is a space between an ellipsis and a word following or preceding the ellipsis. + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + ...as we intended. + ...this would work: + ...etc. + others... + More to come... + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + ... wie wir es beabsichtigt hatten. + ... das wÃŧrde funktionieren: + ... usw. + Andere ... + Später mehr ... + ÂģÂģÂģ + +2) This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there. + + +### Headings + +1) Translate headings using the infinite form. + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + ## Create a Project { #create-a-project } + ÂģÂģÂģ + + Translate with (German): + + ÂĢÂĢÂĢ + ## Ein Projekt erstellen { #create-a-project } + ÂģÂģÂģ + + Do NOT translate with (German): + + ÂĢÂĢÂĢ + ## Erstellen Sie ein Projekt { #create-a-project } + ÂģÂģÂģ + + Source (English): + + ÂĢÂĢÂĢ + # Install Packages { #install-packages } + ÂģÂģÂģ + + Translate with (German): + + ÂĢÂĢÂĢ + # Pakete installieren { #install-packages } + ÂģÂģÂģ + + Do NOT translate with (German): + + ÂĢÂĢÂĢ + # Installieren Sie Pakete { #install-packages } + ÂģÂģÂģ + + Source (English): + + ÂĢÂĢÂĢ + ### Run Your Program { #run-your-program } + ÂģÂģÂģ + + Translate with (German): + + ÂĢÂĢÂĢ + ### Ihr Programm ausfÃŧhren { #run-your-program } + ÂģÂģÂģ + + Do NOT translate with (German): + + ÂĢÂĢÂĢ + ### FÃŧhren Sie Ihr Programm aus { #run-your-program } + ÂģÂģÂģ + +2) Make sure that the translated part of the heading does not end with a period. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + ## Another module with `APIRouter` { #another-module-with-apirouter } + ÂģÂģÂģ + + Translate with (German): + + ÂĢÂĢÂĢ + ## Ein weiteres Modul mit `APIRouter` { #another-module-with-apirouter } + ÂģÂģÂģ + + Do NOT translate with (German) – notice the added period: + + ÂĢÂĢÂĢ + ## Ein weiteres Modul mit `APIRouter`. { #another-module-with-apirouter } + ÂģÂģÂģ + +3) Replace occurrences of literal ÂĢ - Âģ (a space followed by a hyphen followed by a space) with ÂĢ â€“ Âģ (a space followed by a dash followed by a space) in the translated part of the heading. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + # FastAPI in Containers - Docker { #fastapi-in-containers-docker } + ÂģÂģÂģ + + Translate with (German) – notice the dash: + + ÂĢÂĢÂĢ + # FastAPI in Containern – Docker { #fastapi-in-containers-docker } + ÂģÂģÂģ + + Do NOT translate with (German) – notice the hyphen: + + ÂĢÂĢÂĢ + # FastAPI in Containern - Docker { #fastapi-in-containers-docker } + ÂģÂģÂģ + +3.1) Do not apply rule 3 when there is no space before or no space after the dash. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + ## Type hints and annotations { #type-hints-and-annotations } + ÂģÂģÂģ + + Translate with (German) – use a short dash: + + ÂĢÂĢÂĢ + ## Typhinweise und -annotationen { #type-hints-and-annotations } + ÂģÂģÂģ + + Do NOT translate with (German): + + ÂĢÂĢÂĢ + ## Typhinweise und –annotationen { #type-hints-and-annotations } + ÂģÂģÂģ + +3.2) Do not apply rule 3 to the untranslated part of the heading inside curly brackets, which you shall not translate. + + +### German instructions, when to use and when not to use hyphens in words (written in first person, which is you) + +In der Regel versuche ich so weit wie mÃļglich Worte zusammenzuschreiben, also ohne Bindestrich, es sei denn, es ist Konkretesding-Klassevondingen, etwa ÂĢPydantic-ModellÂģ (aber: ÂĢDatenbankmodellÂģ), ÂĢPython-ModulÂģ (aber: ÂĢStandardmodulÂģ). Ich setze auch einen Bindestrich, wenn er die gleichen Buchstaben verbindet, etwa ÂĢEnum-MemberÂģ, ÂĢCloud-DienstÂģ, ÂĢTemplate-EngineÂģ. Oder wenn das Wort sonst einfach zu lang wird, etwa, ÂĢPerformance-OptimierungÂģ. Oder um etwas visuell besser zu dokumentieren, etwa ÂĢPfadoperation-DekoratorÂģ, ÂĢPfadoperation-FunktionÂģ. + + +### German instructions about difficult to translate technical terms (written in first person, which is you) + +Ich versuche nicht, alles einzudeutschen. Das bezieht sich besonders auf Begriffe aus dem Bereich der Programmierung. Ich wandele zwar korrekt in Großschreibung um und setze Bindestriche, wo notwendig, aber ansonsten lasse ich solch ein Wort unverändert. Beispielsweise wird aus dem englischen Wort ÂĢstringÂģ in der deutschen Übersetzung ÂĢStringÂģ, aber nicht ÂĢZeichenketteÂģ. Oder aus dem englischen Wort ÂĢrequest bodyÂģ wird in der deutschen Übersetzung ÂĢRequestbodyÂģ, aber nicht ÂĢAnfragekÃļrperÂģ. Oder aus dem englischen ÂĢresponseÂģ wird im Deutschen ÂĢResponseÂģ, aber nicht ÂĢAntwortÂģ. + + +### List of English terms and their preferred German translations + +Below is a list of English terms and their preferred German translations, separated by a colon (ÂĢ:Âģ). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them. A term or a translation may be followed by an explanation in brackets, which explains when to translate the term this way. If a translation is preceded by ÂĢNOTÂģ, then that means: do NOT use this translation for this term. English nouns, starting with the word ÂĢtheÂģ, have the German genus – ÂĢderÂģ, ÂĢdieÂģ, ÂĢdasÂģ – prepended to their German translation, to help you to grammatically decline them in the translation. They are given in singular case, unless they have ÂĢ(plural)Âģ attached, which means they are given in plural case. Verbs are given in the full infinitive – starting with the word ÂĢtoÂģ. + +* ÂĢ/// checkÂģ: ÂĢ/// check | TestenÂģ +* ÂĢ/// dangerÂģ: ÂĢ/// danger | GefahrÂģ +* ÂĢ/// infoÂģ: ÂĢ/// info | InfoÂģ +* ÂĢ/// note | Technical DetailsÂģ: ÂĢ/// note | Technische DetailsÂģ +* ÂĢ/// noteÂģ: ÂĢ/// note | HinweisÂģ +* ÂĢ/// tipÂģ: ÂĢ/// tip | TippÂģ +* ÂĢ/// warningÂģ: ÂĢ/// warning | AchtungÂģ +* ÂĢyouÂģ: ÂĢSieÂģ +* ÂĢyourÂģ: ÂĢIhrÂģ +* ÂĢe.gÂģ: ÂĢz. B.Âģ +* ÂĢetc.Âģ: ÂĢusw.Âģ +* ÂĢrefÂģ: ÂĢRef.Âģ +* ÂĢthe Tutorial - User guideÂģ: ÂĢdas Tutorial – BenutzerhandbuchÂģ +* ÂĢthe Advanced User GuideÂģ: ÂĢdas Handbuch fÃŧr fortgeschrittene BenutzerÂģ +* ÂĢthe SQLModel docsÂģ: ÂĢdie SQLModel-DokumentationÂģ +* ÂĢthe docsÂģ: ÂĢdie DokumentationÂģ (use singular case) +* ÂĢthe env varÂģ: ÂĢdie UmgebungsvariableÂģ +* ÂĢthe `PATH` environment variableÂģ: ÂĢdie `PATH`-UmgebungsvariableÂģ +* ÂĢthe `PATH`Âģ: ÂĢder `PATH`Âģ +* ÂĢthe `requirements.txt`Âģ: ÂĢdie `requirements.txt`Âģ +* ÂĢthe API RouterÂģ: ÂĢder API-RouterÂģ +* ÂĢthe Authorization-HeaderÂģ: ÂĢder AutorisierungsheaderÂģ +* ÂĢthe `Authorization`-HeaderÂģ: ÂĢder `Authorization`-HeaderÂģ +* ÂĢthe background taskÂģ: ÂĢder HintergrundtaskÂģ +* ÂĢthe buttonÂģ: ÂĢder ButtonÂģ +* ÂĢthe cloud providerÂģ: ÂĢder CloudanbieterÂģ +* ÂĢthe CLIÂģ: ÂĢDas CLIÂģ +* ÂĢthe command line interfaceÂģ: ÂĢDas KommandozeileninterfaceÂģ +* ÂĢthe default valueÂģ: ÂĢder DefaultwertÂģ +* ÂĢthe default valueÂģ: NOT ÂĢder StandardwertÂģ +* ÂĢthe default declarationÂģ: ÂĢdie Default-DeklarationÂģ +* ÂĢthe dictÂģ: ÂĢdas DictÂģ +* ÂĢthe dictionaryÂģ: ÂĢdas DictionaryÂģ +* ÂĢthe enumerationÂģ: ÂĢdie EnumerationÂģ +* ÂĢthe enumÂģ: ÂĢdas EnumÂģ +* ÂĢthe engineÂģ: ÂĢdie EngineÂģ +* ÂĢthe error responseÂģ: ÂĢdie Error-ResponseÂģ +* ÂĢthe eventÂģ: ÂĢdas EventÂģ +* ÂĢthe exceptionÂģ: ÂĢdie ExceptionÂģ +* ÂĢthe exception handlerÂģ: ÂĢder ExceptionhandlerÂģ +* ÂĢthe form modelÂģ: ÂĢdas FormularmodellÂģ +* ÂĢthe form bodyÂģ: ÂĢder FormularbodyÂģ +* ÂĢthe headerÂģ: ÂĢder HeaderÂģ +* ÂĢthe headersÂģ (plural): ÂĢdie HeaderÂģ +* ÂĢin headersÂģ (plural): ÂĢin HeadernÂģ +* ÂĢthe forwarded headerÂģ: ÂĢder Forwarded-HeaderÂģ +* ÂĢthe lifespan eventÂģ: ÂĢdas Lifespan-EventÂģ +* ÂĢthe lockÂģ: ÂĢder LockÂģ +* ÂĢthe lockingÂģ: ÂĢdas LockingÂģ +* ÂĢthe mobile applicationÂģ: ÂĢdie Mobile-AnwendungÂģ +* ÂĢthe model objectÂģ: ÂĢdas ModellobjektÂģ +* ÂĢthe mountingÂģ: ÂĢdas MountenÂģ +* ÂĢmountedÂģ: ÂĢgemountetÂģ +* ÂĢthe originÂģ: ÂĢdas OriginÂģ +* ÂĢthe overrideÂģ: ÂĢDie ÜberschreibungÂģ +* ÂĢthe parameterÂģ: ÂĢder ParameterÂģ +* ÂĢthe parametersÂģ (plural): ÂĢdie ParameterÂģ +* ÂĢthe function parameterÂģ: ÂĢder FunktionsparameterÂģ +* ÂĢthe default parameterÂģ: ÂĢder DefaultparameterÂģ +* ÂĢthe body parameterÂģ: ÂĢder Body-ParameterÂģ +* ÂĢthe request body parameterÂģ: ÂĢder Requestbody-ParameterÂģ +* ÂĢthe path parameterÂģ: ÂĢder Pfad-ParameterÂģ +* ÂĢthe query parameterÂģ: ÂĢder Query-ParameterÂģ +* ÂĢthe cookie parameterÂģ: ÂĢder Cookie-ParameterÂģ +* ÂĢthe header parameterÂģ: ÂĢder Header-ParameterÂģ +* ÂĢthe form parameterÂģ: ÂĢder Formular-ParameterÂģ +* ÂĢthe payloadÂģ: ÂĢdie PayloadÂģ +* ÂĢthe performanceÂģ: NOT ÂĢdie PerformanceÂģ +* ÂĢthe queryÂģ: ÂĢdie QueryÂģ +* ÂĢthe recapÂģ: ÂĢdie ZusammenfassungÂģ +* ÂĢthe requestÂģ (what the client sends to the server): ÂĢder RequestÂģ +* ÂĢthe request bodyÂģ: ÂĢder RequestbodyÂģ +* ÂĢthe request bodiesÂģ (plural): ÂĢdie RequestbodysÂģ +* ÂĢthe responseÂģ (what the server sends back to the client): ÂĢdie ResponseÂģ +* ÂĢthe return typeÂģ: ÂĢder RÃŧckgabetypÂģ +* ÂĢthe return valueÂģ: ÂĢder RÃŧckgabewertÂģ +* ÂĢthe startupÂģ (the event of the app): ÂĢder StartupÂģ +* ÂĢthe shutdownÂģ (the event of the app): ÂĢder ShutdownÂģ +* ÂĢthe startup eventÂģ: ÂĢdas Startup-EventÂģ +* ÂĢthe shutdown eventÂģ: ÂĢdas Shutdown-EventÂģ +* ÂĢthe startupÂģ (of the server): ÂĢdas HochfahrenÂģ +* ÂĢthe startupÂģ (the company): ÂĢdas StartupÂģ +* ÂĢthe SDKÂģ: ÂĢdas SDKÂģ +* ÂĢthe tagÂģ: ÂĢder TagÂģ +* ÂĢthe type annotationÂģ: ÂĢdie TypannotationÂģ +* ÂĢthe type hintÂģ: ÂĢder TyphinweisÂģ +* ÂĢthe wildcardÂģ: ÂĢdie WildcardÂģ +* ÂĢthe worker classÂģ: ÂĢdie WorkerklasseÂģ +* ÂĢthe worker classÂģ: NOT ÂĢdie ArbeiterklasseÂģ +* ÂĢthe worker processÂģ: ÂĢder WorkerprozessÂģ +* ÂĢthe worker processÂģ: NOT ÂĢder ArbeiterprozessÂģ +* ÂĢto commitÂģ: ÂĢcommittenÂģ +* ÂĢto modifyÂģ: ÂĢändernÂģ +* ÂĢto serveÂģ (an application): ÂĢbereitstellenÂģ +* ÂĢto serveÂģ (a response): ÂĢausliefernÂģ +* ÂĢto serveÂģ: NOT ÂĢbedienenÂģ +* ÂĢto upgradeÂģ: ÂĢaktualisierenÂģ +* ÂĢto wrapÂģ: ÂĢwrappenÂģ +* ÂĢto wrapÂģ: NOT ÂĢhÃŧllenÂģ +* ÂĢ`foo` as a `type`Âģ: ÂĢ`foo` vom Typ `type`Âģ +* ÂĢ`foo` as a `type`Âģ: ÂĢ`foo`, ein `type`Âģ +* ÂĢFastAPI's XÂģ: ÂĢFastAPIs XÂģ +* ÂĢStarlette's YÂģ: ÂĢStarlettes YÂģ +* ÂĢX is case-sensitiveÂģ: ÂĢGroß-/Klein­schrei­bung ist relevant in XÂģ +* ÂĢX is case-insensitiveÂģ: ÂĢGroß-/Klein­schrei­bung ist nicht relevant in XÂģ +* ÂĢstandard PythonÂģ: ÂĢStandard-PythonÂģ +* ÂĢdeprecatedÂģ: ÂĢdeprecatetÂģ + + +### Other rules + +Preserve indentation. Keep emoticons. Encode in utf-8. Use Linux line breaks (LF). diff --git a/docs/em/docs/advanced/security/oauth2-scopes.md b/docs/em/docs/advanced/security/oauth2-scopes.md index b8c49bd11..9e3bc0058 100644 --- a/docs/em/docs/advanced/security/oauth2-scopes.md +++ b/docs/em/docs/advanced/security/oauth2-scopes.md @@ -62,7 +62,7 @@ Oauth2ī¸âƒŖ đŸ‘Ģ đŸŽģ. đŸĨ‡, âžĄī¸ 🔜 👀 🍕 👈 🔀 âšĒī¸âžĄī¸ đŸ–ŧ 👑 **🔰 - 👩‍đŸ’ģ đŸĻŽ** [Oauth2ī¸âƒŖ âŽī¸ 🔐 (& 🔁), 📨 âŽī¸ đŸĨ™ 🤝](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. 🔜 âš™ī¸ Oauth2ī¸âƒŖ ↔: -{* ../../docs_src/security/tutorial005.py hl[2,4,8,12,46,64,105,107:115,121:124,128:134,139,155] *} +{* ../../docs_src/security/tutorial005.py hl[2,4,8,12,46,64,105,107:115,121:125,129:135,140,156] *} 🔜 âžĄī¸ 📄 👈 🔀 🔁 🔁. @@ -98,7 +98,7 @@ Oauth2ī¸âƒŖ đŸ‘Ģ đŸŽģ. /// -{* ../../docs_src/security/tutorial005.py hl[155] *} +{* ../../docs_src/security/tutorial005.py hl[156] *} ## đŸ“Ŗ ↔ *➡ đŸ› ī¸* & 🔗 @@ -124,7 +124,7 @@ Oauth2ī¸âƒŖ đŸ‘Ģ đŸŽģ. /// -{* ../../docs_src/security/tutorial005.py hl[4,139,168] *} +{* ../../docs_src/security/tutorial005.py hl[4,140,169] *} /// info | 📡 ℹ @@ -180,7 +180,7 @@ Oauth2ī¸âƒŖ đŸ‘Ģ đŸŽģ. đŸ‘Ĩ ✔ 👈 đŸ‘Ĩ âœ”ī¸ 👩‍đŸ’ģ âŽī¸ 👈 🆔, & đŸšĨ đŸšĢ, đŸ‘Ĩ 🤚 👈 🎏 ⚠ đŸ‘Ĩ ✍ ⏭. -{* ../../docs_src/security/tutorial005.py hl[46,116:127] *} +{* ../../docs_src/security/tutorial005.py hl[46,116:128] *} ## ✔ `scopes` @@ -188,7 +188,7 @@ Oauth2ī¸âƒŖ đŸ‘Ģ đŸŽģ. 👉, đŸ‘Ĩ âš™ī¸ `security_scopes.scopes`, 👈 🔌 `list` âŽī¸ 🌐 đŸ‘Ģ ↔ `str`. -{* ../../docs_src/security/tutorial005.py hl[128:134] *} +{* ../../docs_src/security/tutorial005.py hl[129:135] *} ## 🔗 🌲 & ↔ diff --git a/docs/em/docs/async.md b/docs/em/docs/async.md index ac9804f64..cde778b0f 100644 --- a/docs/em/docs/async.md +++ b/docs/em/docs/async.md @@ -381,7 +381,7 @@ async def read_burgers(): âŽī¸ âŦ 🐍, 👆 đŸ’Ē âœ”ī¸ âš™ī¸ đŸ§ĩ âš–ī¸ 🐁. âœ‹ī¸ 📟 🌌 🌖 🏗 🤔, ℹ, & 💭 🔃. -âŽī¸ âŦ âœŗ / đŸ–Ĩ 🕸, 👆 🔜 âœ”ī¸ âš™ī¸ "⏲". ❔ â†˜ī¸ ⏲ đŸ”Ĩ😈. +âŽī¸ âŦ âœŗ / đŸ–Ĩ 🕸, 👆 🔜 âœ”ī¸ âš™ī¸ "⏲". ❔ â†˜ī¸ "⏲ đŸ”Ĩ😈". ## 🔁 diff --git a/docs/em/docs/help-fastapi.md b/docs/em/docs/help-fastapi.md index 099485222..9d802f9e4 100644 --- a/docs/em/docs/help-fastapi.md +++ b/docs/em/docs/help-fastapi.md @@ -22,7 +22,7 @@ ## ⏊ FastAPI 🔛 👱📔 -⏊ đŸļ Fastapi 🔛 **👱📔** 🤚 📰 📰 🔃 **FastAPI**. đŸ‘ļ +⏊ đŸļ Fastapi 🔛 **👱📔** 🤚 📰 📰 🔃 **FastAPI**. đŸ‘ļ ## ✴ **FastAPI** 📂 @@ -47,10 +47,10 @@ * ⏊ 👤 🔛 **📂**. * 👀 🎏 📂 ℹ 🏗 👤 âœ”ī¸ ✍ 👈 đŸ’Ē ℹ 👆. * ⏊ 👤 👀 🕐❔ 👤 ✍ 🆕 📂 ℹ 🏗. -* ⏊ 👤 🔛 **👱📔** âš–ī¸ ☠. +* ⏊ 👤 🔛 **👱📔** âš–ī¸ ☠. * đŸ’Ŧ 👤 ❔ 👆 âš™ī¸ FastAPI (👤 💌 👂 👈). * 👂 🕐❔ 👤 ⚒ 🎉 âš–ī¸ 🚀 🆕 🧰. - * 👆 đŸ’Ē ⏊ đŸļ Fastapi 🔛 👱📔 (🎏 🏧). + * 👆 đŸ’Ē ⏊ đŸļ Fastapi 🔛 👱📔 (🎏 🏧). * 🔗 âŽī¸ 👤 🔛 **👱📔**. * 👂 🕐❔ 👤 ⚒ 🎉 âš–ī¸ 🚀 🆕 🧰 (👐 👤 âš™ī¸ 👱📔 🌖 🛎 🤷 ♂). * ✍ âšĢī¸â” 👤 ✍ (âš–ī¸ ⏊ 👤) 🔛 **🇸🇲.** âš–ī¸ **🔉**. @@ -59,7 +59,7 @@ ## 👱📔 🔃 **FastAPI** -👱📔 🔃 **FastAPI** & âžĄī¸ 👤 & 🎏 💭 âšĢī¸â” 👆 💖 âšĢī¸. đŸ‘ļ +👱📔 🔃 **FastAPI** & âžĄī¸ 👤 & 🎏 💭 âšĢī¸â” 👆 💖 âšĢī¸. đŸ‘ļ 👤 💌 👂 🔃 ❔ **FastAPI** 💆‍♂ âš™ī¸, âšĢī¸â” 👆 âœ”ī¸ 💖 âšĢī¸, ❔ 🏗/đŸĸ 👆 âš™ī¸ âšĢī¸, â™’ī¸. diff --git a/docs/em/docs/index.md b/docs/em/docs/index.md index 57be59b07..fac4ba91a 100644 --- a/docs/em/docs/index.md +++ b/docs/em/docs/index.md @@ -87,7 +87,7 @@ FastAPI 🏛, ⏊ (↕-🎭), 🕸 đŸ› ī¸ 🏗 đŸ› ī¸ âŽī¸ 🐍 3ī¸âƒŖ.8ī¸ "_👤 🤭 🌕 😄 🔃 **FastAPI**. âšĢī¸ 🎊 ❗_" -
✡ 🇭🇰 - 🐍 đŸ”ĸ đŸ“ģ đŸĻ  (đŸ‡ĻđŸ‡Ē)
+
✡ 🇭🇰 - 🐍 đŸ”ĸ đŸ“ģ đŸĻ  (đŸ‡ĻđŸ‡Ē)
--- @@ -101,7 +101,7 @@ FastAPI 🏛, ⏊ (↕-🎭), 🕸 đŸ› ī¸ 🏗 đŸ› ī¸ âŽī¸ 🐍 3ī¸âƒŖ.8ī¸ "_đŸ‘Ĩ âœ”ī¸ 🎛 🤭 **FastAPI** 👆 **🔗** [...] 👤 💭 👆 🔜 💖 âšĢī¸ [...]_" -
🇱🇨 🇸🇲 - ✡ Honnibal - đŸ’Ĩ 👲 🕴 - 🌈 đŸ‘ŧ (đŸ‡ĻđŸ‡Ē) - (đŸ‡ĻđŸ‡Ē)
+
🇱🇨 🇸🇲 - ✡ Honnibal - đŸ’Ĩ 👲 🕴 - 🌈 đŸ‘ŧ (đŸ‡ĻđŸ‡Ē) - (đŸ‡ĻđŸ‡Ē)
--- diff --git a/docs/en/data/contributors.yml b/docs/en/data/contributors.yml index e06510ac4..ad2b25c6c 100644 --- a/docs/en/data/contributors.yml +++ b/docs/en/data/contributors.yml @@ -1,21 +1,21 @@ tiangolo: login: tiangolo - count: 753 + count: 776 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo dependabot: login: dependabot - count: 104 + count: 113 avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4 url: https://github.com/apps/dependabot alejsdev: login: alejsdev - count: 47 + count: 48 avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=638c65283ac9e9e2c3a0f9d1e3370db4b8a2c58d&v=4 url: https://github.com/alejsdev pre-commit-ci: login: pre-commit-ci - count: 33 + count: 41 avatarUrl: https://avatars.githubusercontent.com/in/68672?v=4 url: https://github.com/apps/pre-commit-ci github-actions: @@ -78,6 +78,11 @@ alissadb: count: 6 avatarUrl: https://avatars.githubusercontent.com/u/96190409?u=be42d85938c241be781505a5a872575be28b2906&v=4 url: https://github.com/alissadb +YuriiMotov: + login: YuriiMotov + count: 6 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 + url: https://github.com/YuriiMotov wshayes: login: wshayes count: 5 @@ -198,11 +203,11 @@ asheux: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/22955146?u=4553ebf5b5a7c7fe031a46182083aa224faba2e1&v=4 url: https://github.com/asheux -n25a: - login: n25a +blkst8: + login: blkst8 count: 3 avatarUrl: https://avatars.githubusercontent.com/u/49960770?u=7d8a6d5f0a75a5e9a865a2527edfd48895ea27ae&v=4 - url: https://github.com/n25a + url: https://github.com/blkst8 ghandic: login: ghandic count: 3 @@ -273,6 +278,11 @@ hamidrasti: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/43915620?v=4 url: https://github.com/hamidrasti +valentinDruzhinin: + login: valentinDruzhinin + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 + url: https://github.com/valentinDruzhinin kkinder: login: kkinder count: 2 @@ -421,7 +431,7 @@ davidefiocco: adriencaccia: login: adriencaccia count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/19605940?u=980b0b366a02791a5600b2e9f9ac2037679acaa8&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/19605940?u=9a59081f46bfc9d839886a49d5092cf572879049&v=4 url: https://github.com/adriencaccia jamescurtin: login: jamescurtin @@ -486,7 +496,7 @@ softwarebloat: Lancetnik: login: Lancetnik count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/44573917?u=f9a18be7324333daf9cc314c35c3051f0a20a7a6&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/44573917?u=6eaa0cdd35259fba40a76b82e4903440cba03fa9&v=4 url: https://github.com/Lancetnik joakimnordling: login: joakimnordling @@ -506,7 +516,7 @@ s111d: estebanx64: login: estebanx64 count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=1900887aeed268699e5ea6f3fb7db614f7b77cd3&v=4 url: https://github.com/estebanx64 tamird: login: tamird @@ -533,6 +543,11 @@ gsheni: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/8726321?u=ee3bd9ff6320f4715d1dd9671a3d55cccb65b984&v=4 url: https://github.com/gsheni +chailandau: + login: chailandau + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/112015853?u=2e6aaf2b1647db43834aabeae8d8282b4ec01873&v=4 + url: https://github.com/chailandau DanielKusyDev: login: DanielKusyDev count: 2 @@ -543,18 +558,13 @@ DanielYang59: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/80093591?u=63873f701c7c74aac83c906800a1dddc0bc8c92f&v=4 url: https://github.com/DanielYang59 -valentinDruzhinin: - login: valentinDruzhinin - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 - url: https://github.com/valentinDruzhinin blueswen: login: blueswen count: 2 avatarUrl: https://avatars.githubusercontent.com/u/1564148?u=6d6b8cc8f2b5cef715e68d6175154a8a94d518ee&v=4 url: https://github.com/blueswen -YuriiMotov: - login: YuriiMotov +Taoup: + login: Taoup count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 - url: https://github.com/YuriiMotov + avatarUrl: https://avatars.githubusercontent.com/u/22348542?v=4 + url: https://github.com/Taoup diff --git a/docs/en/data/external_links.yml b/docs/en/data/external_links.yml index 50f84ecbf..c1191b460 100644 --- a/docs/en/data/external_links.yml +++ b/docs/en/data/external_links.yml @@ -121,11 +121,11 @@ Articles: link: https://valonjanuzaj.medium.com/deploy-a-dockerized-fastapi-application-to-aws-cc757830ba1b title: Deploy a dockerized FastAPI application to AWS - author: Amit Chaudhary - author_link: https://twitter.com/amitness + author_link: https://x.com/amitness link: https://amitness.com/2020/06/fastapi-vs-flask/ title: FastAPI for Flask Users - author: Louis Guitton - author_link: https://twitter.com/louis_guitton + author_link: https://x.com/louis_guitton link: https://guitton.co/posts/fastapi-monitoring/ title: How to monitor your FastAPI service - author: Precious Ndubueze @@ -149,7 +149,7 @@ Articles: link: https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072 title: Introducing Dispatch - author: Stavros Korokithakis - author_link: https://twitter.com/Stavros + author_link: https://x.com/Stavros link: https://www.stavros.io/posts/fastapi-with-django/ title: Using FastAPI with Django - author: Twilio @@ -157,11 +157,11 @@ Articles: link: https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi title: Build a Secure Twilio Webhook with Python and FastAPI - author: SebastiÃĄn Ramírez (tiangolo) - author_link: https://twitter.com/tiangolo + author_link: https://x.com/tiangolo link: https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe title: Build a web API from scratch with FastAPI - the workshop - author: Paul Sec - author_link: https://twitter.com/PaulWebSec + author_link: https://x.com/PaulWebSec link: https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/ title: FastAPI + Zeit.co = 🚀 - author: cuongld2 @@ -169,7 +169,7 @@ Articles: link: https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o title: Build simple API service with Python FastAPI — Part 1 - author: Paurakh Sharma Humagain - author_link: https://twitter.com/PaurakhSharma + author_link: https://x.com/PaurakhSharma link: https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc title: Microservice in Python using FastAPI - author: Guillermo Cruz @@ -181,7 +181,7 @@ Articles: link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/ title: Create and Deploy FastAPI app to Heroku without using Docker - author: Arthur Henrique - author_link: https://twitter.com/arthurheinrique + author_link: https://x.com/arthurheinrique link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb title: 'Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest' - author: Shane Soh @@ -221,7 +221,7 @@ Articles: link: https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf title: How to Deploy a Machine Learning Model - author: Johannes Gontrum - author_link: https://twitter.com/gntrm + author_link: https://x.com/gntrm link: https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e title: JWT Authentication with FastAPI and AWS Cognito - author: Ankush Thakur @@ -257,7 +257,7 @@ Articles: link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59 title: FastAPI/Starlette debug vs prod - author: Mukul Mantosh - author_link: https://twitter.com/MantoshMukul + author_link: https://x.com/MantoshMukul link: https://www.jetbrains.com/pycharm/guide/tutorials/fastapi-aws-kubernetes/ title: Developing FastAPI Application using K8s & AWS - author: KrishNa @@ -282,7 +282,7 @@ Articles: 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 + author_link: https://x.com/_nicoax link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/ title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI - author: Felix SchÃŧrmeyer @@ -400,15 +400,15 @@ Talks: link: https://www.youtube.com/watch?v=uZdTe8_Z6BQ title: 'PyCon AU 2023: Testing asynchronous applications with FastAPI and pytest' - author: SebastiÃĄn Ramírez (tiangolo) - author_link: https://twitter.com/tiangolo + author_link: https://x.com/tiangolo link: https://www.youtube.com/watch?v=PnpTY1f4k2U title: '[VIRTUAL] Py.Amsterdam''s flying Software Circus: Intro to FastAPI' - author: SebastiÃĄn Ramírez (tiangolo) - author_link: https://twitter.com/tiangolo + author_link: https://x.com/tiangolo link: https://www.youtube.com/watch?v=z9K5pwb0rt8 title: 'PyConBY 2020: Serve ML models easily with FastAPI' - author: Chris Withers - author_link: https://twitter.com/chriswithers13 + author_link: https://x.com/chriswithers13 link: https://www.youtube.com/watch?v=3DLwPcrE5mA title: 'PyCon UK 2019: FastAPI from the ground up' Taiwanese: diff --git a/docs/en/data/github_sponsors.yml b/docs/en/data/github_sponsors.yml index 0cb200185..0daa96fb9 100644 --- a/docs/en/data/github_sponsors.yml +++ b/docs/en/data/github_sponsors.yml @@ -1,7 +1,4 @@ sponsors: -- - login: classmethod - avatarUrl: https://avatars.githubusercontent.com/u/1532151?v=4 - url: https://github.com/classmethod - - login: renderinc avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4 url: https://github.com/renderinc @@ -17,21 +14,15 @@ sponsors: - login: coderabbitai avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4 url: https://github.com/coderabbitai - - login: madisonredtfeldt - avatarUrl: https://avatars.githubusercontent.com/u/152656511?v=4 - url: https://github.com/madisonredtfeldt - login: subtotal avatarUrl: https://avatars.githubusercontent.com/u/176449348?v=4 url: https://github.com/subtotal - - login: Nixtla - avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4 - url: https://github.com/Nixtla + - login: railwayapp + avatarUrl: https://avatars.githubusercontent.com/u/66716858?v=4 + url: https://github.com/railwayapp - login: scalar avatarUrl: https://avatars.githubusercontent.com/u/301879?v=4 url: https://github.com/scalar -- - login: ObliviousAI - avatarUrl: https://avatars.githubusercontent.com/u/65656077?v=4 - url: https://github.com/ObliviousAI - - login: dribia avatarUrl: https://avatars.githubusercontent.com/u/41189616?v=4 url: https://github.com/dribia @@ -50,10 +41,7 @@ sponsors: - login: permitio avatarUrl: https://avatars.githubusercontent.com/u/71775833?v=4 url: https://github.com/permitio -- - login: xoflare - avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4 - url: https://github.com/xoflare - - login: marvin-robot +- - login: marvin-robot avatarUrl: https://avatars.githubusercontent.com/u/41086007?u=b9fcab402d0cd0aec738b6574fe60855cb0cd36d&v=4 url: https://github.com/marvin-robot - login: mercedes-benz @@ -62,9 +50,6 @@ sponsors: - login: Ponte-Energy-Partners avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4 url: https://github.com/Ponte-Energy-Partners - - login: snapit-cypher - avatarUrl: https://avatars.githubusercontent.com/u/115662654?v=4 - url: https://github.com/snapit-cypher - login: LambdaTest-Inc avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4 url: https://github.com/LambdaTest-Inc @@ -98,24 +83,24 @@ sponsors: - - login: upciti avatarUrl: https://avatars.githubusercontent.com/u/43346262?v=4 url: https://github.com/upciti + - login: giunio-prc + avatarUrl: https://avatars.githubusercontent.com/u/59511892?u=b37c1f1e177a4ee0212d24fb1f15edc9b23fd132&v=4 + url: https://github.com/giunio-prc - - login: samuelcolvin avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4 url: https://github.com/samuelcolvin - - login: CoodingPenguin - avatarUrl: https://avatars.githubusercontent.com/u/37505775?u=6a9e1f6647fbf95f99afeee82a3682e15fc6e959&v=4 - url: https://github.com/CoodingPenguin - - login: deight93 - avatarUrl: https://avatars.githubusercontent.com/u/37678115?u=a608798b5bd0034183a9c430ebb42fb266db86ce&v=4 - url: https://github.com/deight93 + - login: vincentkoc + avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4 + url: https://github.com/vincentkoc - login: otosky avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4 url: https://github.com/otosky - login: ramonalmeidam avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4 url: https://github.com/ramonalmeidam - - login: kaoru0310 - avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4 - url: https://github.com/kaoru0310 + - login: roboflow + avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4 + url: https://github.com/roboflow - login: RaamEEIL avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4 url: https://github.com/RaamEEIL @@ -131,48 +116,39 @@ sponsors: - login: Leay15 avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4 url: https://github.com/Leay15 - - login: ProteinQure - avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4 - url: https://github.com/ProteinQure + - login: chickenandstats + avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4 + url: https://github.com/chickenandstats + - login: kaoru0310 + avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4 + url: https://github.com/kaoru0310 - login: DelfinaCare avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4 url: https://github.com/DelfinaCare - login: Karine-Bauch avatarUrl: https://avatars.githubusercontent.com/u/90465103?u=7feb1018abb1a5631cfd9a91fea723d1ceb5f49b&v=4 url: https://github.com/Karine-Bauch - - login: eruditis - avatarUrl: https://avatars.githubusercontent.com/u/95244703?v=4 - url: https://github.com/eruditis - login: jugeeem avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4 url: https://github.com/jugeeem - - login: logic-automation - avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4 - url: https://github.com/logic-automation - - login: roboflow - avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4 - url: https://github.com/roboflow - login: dudikbender avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4 url: https://github.com/dudikbender - login: patsatsia avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4 url: https://github.com/patsatsia + - login: secrett2633 + avatarUrl: https://avatars.githubusercontent.com/u/65999962?v=4 + url: https://github.com/secrett2633 - login: anthonycepeda avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4 url: https://github.com/anthonycepeda - login: patricioperezv avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4 url: https://github.com/patricioperezv - - login: chickenandstats - avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4 - url: https://github.com/chickenandstats - login: dodo5522 avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4 url: https://github.com/dodo5522 - - login: nihpo - avatarUrl: https://avatars.githubusercontent.com/u/1841030?u=0264956d7580f7e46687a762a7baa629f84cf97c&v=4 - url: https://github.com/nihpo - login: knallgelb avatarUrl: https://avatars.githubusercontent.com/u/2358812?u=c48cb6362b309d74cbf144bd6ad3aed3eb443e82&v=4 url: https://github.com/knallgelb @@ -197,9 +173,12 @@ sponsors: - login: gorhack avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4 url: https://github.com/gorhack - - login: vincentkoc - avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4 - url: https://github.com/vincentkoc + - login: Ryandaydev + avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4 + url: https://github.com/Ryandaydev + - login: jaredtrog + avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4 + url: https://github.com/jaredtrog - login: jstanden avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4 url: https://github.com/jstanden @@ -215,9 +194,6 @@ sponsors: - login: pamelafox avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4 url: https://github.com/pamelafox - - login: ericof - avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4 - url: https://github.com/ericof - login: wshayes avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4 url: https://github.com/wshayes @@ -251,12 +227,6 @@ sponsors: - login: ashi-agrawal avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4 url: https://github.com/ashi-agrawal - - login: Ryandaydev - avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4 - url: https://github.com/Ryandaydev - - login: jaredtrog - avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4 - url: https://github.com/jaredtrog - login: oliverxchen avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4 url: https://github.com/oliverxchen @@ -275,14 +245,14 @@ sponsors: - login: hiancdtrsnm avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4 url: https://github.com/hiancdtrsnm -- - login: jpizquierdo - avatarUrl: https://avatars.githubusercontent.com/u/6716239?v=4 - url: https://github.com/jpizquierdo +- - login: manoelpqueiroz + avatarUrl: https://avatars.githubusercontent.com/u/23669137?u=b12e84b28a84369ab5b30bd5a79e5788df5a0756&v=4 + url: https://github.com/manoelpqueiroz - - login: pawamoy avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4 url: https://github.com/pawamoy - login: petercool - avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=81c525232bb35780945a68e88afd96bb2cdad9c4&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=75aa8c6729e6e8f85a300561c4dbeef9d65c8797&v=4 url: https://github.com/petercool - login: siavashyj avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4 @@ -296,12 +266,12 @@ sponsors: - login: caviri avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4 url: https://github.com/caviri + - login: hgalytoby + avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=6cc9028f3db63f8f60ad21c17b1ce4b88c4e2e60&v=4 + url: https://github.com/hgalytoby - login: joshuatz avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4 url: https://github.com/joshuatz - - login: SebTota - avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4 - url: https://github.com/SebTota - login: nisutec avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4 url: https://github.com/nisutec @@ -311,30 +281,21 @@ sponsors: - 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: engineerjoe440 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=db5e6f4f87836cad26c2aa90ce390ce49041c5a9&v=4 url: https://github.com/bnkc - - login: lukzmu - avatarUrl: https://avatars.githubusercontent.com/u/175964415?u=75348f25bb99a5f92ddb40c0b9b1ff7acb39c150&v=4 - url: https://github.com/lukzmu - - login: hgalytoby - avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4 - url: https://github.com/hgalytoby + - login: johnl28 + avatarUrl: https://avatars.githubusercontent.com/u/54412955?u=47dd06082d1c39caa90c752eb55566e4f3813957&v=4 + url: https://github.com/johnl28 - login: PunRabbit avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4 url: https://github.com/PunRabbit - login: PelicanQ avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4 url: https://github.com/PelicanQ - - login: browniebroke - avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4 - url: https://github.com/browniebroke - login: miguelgr avatarUrl: https://avatars.githubusercontent.com/u/1484589?u=54556072b8136efa12ae3b6902032ea2a39ace4b&v=4 url: https://github.com/miguelgr @@ -365,9 +326,6 @@ sponsors: - login: moonape1226 avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4 url: https://github.com/moonape1226 - - login: msehnout - avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4 - url: https://github.com/msehnout - login: xncbf avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4 url: https://github.com/xncbf @@ -389,9 +347,6 @@ sponsors: - login: Zuzah avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4 url: https://github.com/Zuzah - - login: artempronevskiy - avatarUrl: https://avatars.githubusercontent.com/u/12235104?u=03df6e1e55c9c6fe5d230adabb8dd7d43d8bbe8f&v=4 - url: https://github.com/artempronevskiy - login: TheR1D avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4 url: https://github.com/TheR1D @@ -422,36 +377,42 @@ sponsors: - - login: andrecorumba avatarUrl: https://avatars.githubusercontent.com/u/37807517?u=9b9be3b41da9bda60957da9ef37b50dbf65baa61&v=4 url: https://github.com/andrecorumba + - login: KOZ39 + avatarUrl: https://avatars.githubusercontent.com/u/38822500?u=9dfc0a697df1c9628f08e20dc3fb17b1afc4e5a7&v=4 + url: https://github.com/KOZ39 - login: rwxd avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4 url: https://github.com/rwxd - login: morzan1001 avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4 url: https://github.com/morzan1001 - - login: sadikkuzu - avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4 - url: https://github.com/sadikkuzu - login: Olegt0rr avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4 url: https://github.com/Olegt0rr - login: larsyngvelundin avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4 url: https://github.com/larsyngvelundin + - login: henriquesebastiao + avatarUrl: https://avatars.githubusercontent.com/u/85202803?u=1b31ff01127bd267a87c97ff6319c77d91be606f&v=4 + url: https://github.com/henriquesebastiao + - login: olexkram + avatarUrl: https://avatars.githubusercontent.com/u/148793576?v=4 + url: https://github.com/olexkram - login: 0ne-stone avatarUrl: https://avatars.githubusercontent.com/u/62360849?u=746dd21c34e7e06eefb11b03e8bb01aaae3c2a4f&v=4 url: https://github.com/0ne-stone - - login: darixsamani - avatarUrl: https://avatars.githubusercontent.com/u/67915678?u=cfa82128692eeeec4bf0e7a0faaa9a614695c0f9&v=4 - url: https://github.com/darixsamani - login: nayasinghania - avatarUrl: https://avatars.githubusercontent.com/u/74111380?u=af853245a21fe052b6a27e41a8de8cf4cdf76e85&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/74111380?u=752e99a5e139389fdc0a0677122adc08438eb076&v=4 url: https://github.com/nayasinghania - login: Toothwitch avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4 url: https://github.com/Toothwitch - - login: roboman-tech - avatarUrl: https://avatars.githubusercontent.com/u/8183070?u=fdeaa2ed29f598eb7901693884c0ad32b16982e3&v=4 - url: https://github.com/roboman-tech - login: andreagrandi avatarUrl: https://avatars.githubusercontent.com/u/636391?u=13d90cb8ec313593a5b71fbd4e33b78d6da736f5&v=4 url: https://github.com/andreagrandi + - login: roboman-tech + avatarUrl: https://avatars.githubusercontent.com/u/8183070?u=fdeaa2ed29f598eb7901693884c0ad32b16982e3&v=4 + url: https://github.com/roboman-tech + - login: msserpa + avatarUrl: https://avatars.githubusercontent.com/u/6334934?u=82c4489eb1559d88d2990d60001901b14f722bbb&v=4 + url: https://github.com/msserpa diff --git a/docs/en/data/people.yml b/docs/en/data/people.yml index e3eab5d01..2fdb21a05 100644 --- a/docs/en/data/people.yml +++ b/docs/en/data/people.yml @@ -1,16 +1,16 @@ maintainers: - login: tiangolo - answers: 1898 + answers: 1900 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo experts: - login: tiangolo - count: 1898 + count: 1900 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo - login: YuriiMotov - count: 941 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 + count: 971 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 url: https://github.com/YuriiMotov - login: github-actions count: 769 @@ -53,11 +53,11 @@ experts: avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4 url: https://github.com/phy25 - login: JavierSanchezCastro - count: 93 + count: 94 avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4 url: https://github.com/JavierSanchezCastro - login: luzzodev - count: 84 + count: 89 avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4 url: https://github.com/luzzodev - login: raphaelauv @@ -81,7 +81,7 @@ experts: avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4 url: https://github.com/falkben - login: yinziyan1206 - count: 50 + count: 54 avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4 url: https://github.com/yinziyan1206 - login: sm-Fifteen @@ -156,6 +156,10 @@ experts: count: 25 avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4 url: https://github.com/wshayes +- login: valentinDruzhinin + count: 24 + avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 + url: https://github.com/valentinDruzhinin - login: SirTelemak count: 23 avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4 @@ -190,8 +194,12 @@ experts: url: https://github.com/ebottos94 - login: estebanx64 count: 19 - avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=1900887aeed268699e5ea6f3fb7db614f7b77cd3&v=4 url: https://github.com/estebanx64 +- login: sehraramiz + count: 18 + avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4 + url: https://github.com/sehraramiz - login: retnikt count: 18 avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4 @@ -200,10 +208,10 @@ experts: count: 18 avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4 url: https://github.com/zoliknemet -- login: sehraramiz - count: 18 - avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4 - url: https://github.com/sehraramiz +- login: caeser1996 + count: 17 + avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4 + url: https://github.com/caeser1996 - login: Hultner count: 17 avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4 @@ -212,10 +220,6 @@ experts: count: 17 avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4 url: https://github.com/harunyasar -- login: caeser1996 - count: 17 - avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4 - url: https://github.com/caeser1996 - login: nkhitrov count: 17 avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=e19427d8dc296d6950e9c424adacc92d37496fe9&v=4 @@ -224,6 +228,10 @@ experts: count: 16 avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4 url: https://github.com/dstlny +- login: pythonweb2 + count: 16 + avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4 + url: https://github.com/pythonweb2 - login: jonatasoli count: 16 avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=f601c3f111f2148bd9244c2cb3ebbd57b592e674&v=4 @@ -232,153 +240,125 @@ experts: count: 15 avatarUrl: https://avatars.githubusercontent.com/u/10137?u=b1951d34a583cf12ec0d3b0781ba19be97726318&v=4 url: https://github.com/ghost -- login: jorgerpo - count: 15 - avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4 - url: https://github.com/jorgerpo -- login: pythonweb2 - count: 15 - avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4 - url: https://github.com/pythonweb2 - login: abhint count: 15 avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4 url: https://github.com/abhint last_month_experts: - login: YuriiMotov - count: 289 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 + count: 17 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 url: https://github.com/YuriiMotov +- login: valentinDruzhinin + count: 5 + avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 + url: https://github.com/valentinDruzhinin +- login: yinziyan1206 + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4 + url: https://github.com/yinziyan1206 +- login: tiangolo + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 + url: https://github.com/tiangolo - login: luzzodev - count: 12 + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4 + url: https://github.com/luzzodev +three_months_experts: +- login: YuriiMotov + count: 397 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 + url: https://github.com/YuriiMotov +- login: valentinDruzhinin + count: 24 + avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 + url: https://github.com/valentinDruzhinin +- login: luzzodev + count: 17 avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4 url: https://github.com/luzzodev - login: raceychan count: 6 avatarUrl: https://avatars.githubusercontent.com/u/75417963?u=060c62870ec5a791765e63ac20d8885d11143786&v=4 url: https://github.com/raceychan -- login: valentinDruzhinin +- login: yinziyan1206 count: 5 - avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 - url: https://github.com/valentinDruzhinin + avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4 + url: https://github.com/yinziyan1206 - login: DoctorJohn count: 5 avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=2913e70a6142772847e91e2aaa5b9152391715e9&v=4 url: https://github.com/DoctorJohn -- login: eqsdxr +- login: tiangolo count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=58fddf77ed76966eaa8c73eea9bea4bb0c53b673&v=4 - url: https://github.com/eqsdxr + avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 + url: https://github.com/tiangolo - login: sachinh35 count: 4 avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4 url: https://github.com/sachinh35 -- login: tiangolo +- login: eqsdxr + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=58fddf77ed76966eaa8c73eea9bea4bb0c53b673&v=4 + url: https://github.com/eqsdxr +- login: Jelle-tenB + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/210023470?u=c25d66addf36a747bd9fab773c4a6e7b238f45d4&v=4 + url: https://github.com/Jelle-tenB +- login: pythonweb2 count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 - url: https://github.com/tiangolo + avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4 + url: https://github.com/pythonweb2 +- login: WilliamDEdwards + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/12184311?u=9b29d5d1d71f5f1a7ef9e439963ad3529e3b33a4&v=4 + url: https://github.com/WilliamDEdwards - login: Brikas count: 2 avatarUrl: https://avatars.githubusercontent.com/u/80290187?v=4 url: https://github.com/Brikas -- login: TaigoFr +- login: purepani count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4 - url: https://github.com/TaigoFr -three_months_experts: -- login: YuriiMotov - count: 732 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 - url: https://github.com/YuriiMotov -- login: luzzodev - count: 26 - avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4 - url: https://github.com/luzzodev -- login: valentinDruzhinin - count: 14 - avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 - url: https://github.com/valentinDruzhinin -- login: sachinh35 - count: 8 - avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4 - url: https://github.com/sachinh35 -- login: raceychan - count: 6 - avatarUrl: https://avatars.githubusercontent.com/u/75417963?u=060c62870ec5a791765e63ac20d8885d11143786&v=4 - url: https://github.com/raceychan -- login: DoctorJohn - count: 5 - avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=2913e70a6142772847e91e2aaa5b9152391715e9&v=4 - url: https://github.com/DoctorJohn -- login: eqsdxr - count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=58fddf77ed76966eaa8c73eea9bea4bb0c53b673&v=4 - url: https://github.com/eqsdxr -- login: tiangolo - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 - url: https://github.com/tiangolo + avatarUrl: https://avatars.githubusercontent.com/u/7587353?v=4 + url: https://github.com/purepani - login: JavierSanchezCastro count: 2 avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4 url: https://github.com/JavierSanchezCastro -- login: henrymcl +- login: TaigoFr count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/26480299?v=4 - url: https://github.com/henrymcl + avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4 + url: https://github.com/TaigoFr +- login: Garrett-R + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/6614695?u=c128fd775002882f6e391bda5a89d1bdc5bdf45f&v=4 + url: https://github.com/Garrett-R - login: jymchng count: 2 avatarUrl: https://avatars.githubusercontent.com/u/27895426?u=fb88c47775147d62a395fdb895d1af4148c7b566&v=4 url: https://github.com/jymchng -- login: Brikas - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/80290187?v=4 - url: https://github.com/Brikas -- login: TaigoFr - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4 - url: https://github.com/TaigoFr - login: davidhuser count: 2 avatarUrl: https://avatars.githubusercontent.com/u/4357648?u=6ed702f8f6d49a8b2a0ed33cbd8ab59c2d7db7f7&v=4 url: https://github.com/davidhuser -- login: KianAnbarestani - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4 - url: https://github.com/KianAnbarestani -- login: Kludex - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4 - url: https://github.com/Kludex six_months_experts: - login: YuriiMotov - count: 749 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 + count: 763 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 url: https://github.com/YuriiMotov - login: luzzodev - count: 51 + count: 45 avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4 url: https://github.com/luzzodev -- login: alv2017 - count: 26 - avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4 - url: https://github.com/alv2017 -- login: Kludex - count: 20 - avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4 - url: https://github.com/Kludex - login: valentinDruzhinin - count: 14 + count: 24 avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 url: https://github.com/valentinDruzhinin -- login: jgould22 - count: 13 - avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4 - url: https://github.com/jgould22 -- login: JavierSanchezCastro - count: 10 - avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4 - url: https://github.com/JavierSanchezCastro +- login: alv2017 + count: 16 + avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4 + url: https://github.com/alv2017 - login: sachinh35 count: 9 avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4 @@ -388,29 +368,65 @@ six_months_experts: avatarUrl: https://avatars.githubusercontent.com/u/51629535?u=fc1817060daf2df438bfca86c44f33da5cd667db&v=4 url: https://github.com/yauhen-sobaleu - login: tiangolo - count: 8 + count: 6 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo +- login: JavierSanchezCastro + count: 6 + avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4 + url: https://github.com/JavierSanchezCastro - login: raceychan count: 6 avatarUrl: https://avatars.githubusercontent.com/u/75417963?u=060c62870ec5a791765e63ac20d8885d11143786&v=4 url: https://github.com/raceychan +- login: yinziyan1206 + count: 5 + avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4 + url: https://github.com/yinziyan1206 - login: DoctorJohn count: 5 avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=2913e70a6142772847e91e2aaa5b9152391715e9&v=4 url: https://github.com/DoctorJohn -- login: sehraramiz - count: 5 - avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4 - url: https://github.com/sehraramiz - login: eqsdxr count: 4 avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=58fddf77ed76966eaa8c73eea9bea4bb0c53b673&v=4 url: https://github.com/eqsdxr -- login: SobikXexe +- login: Kludex + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4 + url: https://github.com/Kludex +- login: Jelle-tenB count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4 - url: https://github.com/SobikXexe + avatarUrl: https://avatars.githubusercontent.com/u/210023470?u=c25d66addf36a747bd9fab773c4a6e7b238f45d4&v=4 + url: https://github.com/Jelle-tenB +- login: adsouza + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/275832?u=f90f110cfafeafed2f14339e840941c2c328c186&v=4 + url: https://github.com/adsouza +- login: pythonweb2 + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4 + url: https://github.com/pythonweb2 +- login: WilliamDEdwards + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/12184311?u=9b29d5d1d71f5f1a7ef9e439963ad3529e3b33a4&v=4 + url: https://github.com/WilliamDEdwards +- login: Brikas + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/80290187?v=4 + url: https://github.com/Brikas +- login: purepani + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/7587353?v=4 + url: https://github.com/purepani +- login: TaigoFr + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4 + url: https://github.com/TaigoFr +- login: Garrett-R + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/6614695?u=c128fd775002882f6e391bda5a89d1bdc5bdf45f&v=4 + url: https://github.com/Garrett-R - login: EverStarck count: 2 avatarUrl: https://avatars.githubusercontent.com/u/51029456?u=343409b7cb6b3ea6a59359f4e8370d9c3f140ecd&v=4 @@ -423,22 +439,6 @@ six_months_experts: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/27895426?u=fb88c47775147d62a395fdb895d1af4148c7b566&v=4 url: https://github.com/jymchng -- login: adsouza - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/275832?v=4 - url: https://github.com/adsouza -- login: Brikas - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/80290187?v=4 - url: https://github.com/Brikas -- login: JacobHayes - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/2555532?u=354a525847a276bbb4426b0c95791a8ba5970f9b&v=4 - url: https://github.com/JacobHayes -- login: TaigoFr - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4 - url: https://github.com/TaigoFr - login: davidhuser count: 2 avatarUrl: https://avatars.githubusercontent.com/u/4357648?u=6ed702f8f6d49a8b2a0ed33cbd8ab59c2d7db7f7&v=4 @@ -451,87 +451,59 @@ six_months_experts: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4 url: https://github.com/KianAnbarestani -- login: Ykaiqx +- login: jgould22 count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=1eebf5ce25a8067f7bfa6251a24f667be492d9d6&v=4 - url: https://github.com/Ykaiqx -- login: sinisaos - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4 - url: https://github.com/sinisaos -- login: Ale-Cas - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4 - url: https://github.com/Ale-Cas -- login: nbx3 - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/34649527?u=943812f69e0d40adbd3fa1c9b8ef50dd971a2a45&v=4 - url: https://github.com/nbx3 + avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4 + url: https://github.com/jgould22 - login: marsboy02 count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/86903678?u=efe3aa9e4b22689df7633a96328fb35bf4a23905&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/86903678?u=04cc319d6605f8d1ba3a0bed9f4f55a582719ae6&v=4 url: https://github.com/marsboy02 -- login: vtgn - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4 - url: https://github.com/vtgn -- login: Trinkes - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4 - url: https://github.com/Trinkes one_year_experts: - login: YuriiMotov - count: 831 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 + count: 824 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 url: https://github.com/YuriiMotov - login: luzzodev - count: 84 + count: 89 avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4 url: https://github.com/luzzodev - login: Kludex - count: 55 + count: 50 avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4 url: https://github.com/Kludex - login: sinisaos - count: 41 + count: 33 avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4 url: https://github.com/sinisaos - login: alv2017 count: 26 avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4 url: https://github.com/alv2017 +- login: valentinDruzhinin + count: 24 + avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 + url: https://github.com/valentinDruzhinin - login: JavierSanchezCastro - count: 25 + count: 24 avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4 url: https://github.com/JavierSanchezCastro -- login: tiangolo - count: 22 - avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 - url: https://github.com/tiangolo - login: jgould22 count: 17 avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4 url: https://github.com/jgould22 -- login: valentinDruzhinin +- login: tiangolo count: 14 - avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 - url: https://github.com/valentinDruzhinin + avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 + url: https://github.com/tiangolo - login: Kfir-G count: 13 - avatarUrl: https://avatars.githubusercontent.com/u/57500876?u=0cd29db046a17f12f382d398141319fca7ff230a&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/57500876?u=a3bf923ab27bce3d1b13779a8dd22eb7675017fd&v=4 url: https://github.com/Kfir-G -- login: estebanx64 - count: 11 - avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4 - url: https://github.com/estebanx64 - login: sehraramiz count: 11 avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4 url: https://github.com/sehraramiz -- login: ceb10n - count: 10 - avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 - url: https://github.com/ceb10n - login: sachinh35 count: 9 avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4 @@ -540,10 +512,14 @@ one_year_experts: count: 9 avatarUrl: https://avatars.githubusercontent.com/u/51629535?u=fc1817060daf2df438bfca86c44f33da5cd667db&v=4 url: https://github.com/yauhen-sobaleu -- login: n8sty - count: 8 - avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4 - url: https://github.com/n8sty +- login: estebanx64 + count: 7 + avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=1900887aeed268699e5ea6f3fb7db614f7b77cd3&v=4 + url: https://github.com/estebanx64 +- login: ceb10n + count: 7 + avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 + url: https://github.com/ceb10n - login: yvallois count: 7 avatarUrl: https://avatars.githubusercontent.com/u/36999744?v=4 @@ -552,54 +528,50 @@ one_year_experts: count: 6 avatarUrl: https://avatars.githubusercontent.com/u/75417963?u=060c62870ec5a791765e63ac20d8885d11143786&v=4 url: https://github.com/raceychan +- login: yinziyan1206 + count: 5 + avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4 + url: https://github.com/yinziyan1206 - login: DoctorJohn count: 5 avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=2913e70a6142772847e91e2aaa5b9152391715e9&v=4 url: https://github.com/DoctorJohn -- login: AIdjis +- login: n8sty count: 5 - avatarUrl: https://avatars.githubusercontent.com/u/88404339?u=2a80d80b054e9228391e32fb9bb39571509dab6a&v=4 - url: https://github.com/AIdjis + avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4 + url: https://github.com/n8sty +- login: pythonweb2 + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4 + url: https://github.com/pythonweb2 - login: eqsdxr count: 4 avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=58fddf77ed76966eaa8c73eea9bea4bb0c53b673&v=4 url: https://github.com/eqsdxr -- login: TomFaulkner - count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/14956620?v=4 - url: https://github.com/TomFaulkner - login: yokwejuste count: 4 avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=4ba43bd63c169b5c015137d8916752a44001445a&v=4 url: https://github.com/yokwejuste -- login: PhysicallyActive - count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4 - url: https://github.com/PhysicallyActive -- login: svlandeg - count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4 - url: https://github.com/svlandeg +- login: WilliamDEdwards + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/12184311?u=9b29d5d1d71f5f1a7ef9e439963ad3529e3b33a4&v=4 + url: https://github.com/WilliamDEdwards - login: mattmess1221 count: 3 avatarUrl: https://avatars.githubusercontent.com/u/3409962?u=d22ea18aa8ea688af25a45df306134d593621a44&v=4 url: https://github.com/mattmess1221 -- login: pythonweb2 +- login: Jelle-tenB count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4 - url: https://github.com/pythonweb2 + avatarUrl: https://avatars.githubusercontent.com/u/210023470?u=c25d66addf36a747bd9fab773c4a6e7b238f45d4&v=4 + url: https://github.com/Jelle-tenB - login: viniciusCalcantara count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=3d7ffe5808843ee4372f9cc5a559ff1674cf1792&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=80f3ec7427fa6a41d5896984d0c526432f2299fa&v=4 url: https://github.com/viniciusCalcantara - login: davidhuser count: 3 avatarUrl: https://avatars.githubusercontent.com/u/4357648?u=6ed702f8f6d49a8b2a0ed33cbd8ab59c2d7db7f7&v=4 url: https://github.com/davidhuser -- login: bertomaniac - count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/10235051?u=14484a96833228a7b29fee4a7916d411c242c4f6&v=4 - url: https://github.com/bertomaniac - login: dbfreem count: 3 avatarUrl: https://avatars.githubusercontent.com/u/9778569?u=f2f1e9135b5e4f1b0c6821a548b17f97572720fc&v=4 @@ -608,10 +580,6 @@ one_year_experts: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4 url: https://github.com/SobikXexe -- login: DeoLeung - count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/3764720?u=4c222ef513814de4c7fb3736d0a7adf11d953d43&v=4 - url: https://github.com/DeoLeung - login: pawelad count: 3 avatarUrl: https://avatars.githubusercontent.com/u/7062874?u=d27dc220545a8401ad21840590a97d474d7101e6&v=4 @@ -624,37 +592,9 @@ one_year_experts: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/8108085?u=b028dbc308fa8485e0e2e9402b3d03d8deb22bf9&v=4 url: https://github.com/Minibrams -- login: yanggeorge - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/2434407?v=4 - url: https://github.com/yanggeorge -- login: mmzeynalli - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/33568903?u=19efd0c0722730b83a70b7c86c36e5b7d83e07d2&v=4 - url: https://github.com/mmzeynalli -- login: jd-solanki - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/47495003?u=6e225cb42c688d0cd70e65c6baedb9f5922b1178&v=4 - url: https://github.com/jd-solanki -- login: EverStarck - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/51029456?u=343409b7cb6b3ea6a59359f4e8370d9c3f140ecd&v=4 - url: https://github.com/EverStarck -- login: slafs - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4 - url: https://github.com/slafs -- login: henrymcl - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/26480299?v=4 - url: https://github.com/henrymcl -- login: jymchng - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/27895426?u=fb88c47775147d62a395fdb895d1af4148c7b566&v=4 - url: https://github.com/jymchng - login: adsouza count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/275832?v=4 + avatarUrl: https://avatars.githubusercontent.com/u/275832?u=f90f110cfafeafed2f14339e840941c2c328c186&v=4 url: https://github.com/adsouza - login: Synrom count: 2 @@ -664,26 +604,70 @@ one_year_experts: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/835733?u=8c72dec16fa560bdc81113354f2ffd79ad062bde&v=4 url: https://github.com/gaby -- login: christiansicari +- login: Ale-Cas count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/29756552?v=4 - url: https://github.com/christiansicari + avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4 + url: https://github.com/Ale-Cas +- login: CharlesPerrotMinotHCHB + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/112571330?u=e3a666718ff5ad1d1c49d6c31358a9f80c841b30&v=4 + url: https://github.com/CharlesPerrotMinotHCHB +- login: yanggeorge + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/2434407?v=4 + url: https://github.com/yanggeorge - login: Brikas count: 2 avatarUrl: https://avatars.githubusercontent.com/u/80290187?v=4 url: https://github.com/Brikas -- login: JacobHayes +- login: dolfinus count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/2555532?u=354a525847a276bbb4426b0c95791a8ba5970f9b&v=4 - url: https://github.com/JacobHayes + avatarUrl: https://avatars.githubusercontent.com/u/4661021?u=ed5ddadcf36d9b943ebe61febe0b96ee34e5425d&v=4 + url: https://github.com/dolfinus +- login: slafs + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4 + url: https://github.com/slafs +- login: purepani + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/7587353?v=4 + url: https://github.com/purepani +- login: ddahan + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/1933516?u=1d200a620e8d6841df017e9f2bb7efb58b580f40&v=4 + url: https://github.com/ddahan - login: TaigoFr count: 2 avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4 url: https://github.com/TaigoFr -- login: rlimberger +- login: Garrett-R count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/4841242?u=6a13252caf3cedceb07b6e2775b6592445d13b70&v=4 - url: https://github.com/rlimberger + avatarUrl: https://avatars.githubusercontent.com/u/6614695?u=c128fd775002882f6e391bda5a89d1bdc5bdf45f&v=4 + url: https://github.com/Garrett-R +- login: jd-solanki + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/47495003?u=6e225cb42c688d0cd70e65c6baedb9f5922b1178&v=4 + url: https://github.com/jd-solanki +- login: EverStarck + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/51029456?u=343409b7cb6b3ea6a59359f4e8370d9c3f140ecd&v=4 + url: https://github.com/EverStarck +- login: henrymcl + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/26480299?v=4 + url: https://github.com/henrymcl +- login: jymchng + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/27895426?u=fb88c47775147d62a395fdb895d1af4148c7b566&v=4 + url: https://github.com/jymchng +- login: christiansicari + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/29756552?v=4 + url: https://github.com/christiansicari +- login: JacobHayes + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/2555532?u=354a525847a276bbb4426b0c95791a8ba5970f9b&v=4 + url: https://github.com/JacobHayes - login: iloveitaly count: 2 avatarUrl: https://avatars.githubusercontent.com/u/150855?v=4 @@ -692,10 +676,6 @@ one_year_experts: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/131771119?u=bcaf2559ef6266af70b151b7fda31a1ee3dbecb3&v=4 url: https://github.com/iiotsrc -- login: AmirHmZz - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/38752106?u=07f80e451bda00a9492bbc764e49d24ad3ada8cc&v=4 - url: https://github.com/AmirHmZz - login: PidgeyBE count: 2 avatarUrl: https://avatars.githubusercontent.com/u/19860056?u=47b584eb1c1ab45e31c1b474109a962d7e82be49&v=4 @@ -704,19 +684,19 @@ one_year_experts: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4 url: https://github.com/KianAnbarestani -- login: Ykaiqx +- login: ykaiqx count: 2 avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=1eebf5ce25a8067f7bfa6251a24f667be492d9d6&v=4 - url: https://github.com/Ykaiqx + url: https://github.com/ykaiqx - login: AliYmn count: 2 avatarUrl: https://avatars.githubusercontent.com/u/18416653?u=a77e2605e3ce6aaf6fef8ad4a7b0d32954fba47a&v=4 url: https://github.com/AliYmn -- login: dolfinus - count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/4661021?u=ed5ddadcf36d9b943ebe61febe0b96ee34e5425d&v=4 - url: https://github.com/dolfinus - login: gelezo43 count: 2 avatarUrl: https://avatars.githubusercontent.com/u/40732698?u=611f39d3c1d2f4207a590937a78c1f10eed6232c&v=4 url: https://github.com/gelezo43 +- login: jfeaver + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/1091338?u=0bcba366447d8fadad63f6705a52d128da4c7ec2&v=4 + url: https://github.com/jfeaver diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml index f712b6179..ae28410e7 100644 --- a/docs/en/data/sponsors.yml +++ b/docs/en/data/sponsors.yml @@ -2,9 +2,6 @@ gold: - url: https://blockbee.io?ref=fastapi title: BlockBee Cryptocurrency Payment Gateway img: https://fastapi.tiangolo.com/img/sponsors/blockbee.png - - 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 - url: https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge title: "Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files" img: https://fastapi.tiangolo.com/img/sponsors/scalar.svg @@ -26,8 +23,11 @@ gold: - url: https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source title: The Gold Standard in Retail Account Linking img: https://fastapi.tiangolo.com/img/sponsors/subtotal.svg + - url: https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi + title: Deploy enterprise applications at startup speed + img: https://fastapi.tiangolo.com/img/sponsors/railway.png silver: - - url: https://databento.com/ + - url: https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display title: Pay as you go for market data img: https://fastapi.tiangolo.com/img/sponsors/databento.svg - url: https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship diff --git a/docs/en/data/sponsors_badge.yml b/docs/en/data/sponsors_badge.yml index d145e7372..62ba6a84c 100644 --- a/docs/en/data/sponsors_badge.yml +++ b/docs/en/data/sponsors_badge.yml @@ -43,3 +43,6 @@ logins: - permitio - LambdaTest-Inc - dribia + - madisonredtfeldt + - railwayapp + - subtotal diff --git a/docs/en/data/topic_repos.yml b/docs/en/data/topic_repos.yml index ab9f21995..af5bb21d5 100644 --- a/docs/en/data/topic_repos.yml +++ b/docs/en/data/topic_repos.yml @@ -1,495 +1,495 @@ - name: full-stack-fastapi-template html_url: https://github.com/fastapi/full-stack-fastapi-template - stars: 34156 + stars: 37341 owner_login: fastapi owner_html_url: https://github.com/fastapi - name: Hello-Python html_url: https://github.com/mouredev/Hello-Python - stars: 30835 + stars: 31799 owner_login: mouredev owner_html_url: https://github.com/mouredev - name: serve html_url: https://github.com/jina-ai/serve - stars: 21631 + stars: 21721 owner_login: jina-ai owner_html_url: https://github.com/jina-ai - name: HivisionIDPhotos html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos - stars: 18125 + stars: 19114 owner_login: Zeyi-Lin owner_html_url: https://github.com/Zeyi-Lin - name: sqlmodel html_url: https://github.com/fastapi/sqlmodel - stars: 16249 + stars: 16678 owner_login: fastapi owner_html_url: https://github.com/fastapi - name: Douyin_TikTok_Download_API html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API - stars: 13279 + stars: 14126 owner_login: Evil0ctal owner_html_url: https://github.com/Evil0ctal - name: fastapi-best-practices html_url: https://github.com/zhanymkanov/fastapi-best-practices - stars: 12334 + stars: 13189 owner_login: zhanymkanov owner_html_url: https://github.com/zhanymkanov - name: awesome-fastapi html_url: https://github.com/mjhea0/awesome-fastapi - stars: 9934 + stars: 10264 owner_login: mjhea0 owner_html_url: https://github.com/mjhea0 +- name: fastapi_mcp + html_url: https://github.com/tadata-org/fastapi_mcp + stars: 9964 + owner_login: tadata-org + owner_html_url: https://github.com/tadata-org - name: FastUI html_url: https://github.com/pydantic/FastUI - stars: 8838 + stars: 8861 owner_login: pydantic owner_html_url: https://github.com/pydantic - name: XHS-Downloader html_url: https://github.com/JoeanAmier/XHS-Downloader - stars: 7962 + stars: 8576 owner_login: JoeanAmier owner_html_url: https://github.com/JoeanAmier -- name: nonebot2 - html_url: https://github.com/nonebot/nonebot2 - stars: 6834 - owner_login: nonebot - owner_html_url: https://github.com/nonebot +- name: SurfSense + html_url: https://github.com/MODSetter/SurfSense + stars: 7421 + owner_login: MODSetter + owner_html_url: https://github.com/MODSetter - name: FileCodeBox html_url: https://github.com/vastsa/FileCodeBox - stars: 6783 + stars: 7179 owner_login: vastsa owner_html_url: https://github.com/vastsa -- name: fastapi_mcp - html_url: https://github.com/tadata-org/fastapi_mcp - stars: 5846 - owner_login: tadata-org - owner_html_url: https://github.com/tadata-org +- name: polar + html_url: https://github.com/polarsource/polar + stars: 7106 + owner_login: polarsource + owner_html_url: https://github.com/polarsource +- name: nonebot2 + html_url: https://github.com/nonebot/nonebot2 + stars: 6998 + owner_login: nonebot + owner_html_url: https://github.com/nonebot - name: hatchet html_url: https://github.com/hatchet-dev/hatchet - stars: 5773 + stars: 5978 owner_login: hatchet-dev owner_html_url: https://github.com/hatchet-dev - name: serge html_url: https://github.com/serge-chat/serge - stars: 5728 + stars: 5751 owner_login: serge-chat owner_html_url: https://github.com/serge-chat -- name: polar - html_url: https://github.com/polarsource/polar - stars: 5709 - owner_login: polarsource - owner_html_url: https://github.com/polarsource - name: fastapi-users html_url: https://github.com/fastapi-users/fastapi-users - stars: 5336 + stars: 5517 owner_login: fastapi-users owner_html_url: https://github.com/fastapi-users - name: strawberry html_url: https://github.com/strawberry-graphql/strawberry - stars: 4317 + stars: 4392 owner_login: strawberry-graphql owner_html_url: https://github.com/strawberry-graphql - name: chatgpt-web-share html_url: https://github.com/chatpire/chatgpt-web-share - stars: 4301 + stars: 4305 owner_login: chatpire owner_html_url: https://github.com/chatpire -- name: atrilabs-engine - html_url: https://github.com/Atri-Labs/atrilabs-engine - stars: 4106 - owner_login: Atri-Labs - owner_html_url: https://github.com/Atri-Labs -- name: dynaconf - html_url: https://github.com/dynaconf/dynaconf - stars: 4045 - owner_login: dynaconf - owner_html_url: https://github.com/dynaconf - name: poem html_url: https://github.com/poem-web/poem - stars: 4037 + stars: 4157 owner_login: poem-web owner_html_url: https://github.com/poem-web -- name: farfalle - html_url: https://github.com/rashadphz/farfalle - stars: 3348 - owner_login: rashadphz - owner_html_url: https://github.com/rashadphz -- name: LitServe - html_url: https://github.com/Lightning-AI/LitServe - stars: 3347 - owner_login: Lightning-AI - owner_html_url: https://github.com/Lightning-AI -- name: fastapi-admin - html_url: https://github.com/fastapi-admin/fastapi-admin - stars: 3309 - owner_login: fastapi-admin - owner_html_url: https://github.com/fastapi-admin -- name: datamodel-code-generator - html_url: https://github.com/koxudaxi/datamodel-code-generator - stars: 3291 - owner_login: koxudaxi - owner_html_url: https://github.com/koxudaxi -- name: logfire - html_url: https://github.com/pydantic/logfire - stars: 3288 - owner_login: pydantic - owner_html_url: https://github.com/pydantic -- name: huma - html_url: https://github.com/danielgtaylor/huma - stars: 3201 - owner_login: danielgtaylor - owner_html_url: https://github.com/danielgtaylor -- name: opyrator - html_url: https://github.com/ml-tooling/opyrator - stars: 3132 - owner_login: ml-tooling - owner_html_url: https://github.com/ml-tooling +- name: dynaconf + html_url: https://github.com/dynaconf/dynaconf + stars: 4112 + owner_login: dynaconf + owner_html_url: https://github.com/dynaconf +- name: atrilabs-engine + html_url: https://github.com/Atri-Labs/atrilabs-engine + stars: 4104 + owner_login: Atri-Labs + owner_html_url: https://github.com/Atri-Labs - name: Kokoro-FastAPI html_url: https://github.com/remsky/Kokoro-FastAPI - stars: 3099 + stars: 3569 owner_login: remsky owner_html_url: https://github.com/remsky +- name: LitServe + html_url: https://github.com/Lightning-AI/LitServe + stars: 3531 + owner_login: Lightning-AI + owner_html_url: https://github.com/Lightning-AI +- name: logfire + html_url: https://github.com/pydantic/logfire + stars: 3510 + owner_login: pydantic + owner_html_url: https://github.com/pydantic +- name: datamodel-code-generator + html_url: https://github.com/koxudaxi/datamodel-code-generator + stars: 3425 + owner_login: koxudaxi + owner_html_url: https://github.com/koxudaxi +- name: farfalle + html_url: https://github.com/rashadphz/farfalle + stars: 3420 + owner_login: rashadphz + owner_html_url: https://github.com/rashadphz +- name: fastapi-admin + html_url: https://github.com/fastapi-admin/fastapi-admin + stars: 3417 + owner_login: fastapi-admin + owner_html_url: https://github.com/fastapi-admin +- name: huma + html_url: https://github.com/danielgtaylor/huma + stars: 3351 + owner_login: danielgtaylor + owner_html_url: https://github.com/danielgtaylor +- name: tracecat + html_url: https://github.com/TracecatHQ/tracecat + stars: 3213 + owner_login: TracecatHQ + owner_html_url: https://github.com/TracecatHQ +- name: opyrator + html_url: https://github.com/ml-tooling/opyrator + stars: 3131 + owner_login: ml-tooling + owner_html_url: https://github.com/ml-tooling - name: docarray html_url: https://github.com/docarray/docarray - stars: 3075 + stars: 3098 owner_login: docarray owner_html_url: https://github.com/docarray - name: fastapi-realworld-example-app html_url: https://github.com/nsidnev/fastapi-realworld-example-app - stars: 2902 + stars: 2925 owner_login: nsidnev owner_html_url: https://github.com/nsidnev -- name: tracecat - html_url: https://github.com/TracecatHQ/tracecat - stars: 2888 - owner_login: TracecatHQ - owner_html_url: https://github.com/TracecatHQ - name: uvicorn-gunicorn-fastapi-docker html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker - stars: 2775 + stars: 2796 owner_login: tiangolo owner_html_url: https://github.com/tiangolo - name: best-of-web-python html_url: https://github.com/ml-tooling/best-of-web-python - stars: 2537 + stars: 2583 owner_login: ml-tooling owner_html_url: https://github.com/ml-tooling - name: RasaGPT html_url: https://github.com/paulpierre/RasaGPT - stars: 2427 + stars: 2438 owner_login: paulpierre owner_html_url: https://github.com/paulpierre - name: fastapi-react html_url: https://github.com/Buuntu/fastapi-react - stars: 2397 + stars: 2432 owner_login: Buuntu owner_html_url: https://github.com/Buuntu - name: FastAPI-template html_url: https://github.com/s3rius/FastAPI-template - stars: 2334 + stars: 2388 owner_login: s3rius owner_html_url: https://github.com/s3rius -- name: nextpy - html_url: https://github.com/dot-agent/nextpy - stars: 2295 - owner_login: dot-agent - owner_html_url: https://github.com/dot-agent - name: sqladmin html_url: https://github.com/aminalaee/sqladmin - stars: 2235 + stars: 2323 owner_login: aminalaee owner_html_url: https://github.com/aminalaee +- name: nextpy + html_url: https://github.com/dot-agent/nextpy + stars: 2314 + owner_login: dot-agent + owner_html_url: https://github.com/dot-agent +- name: mcp-context-forge + html_url: https://github.com/IBM/mcp-context-forge + stars: 2236 + owner_login: IBM + owner_html_url: https://github.com/IBM - name: 30-Days-of-Python html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python - stars: 2181 + stars: 2196 owner_login: codingforentrepreneurs owner_html_url: https://github.com/codingforentrepreneurs +- name: supabase-py + html_url: https://github.com/supabase/supabase-py + stars: 2194 + owner_login: supabase + owner_html_url: https://github.com/supabase - name: langserve html_url: https://github.com/langchain-ai/langserve - stars: 2119 + stars: 2157 owner_login: langchain-ai owner_html_url: https://github.com/langchain-ai - name: fastapi-utils html_url: https://github.com/fastapiutils/fastapi-utils - stars: 2100 + stars: 2155 owner_login: fastapiutils owner_html_url: https://github.com/fastapiutils -- name: supabase-py - html_url: https://github.com/supabase/supabase-py - stars: 2084 - owner_login: supabase - owner_html_url: https://github.com/supabase - name: solara html_url: https://github.com/widgetti/solara - stars: 2056 + stars: 2083 owner_login: widgetti owner_html_url: https://github.com/widgetti - name: mangum html_url: https://github.com/Kludex/mangum - stars: 1923 + stars: 1969 owner_login: Kludex owner_html_url: https://github.com/Kludex +- name: Yuxi-Know + html_url: https://github.com/xerrors/Yuxi-Know + stars: 1849 + owner_login: xerrors + owner_html_url: https://github.com/xerrors - name: python-week-2022 html_url: https://github.com/rochacbruno/python-week-2022 - stars: 1821 + stars: 1817 owner_login: rochacbruno owner_html_url: https://github.com/rochacbruno - name: agentkit html_url: https://github.com/BCG-X-Official/agentkit - stars: 1765 + stars: 1779 owner_login: BCG-X-Official owner_html_url: https://github.com/BCG-X-Official - name: manage-fastapi html_url: https://github.com/ycd/manage-fastapi - stars: 1756 + stars: 1770 owner_login: ycd owner_html_url: https://github.com/ycd - name: ormar html_url: https://github.com/collerek/ormar - stars: 1755 + stars: 1766 owner_login: collerek owner_html_url: https://github.com/collerek -- name: langchain-serve - html_url: https://github.com/jina-ai/langchain-serve - stars: 1631 - owner_login: jina-ai - owner_html_url: https://github.com/jina-ai - name: piccolo html_url: https://github.com/piccolo-orm/piccolo - stars: 1629 + stars: 1673 owner_login: piccolo-orm owner_html_url: https://github.com/piccolo-orm -- name: termpair - html_url: https://github.com/cs01/termpair - stars: 1616 - owner_login: cs01 - owner_html_url: https://github.com/cs01 - name: openapi-python-client html_url: https://github.com/openapi-generators/openapi-python-client - stars: 1603 + stars: 1667 owner_login: openapi-generators owner_html_url: https://github.com/openapi-generators +- name: langchain-serve + html_url: https://github.com/jina-ai/langchain-serve + stars: 1632 + owner_login: jina-ai + owner_html_url: https://github.com/jina-ai - name: fastapi-cache html_url: https://github.com/long2ice/fastapi-cache - stars: 1589 + stars: 1628 owner_login: long2ice owner_html_url: https://github.com/long2ice -- name: coronavirus-tracker-api - html_url: https://github.com/ExpDev07/coronavirus-tracker-api - stars: 1580 - owner_login: ExpDev07 - owner_html_url: https://github.com/ExpDev07 +- name: termpair + html_url: https://github.com/cs01/termpair + stars: 1622 + owner_login: cs01 + owner_html_url: https://github.com/cs01 +- name: vue-fastapi-admin + html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin + stars: 1591 + owner_login: mizhexiaoxiao + owner_html_url: https://github.com/mizhexiaoxiao - name: slowapi html_url: https://github.com/laurentS/slowapi - stars: 1533 + stars: 1580 owner_login: laurentS owner_html_url: https://github.com/laurentS +- name: coronavirus-tracker-api + html_url: https://github.com/ExpDev07/coronavirus-tracker-api + stars: 1578 + owner_login: ExpDev07 + owner_html_url: https://github.com/ExpDev07 - name: fastapi-crudrouter html_url: https://github.com/awtkns/fastapi-crudrouter - stars: 1518 + stars: 1531 owner_login: awtkns owner_html_url: https://github.com/awtkns - name: awesome-fastapi-projects html_url: https://github.com/Kludex/awesome-fastapi-projects - stars: 1461 + stars: 1473 owner_login: Kludex owner_html_url: https://github.com/Kludex -- name: vue-fastapi-admin - html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin - stars: 1409 - owner_login: mizhexiaoxiao - owner_html_url: https://github.com/mizhexiaoxiao -- name: awesome-python-resources - html_url: https://github.com/DjangoEx/awesome-python-resources - stars: 1393 - owner_login: DjangoEx - owner_html_url: https://github.com/DjangoEx +- name: FastAPI-boilerplate + html_url: https://github.com/benavlabs/FastAPI-boilerplate + stars: 1432 + owner_login: benavlabs + owner_html_url: https://github.com/benavlabs - name: fastapi-pagination html_url: https://github.com/uriyyo/fastapi-pagination - stars: 1378 + stars: 1428 owner_login: uriyyo owner_html_url: https://github.com/uriyyo +- name: awesome-python-resources + html_url: https://github.com/DjangoEx/awesome-python-resources + stars: 1413 + owner_login: DjangoEx + owner_html_url: https://github.com/DjangoEx +- name: bracket + html_url: https://github.com/evroon/bracket + stars: 1393 + owner_login: evroon + owner_html_url: https://github.com/evroon - name: fastapi-boilerplate html_url: https://github.com/teamhide/fastapi-boilerplate - stars: 1348 + stars: 1385 owner_login: teamhide owner_html_url: https://github.com/teamhide - name: budgetml html_url: https://github.com/ebhy/budgetml - stars: 1344 + stars: 1345 owner_login: ebhy owner_html_url: https://github.com/ebhy - name: fastapi-amis-admin html_url: https://github.com/amisadmin/fastapi-amis-admin - stars: 1284 + stars: 1327 owner_login: amisadmin owner_html_url: https://github.com/amisadmin -- name: bracket - html_url: https://github.com/evroon/bracket - stars: 1274 - owner_login: evroon - owner_html_url: https://github.com/evroon - name: fastapi-tutorial html_url: https://github.com/liaogx/fastapi-tutorial - stars: 1265 + stars: 1297 owner_login: liaogx owner_html_url: https://github.com/liaogx +- name: fastapi_best_architecture + html_url: https://github.com/fastapi-practices/fastapi_best_architecture + stars: 1242 + owner_login: fastapi-practices + owner_html_url: https://github.com/fastapi-practices - name: fastapi-code-generator html_url: https://github.com/koxudaxi/fastapi-code-generator - stars: 1216 + stars: 1241 owner_login: koxudaxi owner_html_url: https://github.com/koxudaxi -- name: bolt-python - html_url: https://github.com/slackapi/bolt-python - stars: 1190 - owner_login: slackapi - owner_html_url: https://github.com/slackapi - name: fastcrud html_url: https://github.com/benavlabs/fastcrud - stars: 1169 + stars: 1236 owner_login: benavlabs owner_html_url: https://github.com/benavlabs - name: prometheus-fastapi-instrumentator html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator - stars: 1167 + stars: 1217 owner_login: trallnag owner_html_url: https://github.com/trallnag -- name: fastapi_production_template - html_url: https://github.com/zhanymkanov/fastapi_production_template - stars: 1165 - owner_login: zhanymkanov - owner_html_url: https://github.com/zhanymkanov +- name: bolt-python + html_url: https://github.com/slackapi/bolt-python + stars: 1209 + owner_login: slackapi + owner_html_url: https://github.com/slackapi - name: bedrock-chat html_url: https://github.com/aws-samples/bedrock-chat - stars: 1163 + stars: 1199 owner_login: aws-samples owner_html_url: https://github.com/aws-samples +- name: fastapi_production_template + html_url: https://github.com/zhanymkanov/fastapi_production_template + stars: 1182 + owner_login: zhanymkanov + owner_html_url: https://github.com/zhanymkanov - name: langchain-extract html_url: https://github.com/langchain-ai/langchain-extract - stars: 1142 + stars: 1162 owner_login: langchain-ai owner_html_url: https://github.com/langchain-ai -- name: odmantic - html_url: https://github.com/art049/odmantic - stars: 1121 - owner_login: art049 - owner_html_url: https://github.com/art049 -- name: fastapi_best_architecture - html_url: https://github.com/fastapi-practices/fastapi_best_architecture - stars: 1118 - owner_login: fastapi-practices - owner_html_url: https://github.com/fastapi-practices +- name: fastapi-langgraph-agent-production-ready-template + html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template + stars: 1150 + owner_login: wassim249 + owner_html_url: https://github.com/wassim249 - name: fastapi-alembic-sqlmodel-async html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async - stars: 1116 + stars: 1145 owner_login: jonra1993 owner_html_url: https://github.com/jonra1993 -- name: FastAPI-boilerplate - html_url: https://github.com/benavlabs/FastAPI-boilerplate - stars: 1070 - owner_login: benavlabs - owner_html_url: https://github.com/benavlabs +- name: odmantic + html_url: https://github.com/art049/odmantic + stars: 1130 + owner_login: art049 + owner_html_url: https://github.com/art049 - name: restish html_url: https://github.com/rest-sh/restish - stars: 1069 + stars: 1107 owner_login: rest-sh owner_html_url: https://github.com/rest-sh +- name: fastapi-scaff + html_url: https://github.com/atpuxiner/fastapi-scaff + stars: 1052 + owner_login: atpuxiner + owner_html_url: https://github.com/atpuxiner - name: runhouse html_url: https://github.com/run-house/runhouse - stars: 1037 + stars: 1043 owner_login: run-house owner_html_url: https://github.com/run-house +- name: flock + html_url: https://github.com/Onelevenvy/flock + stars: 1010 + owner_login: Onelevenvy + owner_html_url: https://github.com/Onelevenvy - name: autollm html_url: https://github.com/viddexa/autollm - stars: 994 + stars: 995 owner_login: viddexa owner_html_url: https://github.com/viddexa - name: lanarky html_url: https://github.com/ajndkr/lanarky - stars: 992 + stars: 994 owner_login: ajndkr owner_html_url: https://github.com/ajndkr - name: authx html_url: https://github.com/yezz123/authx - stars: 953 + stars: 978 owner_login: yezz123 owner_html_url: https://github.com/yezz123 - name: secure html_url: https://github.com/TypeError/secure - stars: 941 + stars: 942 owner_login: TypeError owner_html_url: https://github.com/TypeError +- name: titiler + html_url: https://github.com/developmentseed/titiler + stars: 940 + owner_login: developmentseed + owner_html_url: https://github.com/developmentseed - name: energy-forecasting html_url: https://github.com/iusztinpaul/energy-forecasting - stars: 928 + stars: 937 owner_login: iusztinpaul owner_html_url: https://github.com/iusztinpaul - name: langcorn html_url: https://github.com/msoedov/langcorn - stars: 927 + stars: 933 owner_login: msoedov owner_html_url: https://github.com/msoedov -- name: titiler - html_url: https://github.com/developmentseed/titiler - stars: 901 - owner_login: developmentseed - owner_html_url: https://github.com/developmentseed -- name: flock - html_url: https://github.com/Onelevenvy/flock - stars: 896 - owner_login: Onelevenvy - owner_html_url: https://github.com/Onelevenvy -- name: fastapi-langgraph-agent-production-ready-template - html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template - stars: 896 - owner_login: wassim249 - owner_html_url: https://github.com/wassim249 -- name: marker-api - html_url: https://github.com/adithya-s-k/marker-api - stars: 875 - owner_login: adithya-s-k - owner_html_url: https://github.com/adithya-s-k -- name: httpdbg - html_url: https://github.com/cle-b/httpdbg - stars: 870 - owner_login: cle-b - owner_html_url: https://github.com/cle-b - name: fastapi-do-zero html_url: https://github.com/dunossauro/fastapi-do-zero - stars: 855 + stars: 892 owner_login: dunossauro owner_html_url: https://github.com/dunossauro -- name: ludic - html_url: https://github.com/getludic/ludic - stars: 849 - owner_login: getludic - owner_html_url: https://github.com/getludic -- name: fastapi-observability - html_url: https://github.com/blueswen/fastapi-observability - stars: 837 - owner_login: blueswen - owner_html_url: https://github.com/blueswen -- name: fastapi-scaf - html_url: https://github.com/atpuxiner/fastapi-scaf - stars: 821 - owner_login: atpuxiner - owner_html_url: https://github.com/atpuxiner -- name: starlette-admin - html_url: https://github.com/jowilf/starlette-admin - stars: 808 - owner_login: jowilf - owner_html_url: https://github.com/jowilf -- name: fastapi-mail - html_url: https://github.com/sabuhish/fastapi-mail - stars: 807 - owner_login: sabuhish - owner_html_url: https://github.com/sabuhish -- name: aktools - html_url: https://github.com/akfamily/aktools - stars: 796 - owner_login: akfamily - owner_html_url: https://github.com/akfamily +- name: marker-api + html_url: https://github.com/adithya-s-k/marker-api + stars: 890 + owner_login: adithya-s-k + owner_html_url: https://github.com/adithya-s-k - name: RuoYi-Vue3-FastAPI html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI - stars: 782 + stars: 884 owner_login: insistence owner_html_url: https://github.com/insistence +- name: aktools + html_url: https://github.com/akfamily/aktools + stars: 880 + owner_login: akfamily + owner_html_url: https://github.com/akfamily +- name: fastapi-observability + html_url: https://github.com/blueswen/fastapi-observability + stars: 880 + owner_login: blueswen + owner_html_url: https://github.com/blueswen +- name: httpdbg + html_url: https://github.com/cle-b/httpdbg + stars: 876 + owner_login: cle-b + owner_html_url: https://github.com/cle-b diff --git a/docs/en/data/translation_reviewers.yml b/docs/en/data/translation_reviewers.yml index 4f3c95b27..efcf81c9d 100644 --- a/docs/en/data/translation_reviewers.yml +++ b/docs/en/data/translation_reviewers.yml @@ -10,12 +10,12 @@ Xewus: url: https://github.com/Xewus sodaMelon: login: sodaMelon - count: 126 + count: 127 avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4 url: https://github.com/sodaMelon ceb10n: login: ceb10n - count: 112 + count: 116 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 url: https://github.com/ceb10n tokusumi: @@ -40,8 +40,8 @@ alv2017: url: https://github.com/alv2017 nazarepiedady: login: nazarepiedady - count: 83 - avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4 + count: 86 + avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=f69ddc4ea8bda3bdfac7aa0e2ea38de282e6ee2d&v=4 url: https://github.com/nazarepiedady AlertRED: login: AlertRED @@ -108,6 +108,11 @@ Rishat-F: count: 42 avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4 url: https://github.com/Rishat-F +nilslindemann: + login: nilslindemann + count: 41 + avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4 + url: https://github.com/nilslindemann Winand: login: Winand count: 40 @@ -123,6 +128,11 @@ JavierSanchezCastro: count: 38 avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4 url: https://github.com/JavierSanchezCastro +alejsdev: + login: alejsdev + count: 37 + avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=638c65283ac9e9e2c3a0f9d1e3370db4b8a2c58d&v=4 + url: https://github.com/alejsdev stlucasgarcia: login: stlucasgarcia count: 36 @@ -133,21 +143,11 @@ SwftAlpc: count: 36 avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4 url: https://github.com/SwftAlpc -alejsdev: - login: alejsdev - count: 36 - avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=638c65283ac9e9e2c3a0f9d1e3370db4b8a2c58d&v=4 - url: https://github.com/alejsdev timothy-jeong: login: timothy-jeong count: 36 avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4 url: https://github.com/timothy-jeong -nilslindemann: - login: nilslindemann - count: 35 - avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4 - url: https://github.com/nilslindemann mezgoodle: login: mezgoodle count: 35 @@ -173,6 +173,11 @@ romashevchenko: count: 32 avatarUrl: https://avatars.githubusercontent.com/u/132477732?v=4 url: https://github.com/romashevchenko +YuriiMotov: + login: YuriiMotov + count: 31 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 + url: https://github.com/YuriiMotov LorhanSohaky: login: LorhanSohaky count: 30 @@ -243,11 +248,6 @@ mycaule: count: 25 avatarUrl: https://avatars.githubusercontent.com/u/6161385?u=e3cec75bd6d938a0d73fae0dc5534d1ab2ed1b0e&v=4 url: https://github.com/mycaule -YuriiMotov: - login: YuriiMotov - count: 24 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4 - url: https://github.com/YuriiMotov Aruelius: login: Aruelius count: 24 @@ -386,7 +386,7 @@ Joao-Pedro-P-Holanda: JaeHyuckSa: login: JaeHyuckSa count: 16 - avatarUrl: https://avatars.githubusercontent.com/u/104830931?u=6e352201714a05154e5d0ccf91b4715a951c622e&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/104830931?u=f3b4a2baea550f428a4c602a30ebee6721c1e3df&v=4 url: https://github.com/JaeHyuckSa Jedore: login: Jedore @@ -548,6 +548,11 @@ KNChiu: count: 11 avatarUrl: https://avatars.githubusercontent.com/u/36751646?v=4 url: https://github.com/KNChiu +maru0123-2004: + login: maru0123-2004 + count: 11 + avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4 + url: https://github.com/maru0123-2004 mariacamilagl: login: mariacamilagl count: 10 @@ -606,13 +611,8 @@ nick-cjyx9: lucasbalieiro: login: lucasbalieiro count: 10 - avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=dad91601ee4f40458d691774ec439aff308344d7&v=4 url: https://github.com/lucasbalieiro -maru0123-2004: - login: maru0123-2004 - count: 10 - avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4 - url: https://github.com/maru0123-2004 Zhongheng-Cheng: login: Zhongheng-Cheng count: 10 @@ -753,11 +753,6 @@ anthonycepeda: count: 7 avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4 url: https://github.com/anthonycepeda -Muaytie666: - login: Muaytie666 - count: 7 - avatarUrl: https://avatars.githubusercontent.com/u/198508825?v=4 - url: https://github.com/Muaytie666 fabioueno: login: fabioueno count: 7 @@ -1028,6 +1023,11 @@ devluisrodrigues: count: 5 avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4 url: https://github.com/11kkw +soroushgh1: + login: soroushgh1 + count: 5 + avatarUrl: https://avatars.githubusercontent.com/u/178516095?u=5e26f6a5f66cdb32d7b56e6ab362bf18ba7858b9&v=4 + url: https://github.com/soroushgh1 lpdswing: login: lpdswing count: 4 @@ -1163,6 +1163,11 @@ cookie-byte217: count: 4 avatarUrl: https://avatars.githubusercontent.com/u/57880178?v=4 url: https://github.com/cookie-byte217 +AbolfazlKameli: + login: AbolfazlKameli + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/120686133?u=ad99cb0adb4a2091f552f9d7281ced334150f9c2&v=4 + url: https://github.com/AbolfazlKameli tyronedamasceno: login: tyronedamasceno count: 3 @@ -1251,7 +1256,7 @@ rafsaf: frnsimoes: login: frnsimoes count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=a405e8f10654251e239a4a1d9dd5bda59216727d&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=fd8d408946633acc4bea057c207e6c0833871527&v=4 url: https://github.com/frnsimoes lieryan: login: lieryan @@ -1403,16 +1408,21 @@ tienduong-21: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/80129618?v=4 url: https://github.com/tienduong-21 -soroushgh1: - login: soroushgh1 - count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/178516095?u=5e26f6a5f66cdb32d7b56e6ab362bf18ba7858b9&v=4 - url: https://github.com/soroushgh1 zbellos: login: zbellos count: 3 avatarUrl: https://avatars.githubusercontent.com/u/204500646?v=4 url: https://github.com/zbellos +Mohammad222PR: + login: Mohammad222PR + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/116789737?u=25810a5fe049d2f1618e2e7417cea011cc353ce4&v=4 + url: https://github.com/Mohammad222PR +EdmilsonRodrigues: + login: EdmilsonRodrigues + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/62777025?u=217d6f3cd6cc750bb8818a3af7726c8d74eb7c2d&v=4 + url: https://github.com/EdmilsonRodrigues blaisep: login: blaisep count: 2 @@ -1508,11 +1518,11 @@ its0x08: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/15280042?u=d7c2058f29d4e8fbdae09b194e04c5e410350211&v=4 url: https://github.com/its0x08 -lindsayzhou: - login: lindsayzhou +linsein: + login: linsein count: 2 avatarUrl: https://avatars.githubusercontent.com/u/23748021?u=4db169ce262b69aa7292f82b785436544f69fb88&v=4 - url: https://github.com/lindsayzhou + url: https://github.com/linsein 0xflotus: login: 0xflotus count: 2 @@ -1668,6 +1678,11 @@ siavashyj: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4 url: https://github.com/siavashyj +Ramin-RX7: + login: Ramin-RX7 + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/52785580?u=b3678f779ad0ee9cd9dca9e50ccb804b5eb990a5&v=4 + url: https://github.com/Ramin-RX7 DevSpace88: login: DevSpace88 count: 2 @@ -1763,6 +1778,11 @@ logan2d5: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/146642263?u=dbd6621f8b0330d6919f6a7131277b92e26fbe87&v=4 url: https://github.com/logan2d5 +guspan-tanadi: + login: guspan-tanadi + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/36249910?v=4 + url: https://github.com/guspan-tanadi tiaggo16: login: tiaggo16 count: 2 @@ -1793,6 +1813,11 @@ ivintoiu: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/1853336?u=5e3d0977f44661fb9712fa297cc8f7608ea6ce48&v=4 url: https://github.com/ivintoiu +TechnoService2: + login: TechnoService2 + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/142113388?v=4 + url: https://github.com/TechnoService2 EgorOnishchuk: login: EgorOnishchuk count: 2 @@ -1818,3 +1843,13 @@ NavesSapnis: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/79222417?u=b5b10291b8e9130ca84fd20f0a641e04ed94b6b1&v=4 url: https://github.com/NavesSapnis +eqsdxr: + login: eqsdxr + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=58fddf77ed76966eaa8c73eea9bea4bb0c53b673&v=4 + url: https://github.com/eqsdxr +syedasamina56: + login: syedasamina56 + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/183273097?v=4 + url: https://github.com/syedasamina56 diff --git a/docs/en/data/translators.yml b/docs/en/data/translators.yml index 3cd6120d0..b0f570e5c 100644 --- a/docs/en/data/translators.yml +++ b/docs/en/data/translators.yml @@ -121,7 +121,7 @@ batlopes: lucasbalieiro: login: lucasbalieiro count: 6 - avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=dad91601ee4f40458d691774ec439aff308344d7&v=4 url: https://github.com/lucasbalieiro Alexandrhub: login: Alexandrhub @@ -208,6 +208,16 @@ k94-ishi: count: 4 avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4 url: https://github.com/k94-ishi +Mohammad222PR: + login: Mohammad222PR + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/116789737?u=25810a5fe049d2f1618e2e7417cea011cc353ce4&v=4 + url: https://github.com/Mohammad222PR +NavesSapnis: + login: NavesSapnis + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/79222417?u=b5b10291b8e9130ca84fd20f0a641e04ed94b6b1&v=4 + url: https://github.com/NavesSapnis jfunez: login: jfunez count: 3 @@ -446,7 +456,7 @@ ArtemKhymenko: hasnatsajid: login: hasnatsajid count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/86589885?u=49958789e6385be624f2c6a55a860c599eb05e2c&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/86589885?u=6668823c3b029bfecf10a8918ed3af1aafb8b15e&v=4 url: https://github.com/hasnatsajid alperiox: login: alperiox @@ -528,8 +538,8 @@ EgorOnishchuk: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/120256301?v=4 url: https://github.com/EgorOnishchuk -NavesSapnis: - login: NavesSapnis +EdmilsonRodrigues: + login: EdmilsonRodrigues count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/79222417?u=b5b10291b8e9130ca84fd20f0a641e04ed94b6b1&v=4 - url: https://github.com/NavesSapnis + avatarUrl: https://avatars.githubusercontent.com/u/62777025?u=217d6f3cd6cc750bb8818a3af7726c8d74eb7c2d&v=4 + url: https://github.com/EdmilsonRodrigues diff --git a/docs/en/docs/_llm-test.md b/docs/en/docs/_llm-test.md new file mode 100644 index 000000000..e72450b91 --- /dev/null +++ b/docs/en/docs/_llm-test.md @@ -0,0 +1,503 @@ +# LLM test file { #llm-test-file } + +This document tests if the LLM, which translates the documentation, understands the `general_prompt` in `scripts/translate.py` and the language specific prompt in `docs/{language code}/llm-prompt.md`. The language specific prompt is appended to `general_prompt`. + +Tests added here will be seen by all designers of language specific prompts. + +Use as follows: + +* Have a language specific prompt – `docs/{language code}/llm-prompt.md`. +* Do a fresh translation of this document into your desired target language (see e.g. the `translate-page` command of the `translate.py`). This will create the translation under `docs/{language code}/docs/_llm-test.md`. +* Check if things are okay in the translation. +* If necessary, improve your language specific prompt, the general prompt, or the English document. +* Then manually fix the remaining issues in the translation, so that it is a good translation. +* Retranslate, having the good translation in place. The ideal result would be that the LLM makes no changes anymore to the translation. That means that the general prompt and your language specific prompt are as good as they can be (It will sometimes make a few seemingly random changes, the reason is that LLMs are not deterministic algorithms). + +The tests: + +## Code snippets { #code-snippets} + +//// tab | Test + +This is a code snippet: `foo`. And this is another code snippet: `bar`. And another one: `baz quux`. + +//// + +//// tab | Info + +Content of code snippets should be left as is. + +See section `### Content of code snippets` in the general prompt in `scripts/translate.py`. + +//// + +## Quotes { #quotes } + +//// tab | Test + +Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'". + +/// note + +The LLM will probably translate this wrong. Interesting is only if it keeps the fixed translation when retranslating. + +/// + +//// + +//// tab | Info + +The prompt designer may choose if they want to convert neutral quotes to typographic quotes. It is okay to leave them as is. + +See for example section `### Quotes` in `docs/de/llm-prompt.md`. + +//// + +## Quotes in code snippets { #quotes-in-code-snippets} + +//// tab | Test + +`pip install "foo[bar]"` + +Examples for string literals in code snippets: `"this"`, `'that'`. + +A difficult example for string literals in code snippets: `f"I like {'oranges' if orange else "apples"}"` + +Hardcore: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"` + +//// + +//// tab | Info + +... However, quotes inside code snippets must stay as is. + +//// + +## code blocks { #code-blocks } + +//// tab | Test + +A Bash code example... + +```bash +# Print a greeting to the universe +echo "Hello universe" +``` + +...and a console code example... + +```console +$ fastapi run main.py + FastAPI Starting server + Searching for package file structure +``` + +...and another console code example... + +```console +// Create a directory "Code" +$ mkdir code +// Switch into that directory +$ cd code +``` + +...and a Python code example... + +```Python +wont_work() # This won't work 😱 +works(foo="bar") # This works 🎉 +``` + +...and that's it. + +//// + +//// tab | Info + +Code in code blocks should not be modified, with the exception of comments. + +See section `### Content of code blocks` in the general prompt in `scripts/translate.py`. + +//// + +## Tabs and colored boxes { #tabs-and-colored-boxes } + +//// tab | Test + +/// info +Some text +/// + +/// note +Some text +/// + +/// note | Technical details +Some text +/// + +/// check +Some text +/// + +/// tip +Some text +/// + +/// warning +Some text +/// + +/// danger +Some text +/// + +//// + +//// tab | Info + +Tabs and `Info`/`Note`/`Warning`/etc. blocks should have the translation of their title added after a vertical bar (`|`). + +See sections `### Special blocks` and `### Tab blocks` in the general prompt in `scripts/translate.py`. + +//// + +## Web- and internal links { #web-and-internal-links } + +//// tab | Test + +The link text should get translated, the link address should remain unchaged: + +* [Link to heading above](#code-snippets) +* [Internal link](index.md#installation){.internal-link target=_blank} +* External link +* Link to a style +* Link to a script +* Link to an image + +The link text should get translated, the link address should point to the translation: + +* FastAPI link + +//// + +//// tab | Info + +Links should be translated, but their address shall remain unchanged. An exception are absolute links to pages of the FastAPI documentation. In that case it should link to the translation. + +See section `### Links` in the general prompt in `scripts/translate.py`. + +//// + +## HTML "abbr" elements { #html-abbr-elements } + +//// tab | Test + +Here some things wrapped in HTML "abbr" elements (Some are invented): + +### The abbr gives a full phrase { #the-abbr-gives-a-full-phrase } + +* GTD +* lt +* XWT +* PSGI + +### The abbr gives an explanation { #the-abbr-gives-an-explanation } + +* cluster +* Deep Learning + +### The abbr gives a full phrase and an explanation { #the-abbr-gives-a-full-phrase-and-an-explanation } + +* MDN +* I/O. + +//// + +//// tab | Info + +"title" attributes of "abbr" elements are translated following some specific instructions. + +Translations can add their own "abbr" elements which the LLM should not remove. E.g. to explain English words. + +See section `### HTML abbr elements` in the general prompt in `scripts/translate.py`. + +//// + +## Headings { #headings } + +//// tab | Test + +### Develop a webapp - a tutorial { #develop-a-webapp-a-tutorial } + +Hello. + +### Type hints and -annotations { #type-hints-and-annotations } + +Hello again. + +### Super- and subclasses { #super-and-subclasses } + +Hello again. + +//// + +//// tab | Info + +The only hard rule for headings is that the LLM leaves the hash part inside curly brackets unchanged, which ensures that links do not break. + +See section `### Headings` in the general prompt in `scripts/translate.py`. + +For some language specific instructions, see e.g. section `### Headings` in `docs/de/llm-prompt.md`. + +//// + +## Terms used in the docs { #terms-used-in-the-docs } + +//// tab | Test + +* you +* your + +* e.g. +* etc. + +* `foo` as an `int` +* `bar` as a `str` +* `baz` as a `list` + +* the Tutorial - User guide +* the Advanced User Guide +* the SQLModel docs +* the API docs +* the automatic docs + +* Data Science +* Deep Learning +* Machine Learning +* Dependency Injection +* HTTP Basic authentication +* HTTP Digest +* ISO format +* the JSON Schema standard +* the JSON schema +* the schema definition +* Password Flow +* Mobile + +* deprecated +* designed +* invalid +* on the fly +* standard +* default +* case-sensitive +* case-insensitive + +* to serve the application +* to serve the page + +* the app +* the application + +* the request +* the response +* the error response + +* the path operation +* the path operation decorator +* the path operation function + +* the body +* the request body +* the response body +* the JSON body +* the form body +* the file body +* the function body + +* the parameter +* the body parameter +* the path parameter +* the query parameter +* the cookie parameter +* the header parameter +* the form parameter +* the function parameter + +* the event +* the startup event +* the startup of the server +* the shutdown event +* the lifespan event + +* the handler +* the event handler +* the exception handler +* to handle + +* the model +* the Pydantic model +* the data model +* the database model +* the form model +* the model object + +* the class +* the base class +* the parent class +* the subclass +* the child class +* the sibling class +* the class method + +* the header +* the headers +* the authorization header +* the `Authorization` header +* the forwarded header + +* the dependency injection system +* the dependency +* the dependable +* the dependant + +* I/O bound +* CPU bound +* concurrency +* parallelism +* multiprocessing + +* the env var +* the environment variable +* the `PATH` +* the `PATH` variable + +* the authentication +* the authentication provider +* the authorization +* the authorization form +* the authorization provider +* the user authenticates +* the system authenticates the user + +* the CLI +* the command line interface + +* the server +* the client + +* the cloud provider +* the cloud service + +* the development +* the development stages + +* the dict +* the dictionary +* the enumeration +* the enum +* the enum member + +* the encoder +* the decoder +* to encode +* to decode + +* the exception +* to raise + +* the expression +* the statement + +* the frontend +* the backend + +* the GitHub discussion +* the GitHub issue + +* the performance +* the performance optimization + +* the return type +* the return value + +* the security +* the security scheme + +* the task +* the background task +* the task function + +* the template +* the template engine + +* the type annotation +* the type hint + +* the server worker +* the Uvicorn worker +* the Gunicorn Worker +* the worker process +* the worker class +* the workload + +* the deployment +* to deploy + +* the SDK +* the software development kit + +* the `APIRouter` +* the `requirements.txt` +* the Bearer Token +* the breaking change +* the bug +* the button +* the callable +* the code +* the commit +* the context manager +* the coroutine +* the database session +* the disk +* the domain +* the engine +* the fake X +* the HTTP GET method +* the item +* the library +* the lifespan +* the lock +* the middleware +* the mobile application +* the module +* the mounting +* the network +* the origin +* the override +* the payload +* the processor +* the property +* the proxy +* the pull request +* the query +* the RAM +* the remote machine +* the status code +* the string +* the tag +* the web framework +* the wildcard +* to return +* to validate + +//// + +//// tab | Info + +This is a not complete and not normative list of (mostly) technical terms seen in the docs. It may be helpful for the prompt designer to figure out for which terms the LLM needs a helping hand. For example when it keeps reverting a good translation to a suboptimal translation. Or when it has problems conjugating/declinating a term in your language. + +See e.g. section `### List of English terms and their preferred German translations` in `docs/de/llm-prompt.md`. + +//// diff --git a/docs/en/docs/about/index.md b/docs/en/docs/about/index.md index 27b78696b..d178dfec7 100644 --- a/docs/en/docs/about/index.md +++ b/docs/en/docs/about/index.md @@ -1,3 +1,3 @@ -# About +# About { #about } About FastAPI, its design, inspiration and more. 🤓 diff --git a/docs/en/docs/advanced/additional-responses.md b/docs/en/docs/advanced/additional-responses.md index 03d48c2a7..799532c5b 100644 --- a/docs/en/docs/advanced/additional-responses.md +++ b/docs/en/docs/advanced/additional-responses.md @@ -1,4 +1,4 @@ -# Additional Responses in OpenAPI +# Additional Responses in OpenAPI { #additional-responses-in-openapi } /// warning @@ -14,7 +14,7 @@ Those additional responses will be included in the OpenAPI schema, so they will But for those additional responses you have to make sure you return a `Response` like `JSONResponse` directly, with your status code and content. -## Additional Response with `model` +## Additional Response with `model` { #additional-response-with-model } You can pass to your *path operation decorators* a parameter `responses`. @@ -169,7 +169,7 @@ The schemas are referenced to another place inside the OpenAPI schema: } ``` -## Additional media types for the main response +## Additional media types for the main response { #additional-media-types-for-the-main-response } You can use this same `responses` parameter to add different media types for the same main response. @@ -191,7 +191,7 @@ But if you have specified a custom response class with `None` as its media type, /// -## Combining information +## Combining information { #combining-information } You can also combine response information from multiple places, including the `response_model`, `status_code`, and `responses` parameters. @@ -209,7 +209,7 @@ It will all be combined and included in your OpenAPI, and shown in the API docs: -## Combine predefined responses and custom ones +## Combine predefined responses and custom ones { #combine-predefined-responses-and-custom-ones } You might want to have some predefined responses that apply to many *path operations*, but you want to combine them with custom responses needed by each *path operation*. @@ -239,7 +239,7 @@ For example: {* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *} -## More information about OpenAPI responses +## More information about OpenAPI responses { #more-information-about-openapi-responses } To see what exactly you can include in the responses, you can check these sections in the OpenAPI specification: diff --git a/docs/en/docs/advanced/additional-status-codes.md b/docs/en/docs/advanced/additional-status-codes.md index 077a00488..23bcd13c3 100644 --- a/docs/en/docs/advanced/additional-status-codes.md +++ b/docs/en/docs/advanced/additional-status-codes.md @@ -1,10 +1,10 @@ -# Additional Status Codes +# Additional Status Codes { #additional-status-codes } By default, **FastAPI** will return the responses using a `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`. It will use the default status code or the one you set in your *path operation*. -## Additional status codes +## Additional status codes { #additional-status-codes_1 } If you want to return additional status codes apart from the main one, you can do that by returning a `Response` directly, like a `JSONResponse`, and set the additional status code directly. @@ -34,7 +34,7 @@ You could also use `from starlette.responses import JSONResponse`. /// -## OpenAPI and API docs +## OpenAPI and API docs { #openapi-and-api-docs } If you return additional status codes and responses directly, they won't be included in the OpenAPI schema (the API docs), because FastAPI doesn't have a way to know beforehand what you are going to return. diff --git a/docs/en/docs/advanced/advanced-dependencies.md b/docs/en/docs/advanced/advanced-dependencies.md index f933fd264..e0404b389 100644 --- a/docs/en/docs/advanced/advanced-dependencies.md +++ b/docs/en/docs/advanced/advanced-dependencies.md @@ -1,6 +1,6 @@ -# Advanced Dependencies +# Advanced Dependencies { #advanced-dependencies } -## Parameterized dependencies +## Parameterized dependencies { #parameterized-dependencies } All the dependencies we have seen are a fixed function or class. @@ -10,7 +10,7 @@ Let's imagine that we want to have a dependency that checks if the query paramet But we want to be able to parameterize that fixed content. -## A "callable" instance +## A "callable" instance { #a-callable-instance } In Python there's a way to make an instance of a class a "callable". @@ -22,7 +22,7 @@ To do that, we declare a method `__call__`: In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later. -## Parameterize the instance +## Parameterize the instance { #parameterize-the-instance } And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency: @@ -30,7 +30,7 @@ And now, we can use `__init__` to declare the parameters of the instance that we In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code. -## Create an instance +## Create an instance { #create-an-instance } We could create an instance of this class with: @@ -38,7 +38,7 @@ We could create an instance of this class with: And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`. -## Use the instance as a dependency +## Use the instance as a dependency { #use-the-instance-as-a-dependency } Then, we could use this `checker` in a `Depends(checker)`, instead of `Depends(FixedContentQueryChecker)`, because the dependency is the instance, `checker`, not the class itself. @@ -63,3 +63,91 @@ In the chapters about security, there are utility functions that are implemented If you understood all this, you already know how those utility tools for security work underneath. /// + +## Dependencies with `yield`, `HTTPException`, `except` and Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks } + +/// warning + +You most probably don't need these technical details. + +These details are useful mainly if you had a FastAPI application older than 0.118.0 and you are facing issues with dependencies with `yield`. + +/// + +Dependencies with `yield` have evolved over time to account for the different use cases and to fix some issues, here's a summary of what has changed. + +### Dependencies with `yield` and `StreamingResponse`, Technical Details { #dependencies-with-yield-and-streamingresponse-technical-details } + +Before FastAPI 0.118.0, if you used a dependency with `yield`, it would run the exit code after the *path operation function* returned but right before sending the response. + +The intention was to avoid holding resources for longer than necessary, waiting for the response to travel through the network. + +This change also meant that if you returned a `StreamingResponse`, the exit code of the dependency with `yield` would have been already run. + +For example, if you had a database session in a dependency with `yield`, the `StreamingResponse` would not be able to use that session while streaming data because the session would have already been closed in the exit code after `yield`. + +This behavior was reverted in 0.118.0, to make the exit code after `yield` be executed after the response is sent. + +/// info + +As you will see below, this is very similar to the behavior before version 0.106.0, but with several improvements and bug fixes for corner cases. + +/// + +#### Use Cases with Early Exit Code { #use-cases-with-early-exit-code } + +There are some use cases with specific conditions that could benefit from the old behavior of running the exit code of dependencies with `yield` before sending the response. + +For example, imagine you have code that uses a database session in a dependency with `yield` only to verify a user, but the database session is never used again in the *path operation function*, only in the dependency, **and** the response takes a long time to be sent, like a `StreamingResponse` that sends data slowly, but for some reason doesn't use the database. + +In this case, the database session would be held until the response is finished being sent, but if you don't use it, then it wouldn't be necessary to hold it. + +Here's how it could look like: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py *} + +The exit code, the automatic closing of the `Session` in: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *} + +...would be run after the the response finishes sending the slow data: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *} + +But as `generate_stream()` doesn't use the database session, it is not really necessary to keep the session open while sending the response. + +If you have this specific use case using SQLModel (or SQLAlchemy), you could explicitly close the session after you don't need it anymore: + +{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *} + +That way the session would release the database connection, so other requests could use it. + +If you have a different use case that needs to exit early from a dependency with `yield`, please create a GitHub Discussion Question with your specific use case and why you would benefit from having early closing for dependencies with `yield`. + +If there are compelling use cases for early closing in dependencies with `yield`, I would consider adding a new way to opt in to early closing. + +### Dependencies with `yield` and `except`, Technical Details { #dependencies-with-yield-and-except-technical-details } + +Before FastAPI 0.110.0, if you used a dependency with `yield`, and then you captured an exception with `except` in that dependency, and you didn't raise the exception again, the exception would be automatically raised/forwarded to any exception handlers or the internal server error handler. + +This was changed in version 0.110.0 to fix unhandled memory consumption from forwarded exceptions without a handler (internal server errors), and to make it consistent with the behavior of regular Python code. + +### Background Tasks and Dependencies with `yield`, Technical Details { #background-tasks-and-dependencies-with-yield-technical-details } + +Before FastAPI 0.106.0, raising exceptions after `yield` was not possible, the exit code in dependencies with `yield` was executed *after* the response was sent, so [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} would have already run. + +This was designed this way mainly to allow using the same objects "yielded" by dependencies inside of background tasks, because the exit code would be executed after the background tasks were finished. + +This was changed in FastAPI 0.106.0 with the intention to not hold resources while waiting for the response to travel through the network. + +/// tip + +Additionally, a background task is normally an independent set of logic that should be handled separately, with its own resources (e.g. its own database connection). + +So, this way you will probably have cleaner code. + +/// + +If you used to rely on this behavior, now you should create the resources for background tasks inside the background task itself, and use internally only data that doesn't depend on the resources of dependencies with `yield`. + +For example, instead of using the same database session, you would create a new database session inside of the background task, and you would obtain the objects from the database using this new session. And then instead of passing the object from the database as a parameter to the background task function, you would pass the ID of that object and then obtain the object again inside the background task function. diff --git a/docs/en/docs/advanced/async-tests.md b/docs/en/docs/advanced/async-tests.md index 8d6929222..e920e22c3 100644 --- a/docs/en/docs/advanced/async-tests.md +++ b/docs/en/docs/advanced/async-tests.md @@ -1,4 +1,4 @@ -# Async Tests +# Async Tests { #async-tests } You have already seen how to test your **FastAPI** applications using the provided `TestClient`. Up to now, you have only seen how to write synchronous tests, without using `async` functions. @@ -6,11 +6,11 @@ Being able to use asynchronous functions in your tests could be useful, for exam Let's look at how we can make that work. -## pytest.mark.anyio +## pytest.mark.anyio { #pytest-mark-anyio } If we want to call asynchronous functions in our tests, our test functions have to be asynchronous. AnyIO provides a neat plugin for this, that allows us to specify that some test functions are to be called asynchronously. -## HTTPX +## HTTPX { #httpx } Even if your **FastAPI** application uses normal `def` functions instead of `async def`, it is still an `async` application underneath. @@ -18,7 +18,7 @@ The `TestClient` does some magic inside to call the asynchronous FastAPI applica The `TestClient` is based on HTTPX, and luckily, we can use it directly to test the API. -## Example +## Example { #example } For a simple example, let's consider a file structure similar to the one described in [Bigger Applications](../tutorial/bigger-applications.md){.internal-link target=_blank} and [Testing](../tutorial/testing.md){.internal-link target=_blank}: @@ -38,7 +38,7 @@ The file `test_main.py` would have the tests for `main.py`, it could look like t {* ../../docs_src/async_tests/test_main.py *} -## Run it +## Run it { #run-it } You can run your tests as usual via: @@ -52,7 +52,7 @@ $ pytest
-## In Detail +## In Detail { #in-detail } The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously: @@ -88,12 +88,12 @@ If your application relies on lifespan events, the `AsyncClient` won't trigger t /// -## Other Asynchronous Function Calls +## Other Asynchronous Function Calls { #other-asynchronous-function-calls } As the testing function is now asynchronous, you can now also call (and `await`) other `async` functions apart from sending requests to your FastAPI application in your tests, exactly as you would call them anywhere else in your code. /// tip -If you encounter a `RuntimeError: Task attached to a different loop` when integrating asynchronous function calls in your tests (e.g. when using MongoDB's MotorClient), remember to instantiate objects that need an event loop only within async functions, e.g. an `'@app.on_event("startup")` callback. +If you encounter a `RuntimeError: Task attached to a different loop` when integrating asynchronous function calls in your tests (e.g. when using MongoDB's MotorClient), remember to instantiate objects that need an event loop only within async functions, e.g. an `@app.on_event("startup")` callback. /// diff --git a/docs/en/docs/advanced/behind-a-proxy.md b/docs/en/docs/advanced/behind-a-proxy.md index 1f0d0fd9f..4d19d29e0 100644 --- a/docs/en/docs/advanced/behind-a-proxy.md +++ b/docs/en/docs/advanced/behind-a-proxy.md @@ -1,6 +1,105 @@ -# Behind a Proxy +# Behind a Proxy { #behind-a-proxy } -In some situations, you might need to use a **proxy** server like Traefik or Nginx with a configuration that adds an extra path prefix that is not seen by your application. +In many situations, you would use a **proxy** like Traefik or Nginx in front of your FastAPI app. + +These proxies could handle HTTPS certificates and other things. + +## Proxy Forwarded Headers { #proxy-forwarded-headers } + +A **proxy** in front of your application would normally set some headers on the fly before sending the requests to your **server** to let the server know that the request was **forwarded** by the proxy, letting it know the original (public) URL, including the domain, that it is using HTTPS, etc. + +The **server** program (for example **Uvicorn** via **FastAPI CLI**) is capable of interpreting these headers, and then passing that information to your application. + +But for security, as the server doesn't know it is behind a trusted proxy, it won't interpret those headers. + +/// note | Technical Details + +The proxy headers are: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +### Enable Proxy Forwarded Headers { #enable-proxy-forwarded-headers } + +You can start FastAPI CLI with the *CLI Option* `--forwarded-allow-ips` and pass the IP addresses that should be trusted to read those forwarded headers. + +If you set it to `--forwarded-allow-ips="*"` it would trust all the incoming IPs. + +If your **server** is behind a trusted **proxy** and only the proxy talks to it, this would make it accept whatever is the IP of that **proxy**. + +
+ +```console +$ fastapi run --forwarded-allow-ips="*" + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +### Redirects with HTTPS { #redirects-with-https } + +For example, let's say you define a *path operation* `/items/`: + +{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *} + +If the client tries to go to `/items`, by default, it would be redirected to `/items/`. + +But before setting the *CLI Option* `--forwarded-allow-ips` it could redirect to `http://localhost:8000/items/`. + +But maybe your application is hosted at `https://mysuperapp.com`, and the redirection should be to `https://mysuperapp.com/items/`. + +By setting `--proxy-headers` now FastAPI would be able to redirect to the right location. 😎 + +``` +https://mysuperapp.com/items/ +``` + +/// tip + +If you want to learn more about HTTPS, check the guide [About HTTPS](../deployment/https.md){.internal-link target=_blank}. + +/// + +### How Proxy Forwarded Headers Work + +Here's a visual representation of how the **proxy** adds forwarded headers between the client and the **application server**: + +```mermaid +sequenceDiagram + participant Client + participant Proxy as Proxy/Load Balancer + participant Server as FastAPI Server + + Client->>Proxy: HTTPS Request
Host: mysuperapp.com
Path: /items + + Note over Proxy: Proxy adds forwarded headers + + Proxy->>Server: HTTP Request
X-Forwarded-For: [client IP]
X-Forwarded-Proto: https
X-Forwarded-Host: mysuperapp.com
Path: /items + + Note over Server: Server interprets headers
(if --forwarded-allow-ips is set) + + Server->>Proxy: HTTP Response
with correct HTTPS URLs + + Proxy->>Client: HTTPS Response +``` + +The **proxy** intercepts the original client request and adds the special *forwarded* headers (`X-Forwarded-*`) before passing the request to the **application server**. + +These headers preserve information about the original request that would otherwise be lost: + +* **X-Forwarded-For**: The original client's IP address +* **X-Forwarded-Proto**: The original protocol (`https`) +* **X-Forwarded-Host**: The original host (`mysuperapp.com`) + +When **FastAPI CLI** is configured with `--forwarded-allow-ips`, it trusts these headers and uses them, for example to generate the correct URLs in redirects. + +## Proxy with a stripped path prefix { #proxy-with-a-stripped-path-prefix } + +You could have a proxy that adds a path prefix to your application. In these cases you can use `root_path` to configure your application. @@ -10,8 +109,6 @@ The `root_path` is used to handle these specific cases. And it's also used internally when mounting sub-applications. -## Proxy with a stripped path prefix - Having a proxy with a stripped path prefix, in this case, means that you could declare a path at `/app` in your code, but then, you add a layer on top (the proxy) that would put your **FastAPI** application under a path like `/api/v1`. In this case, the original path `/app` would actually be served at `/api/v1/app`. @@ -66,14 +163,14 @@ The docs UI would also need the OpenAPI schema to declare that this API `server` In this example, the "Proxy" could be something like **Traefik**. And the server would be something like FastAPI CLI with **Uvicorn**, running your FastAPI application. -### Providing the `root_path` +### Providing the `root_path` { #providing-the-root-path } To achieve this, you can use the command line option `--root-path` like:
```console -$ fastapi run main.py --root-path /api/v1 +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -90,7 +187,7 @@ And the `--root-path` command line option provides that `root_path`. /// -### Checking the current `root_path` +### Checking the current `root_path` { #checking-the-current-root-path } You can get the current `root_path` used by your application for each request, it is part of the `scope` dictionary (that's part of the ASGI spec). @@ -103,7 +200,7 @@ Then, if you start Uvicorn with:
```console -$ fastapi run main.py --root-path /api/v1 +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -119,7 +216,7 @@ The response would be something like: } ``` -### Setting the `root_path` in the FastAPI app +### Setting the `root_path` in the FastAPI app { #setting-the-root-path-in-the-fastapi-app } Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app: @@ -127,7 +224,7 @@ Alternatively, if you don't have a way to provide a command line option like `-- Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn. -### About `root_path` +### About `root_path` { #about-root-path } Keep in mind that the server (Uvicorn) won't use that `root_path` for anything else than passing it to the app. @@ -144,7 +241,7 @@ So, it won't expect to be accessed at `http://127.0.0.1:8000/api/v1/app`. Uvicorn will expect the proxy to access Uvicorn at `http://127.0.0.1:8000/app`, and then it would be the proxy's responsibility to add the extra `/api/v1` prefix on top. -## About proxies with a stripped path prefix +## About proxies with a stripped path prefix { #about-proxies-with-a-stripped-path-prefix } Keep in mind that a proxy with stripped path prefix is only one of the ways to configure it. @@ -152,7 +249,7 @@ Probably in many cases the default will be that the proxy doesn't have a strippe In a case like that (without a stripped path prefix), the proxy would listen on something like `https://myawesomeapp.com`, and then if the browser goes to `https://myawesomeapp.com/api/v1/app` and your server (e.g. Uvicorn) listens on `http://127.0.0.1:8000` the proxy (without a stripped path prefix) would access Uvicorn at the same path: `http://127.0.0.1:8000/api/v1/app`. -## Testing locally with Traefik +## Testing locally with Traefik { #testing-locally-with-traefik } You can easily run the experiment locally with a stripped path prefix using Traefik. @@ -224,14 +321,14 @@ And now start your app, using the `--root-path` option:
```console -$ fastapi run main.py --root-path /api/v1 +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ```
-### Check the responses +### Check the responses { #check-the-responses } Now, if you go to the URL with the port for Uvicorn: http://127.0.0.1:8000/app, you will see the normal response: @@ -267,7 +364,7 @@ And the version without the path prefix (`http://127.0.0.1:8000/app`), provided That demonstrates how the Proxy (Traefik) uses the path prefix and how the server (Uvicorn) uses the `root_path` from the option `--root-path`. -### Check the docs UI +### Check the docs UI { #check-the-docs-ui } But here's the fun part. ✨ @@ -287,7 +384,7 @@ Right as we wanted it. âœ”ī¸ This is because FastAPI uses this `root_path` to create the default `server` in OpenAPI with the URL provided by `root_path`. -## Additional servers +## Additional servers { #additional-servers } /// warning @@ -346,7 +443,7 @@ The docs UI will interact with the server that you select. /// -### Disable automatic server from `root_path` +### Disable automatic server from `root_path` { #disable-automatic-server-from-root-path } If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`: @@ -354,7 +451,7 @@ If you don't want **FastAPI** to include an automatic server using the `root_pat and then it won't include it in the OpenAPI schema. -## Mounting a sub-application +## Mounting a sub-application { #mounting-a-sub-application } If you need to mount a sub-application (as described in [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}) while also using a proxy with `root_path`, you can do it normally, as you would expect. diff --git a/docs/en/docs/advanced/custom-response.md b/docs/en/docs/advanced/custom-response.md index 8268dd81a..0f3d8b701 100644 --- a/docs/en/docs/advanced/custom-response.md +++ b/docs/en/docs/advanced/custom-response.md @@ -1,4 +1,4 @@ -# Custom Response - HTML, Stream, File, others +# Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } By default, **FastAPI** will return the responses using `JSONResponse`. @@ -18,7 +18,7 @@ If you use a response class with no media type, FastAPI will expect your respons /// -## Use `ORJSONResponse` +## Use `ORJSONResponse` { #use-orjsonresponse } For example, if you are squeezing performance, you can install and use `orjson` and set the response to be `ORJSONResponse`. @@ -48,7 +48,7 @@ The `ORJSONResponse` is only available in FastAPI, not in Starlette. /// -## HTML Response +## HTML Response { #html-response } To return a response with HTML directly from **FastAPI**, use `HTMLResponse`. @@ -67,7 +67,7 @@ And it will be documented as such in OpenAPI. /// -### Return a `Response` +### Return a `Response` { #return-a-response } As seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}, you can also override the response directly in your *path operation*, by returning it. @@ -87,13 +87,13 @@ Of course, the actual `Content-Type` header, status code, etc, will come from th /// -### Document in OpenAPI and override `Response` +### Document in OpenAPI and override `Response` { #document-in-openapi-and-override-response } If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use the `response_class` parameter AND return a `Response` object. The `response_class` will then be used only to document the OpenAPI *path operation*, but your `Response` will be used as is. -#### Return an `HTMLResponse` directly +#### Return an `HTMLResponse` directly { #return-an-htmlresponse-directly } For example, it could be something like: @@ -107,7 +107,7 @@ But as you passed the `HTMLResponse` in the `response_class` too, **FastAPI** wi -## Available responses +## Available responses { #available-responses } Here are some of the available responses. @@ -121,7 +121,7 @@ You could also use `from starlette.responses import HTMLResponse`. /// -### `Response` +### `Response` { #response } The main `Response` class, all the other responses inherit from it. @@ -138,23 +138,23 @@ FastAPI (actually Starlette) will automatically include a Content-Length header. {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} -### `HTMLResponse` +### `HTMLResponse` { #htmlresponse } Takes some text or bytes and returns an HTML response, as you read above. -### `PlainTextResponse` +### `PlainTextResponse` { #plaintextresponse } Takes some text or bytes and returns a plain text response. {* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} -### `JSONResponse` +### `JSONResponse` { #jsonresponse } Takes some data and returns an `application/json` encoded response. This is the default response used in **FastAPI**, as you read above. -### `ORJSONResponse` +### `ORJSONResponse` { #orjsonresponse } A fast alternative JSON response using `orjson`, as you read above. @@ -164,7 +164,7 @@ This requires installing `orjson` for example with `pip install orjson`. /// -### `UJSONResponse` +### `UJSONResponse` { #ujsonresponse } An alternative JSON response using `ujson`. @@ -188,7 +188,7 @@ It's possible that `ORJSONResponse` might be a faster alternative. /// -### `RedirectResponse` +### `RedirectResponse` { #redirectresponse } Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default. @@ -213,15 +213,15 @@ You can also use the `status_code` parameter combined with the `response_class` {* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} -### `StreamingResponse` +### `StreamingResponse` { #streamingresponse } Takes an async generator or a normal generator/iterator and streams the response body. {* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} -#### Using `StreamingResponse` with file-like objects +#### Using `StreamingResponse` with file-like objects { #using-streamingresponse-with-file-like-objects } -If you have a file-like object (e.g. the object returned by `open()`), you can create a generator function to iterate over that file-like object. +If you have a file-like object (e.g. the object returned by `open()`), you can create a generator function to iterate over that file-like object. That way, you don't have to read it all first in memory, and you can pass that generator function to the `StreamingResponse`, and return it. @@ -243,7 +243,7 @@ Notice that here as we are using standard `open()` that doesn't support `async` /// -### `FileResponse` +### `FileResponse` { #fileresponse } Asynchronously streams a file as the response. @@ -264,7 +264,7 @@ You can also use the `response_class` parameter: In this case, you can return the file path directly from your *path operation* function. -## Custom response class +## Custom response class { #custom-response-class } You can create your own custom response class, inheriting from `Response` and using it. @@ -292,7 +292,7 @@ Now instead of returning: Of course, you will probably find much better ways to take advantage of this than formatting JSON. 😉 -## Default response class +## Default response class { #default-response-class } When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default. @@ -308,6 +308,6 @@ You can still override `response_class` in *path operations* as before. /// -## Additional documentation +## Additional documentation { #additional-documentation } You can also declare the media type and many other details in OpenAPI using `responses`: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}. diff --git a/docs/en/docs/advanced/dataclasses.md b/docs/en/docs/advanced/dataclasses.md index 2936c6d5d..b7b9b65c5 100644 --- a/docs/en/docs/advanced/dataclasses.md +++ b/docs/en/docs/advanced/dataclasses.md @@ -1,4 +1,4 @@ -# Using Dataclasses +# Using Dataclasses { #using-dataclasses } FastAPI is built on top of **Pydantic**, and I have been showing you how to use Pydantic models to declare requests and responses. @@ -28,7 +28,7 @@ But if you have a bunch of dataclasses laying around, this is a nice trick to us /// -## Dataclasses in `response_model` +## Dataclasses in `response_model` { #dataclasses-in-response-model } You can also use `dataclasses` in the `response_model` parameter: @@ -40,7 +40,7 @@ This way, its schema will show up in the API docs user interface: -## Dataclasses in Nested Data Structures +## Dataclasses in Nested Data Structures { #dataclasses-in-nested-data-structures } You can also combine `dataclasses` with other type annotations to make nested data structures. @@ -84,12 +84,12 @@ You can combine `dataclasses` with other type annotations in many different comb Check the in-code annotation tips above to see more specific details. -## Learn More +## Learn More { #learn-more } You can also combine `dataclasses` with other Pydantic models, inherit from them, include them in your own models, etc. To learn more, check the Pydantic docs about dataclasses. -## Version +## Version { #version } This is available since FastAPI version `0.67.0`. 🔖 diff --git a/docs/en/docs/advanced/events.md b/docs/en/docs/advanced/events.md index 19465d891..c805e81ee 100644 --- a/docs/en/docs/advanced/events.md +++ b/docs/en/docs/advanced/events.md @@ -1,4 +1,4 @@ -# Lifespan Events +# Lifespan Events { #lifespan-events } You can define logic (code) that should be executed before the application **starts up**. This means that this code will be executed **once**, **before** the application **starts receiving requests**. @@ -8,7 +8,7 @@ Because this code is executed before the application **starts** taking requests, This can be very useful for setting up **resources** that you need to use for the whole app, and that are **shared** among requests, and/or that you need to **clean up** afterwards. For example, a database connection pool, or loading a shared machine learning model. -## Use Case +## Use Case { #use-case } Let's start with an example **use case** and then see how to solve it with this. @@ -22,7 +22,7 @@ You could load it at the top level of the module/file, but that would also mean That's what we'll solve, let's load the model before the requests are handled, but only right before the application starts receiving requests, not while the code is being loaded. -## Lifespan +## Lifespan { #lifespan } You can define this *startup* and *shutdown* logic using the `lifespan` parameter of the `FastAPI` app, and a "context manager" (I'll show you what that is in a second). @@ -44,7 +44,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷 /// -### Lifespan function +### Lifespan function { #lifespan-function } The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`. @@ -54,7 +54,7 @@ The first part of the function, before the `yield`, will be executed **before** And the part after the `yield` will be executed **after** the application has finished. -### Async Context Manager +### Async Context Manager { #async-context-manager } If you check, the function is decorated with an `@asynccontextmanager`. @@ -84,7 +84,7 @@ The `lifespan` parameter of the `FastAPI` app takes an **async context manager** {* ../../docs_src/events/tutorial003.py hl[22] *} -## Alternative Events (deprecated) +## Alternative Events (deprecated) { #alternative-events-deprecated } /// warning @@ -100,7 +100,7 @@ You can define event handlers (functions) that need to be executed before the ap These functions can be declared with `async def` or normal `def`. -### `startup` event +### `startup` event { #startup-event } To add a function that should be run before the application starts, declare it with the event `"startup"`: @@ -112,7 +112,7 @@ You can add more than one event handler function. And your application won't start receiving requests until all the `startup` event handlers have completed. -### `shutdown` event +### `shutdown` event { #shutdown-event } To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`: @@ -138,7 +138,7 @@ So, we declare the event handler function with standard `def` instead of `async /// -### `startup` and `shutdown` together +### `startup` and `shutdown` together { #startup-and-shutdown-together } There's a high chance that the logic for your *startup* and *shutdown* is connected, you might want to start something and then finish it, acquire a resource and then release it, etc. @@ -146,7 +146,7 @@ Doing that in separated functions that don't share logic or variables together i Because of that, it's now recommended to instead use the `lifespan` as explained above. -## Technical Details +## Technical Details { #technical-details } Just a technical detail for the curious nerds. 🤓 @@ -160,6 +160,6 @@ Including how to handle lifespan state that can be used in other areas of your c /// -## Sub Applications +## Sub Applications { #sub-applications } 🚨 Keep in mind that these lifespan events (startup and shutdown) will only be executed for the main application, not for [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}. diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md index 55e6a08b1..897c30808 100644 --- a/docs/en/docs/advanced/generate-clients.md +++ b/docs/en/docs/advanced/generate-clients.md @@ -1,34 +1,42 @@ -# Generate Clients +# Generating SDKs { #generating-sdks } -As **FastAPI** is based on the OpenAPI specification, you get automatic compatibility with many tools, including the automatic API docs (provided by Swagger UI). +Because **FastAPI** is based on the **OpenAPI** specification, its APIs can be described in a standard format that many tools understand. -One particular advantage that is not necessarily obvious is that you can **generate clients** (sometimes called **SDKs** ) for your API, for many different **programming languages**. +This makes it easy to generate up-to-date **documentation**, client libraries (**SDKs**) in multiple languages, and **testing** or **automation workflows** that stay in sync with your code. -## OpenAPI Client Generators +In this guide, you'll learn how to generate a **TypeScript SDK** for your FastAPI backend. -There are many tools to generate clients from **OpenAPI**. +## Open Source SDK Generators { #open-source-sdk-generators } -A common tool is OpenAPI Generator. +A versatile option is the OpenAPI Generator, which supports **many programming languages** and can generate SDKs from your OpenAPI specification. -If you are building a **frontend**, a very interesting alternative is openapi-ts. +For **TypeScript clients**, Hey API is a purpose-built solution, providing an optimized experience for the TypeScript ecosystem. -## Client and SDK Generators - Sponsor +You can discover more SDK generators on OpenAPI.Tools. -There are also some **company-backed** Client and SDK generators based on OpenAPI (FastAPI), in some cases they can offer you **additional features** on top of high-quality generated SDKs/clients. +/// tip -Some of them also ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**. +FastAPI automatically generates **OpenAPI 3.1** specifications, so any tool you use must support this version. -And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇 +/// + +## SDK Generators from FastAPI Sponsors { #sdk-generators-from-fastapi-sponsors } + +This section highlights **venture-backed** and **company-supported** solutions from companies that sponsor FastAPI. These products provide **additional features** and **integrations** on top of high-quality generated SDKs. + +By ✨ [**sponsoring FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, these companies help ensure the framework and its **ecosystem** remain healthy and **sustainable**. + +Their sponsorship also demonstrates a strong commitment to the FastAPI **community** (you), showing that they care not only about offering a **great service** but also about supporting a **robust and thriving framework**, FastAPI. 🙇 For example, you might want to try: * Speakeasy -* Stainless +* Stainless * liblab -There are also several other companies offering similar services that you can search and find online. 🤓 +Some of these solutions may also be open source or offer free tiers, so you can try them without a financial commitment. Other commercial SDK generators are available and can be found online. 🤓 -## Generate a TypeScript Frontend Client +## Create a TypeScript SDK { #create-a-typescript-sdk } Let's start with a simple FastAPI application: @@ -36,80 +44,33 @@ Let's start with a simple FastAPI application: Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`. -### API Docs +### API Docs { #api-docs } -If you go to the API docs, you will see that it has the **schemas** for the data to be sent in requests and received in responses: +If you go to `/docs`, you will see that it has the **schemas** for the data to be sent in requests and received in responses: You can see those schemas because they were declared with the models in the app. -That information is available in the app's **OpenAPI schema**, and then shown in the API docs (by Swagger UI). +That information is available in the app's **OpenAPI schema**, and then shown in the API docs. -And that same information from the models that is included in OpenAPI is what can be used to **generate the client code**. +That same information from the models that is included in OpenAPI is what can be used to **generate the client code**. -### Generate a TypeScript Client +### Hey API { #hey-api } -Now that we have the app with the models, we can generate the client code for the frontend. +Once we have a FastAPI app with the models, we can use Hey API to generate a TypeScript client. The fastest way to do that is via npx. -#### Install `openapi-ts` - -You can install `openapi-ts` in your frontend code with: - -
- -```console -$ npm install @hey-api/openapi-ts --save-dev - ----> 100% +```sh +npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client ``` -
+This will generate a TypeScript SDK in `./src/client`. -#### Generate Client Code +You can learn how to install `@hey-api/openapi-ts` and read about the generated output on their website. -To generate the client code you can use the command line application `openapi-ts` that would now be installed. +### Using the SDK { #using-the-sdk } -Because it is installed in the local project, you probably wouldn't be able to call that command directly, but you would put it on your `package.json` file. - -It could look like this: - -```JSON hl_lines="7" -{ - "name": "frontend-app", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios" - }, - "author": "", - "license": "", - "devDependencies": { - "@hey-api/openapi-ts": "^0.27.38", - "typescript": "^4.6.2" - } -} -``` - -After having that NPM `generate-client` script there, you can run it with: - -
- -```console -$ npm run generate-client - -frontend-app@1.0.0 generate-client /home/user/code/frontend-app -> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios -``` - -
- -That command will generate code in `./src/client` and will use `axios` (the frontend HTTP library) internally. - -### Try Out the Client Code - -Now you can import and use the client code, it could look like this, notice that you get autocompletion for the methods: +Now you can import and use the client code. It could look like this, notice that you get autocompletion for the methods: @@ -131,30 +92,30 @@ The response object will also have autocompletion: -## FastAPI App with Tags +## FastAPI App with Tags { #fastapi-app-with-tags } -In many cases your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*. +In many cases, your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*. For example, you could have a section for **items** and another section for **users**, and they could be separated by tags: {* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *} -### Generate a TypeScript Client with Tags +### Generate a TypeScript Client with Tags { #generate-a-typescript-client-with-tags } If you generate a client for a FastAPI app using tags, it will normally also separate the client code based on the tags. -This way you will be able to have things ordered and grouped correctly for the client code: +This way, you will be able to have things ordered and grouped correctly for the client code: -In this case you have: +In this case, you have: * `ItemsService` * `UsersService` -### Client Method Names +### Client Method Names { #client-method-names } -Right now the generated method names like `createItemItemsPost` don't look very clean: +Right now, the generated method names like `createItemItemsPost` don't look very clean: ```TypeScript ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) @@ -166,17 +127,17 @@ OpenAPI requires that each operation ID is unique across all the *path operation But I'll show you how to improve that next. 🤓 -## Custom Operation IDs and Better Method Names +## Custom Operation IDs and Better Method Names { #custom-operation-ids-and-better-method-names } You can **modify** the way these operation IDs are **generated** to make them simpler and have **simpler method names** in the clients. -In this case you will have to ensure that each operation ID is **unique** in some other way. +In this case, you will have to ensure that each operation ID is **unique** in some other way. For example, you could make sure that each *path operation* has a tag, and then generate the operation ID based on the **tag** and the *path operation* **name** (the function name). -### Custom Generate Unique ID Function +### Custom Generate Unique ID Function { #custom-generate-unique-id-function } -FastAPI uses a **unique ID** for each *path operation*, it is used for the **operation ID** and also for the names of any needed custom models, for requests or responses. +FastAPI uses a **unique ID** for each *path operation*, which is used for the **operation ID** and also for the names of any needed custom models, for requests or responses. You can customize that function. It takes an `APIRoute` and outputs a string. @@ -186,15 +147,15 @@ You can then pass that custom function to **FastAPI** as the `generate_unique_id {* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *} -### Generate a TypeScript Client with Custom Operation IDs +### Generate a TypeScript Client with Custom Operation IDs { #generate-a-typescript-client-with-custom-operation-ids } -Now if you generate the client again, you will see that it has the improved method names: +Now, if you generate the client again, you will see that it has the improved method names: As you see, the method names now have the tag and then the function name, now they don't include information from the URL path and the HTTP operation. -### Preprocess the OpenAPI Specification for the Client Generator +### Preprocess the OpenAPI Specification for the Client Generator { #preprocess-the-openapi-specification-for-the-client-generator } The generated code still has some **duplicated information**. @@ -202,7 +163,7 @@ We already know that this method is related to the **items** because that word i We will probably still want to keep it for OpenAPI in general, as that will ensure that the operation IDs are **unique**. -But for the generated client we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**. +But for the generated client, we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**. We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this: @@ -218,35 +179,21 @@ We could download the OpenAPI JSON to a file `openapi.json` and then we could ** With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names. -### Generate a TypeScript Client with the Preprocessed OpenAPI +### Generate a TypeScript Client with the Preprocessed OpenAPI { #generate-a-typescript-client-with-the-preprocessed-openapi } -Now as the end result is in a file `openapi.json`, you would modify the `package.json` to use that local file, for example: +Since the end result is now in an `openapi.json` file, you need to update your input location: -```JSON hl_lines="7" -{ - "name": "frontend-app", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios" - }, - "author": "", - "license": "", - "devDependencies": { - "@hey-api/openapi-ts": "^0.27.38", - "typescript": "^4.6.2" - } -} +```sh +npx @hey-api/openapi-ts -i ./openapi.json -o src/client ``` After generating the new client, you would now have **clean method names**, with all the **autocompletion**, **inline errors**, etc: -## Benefits +## Benefits { #benefits } -When using the automatically generated clients you would get **autocompletion** for: +When using the automatically generated clients, you would get **autocompletion** for: * Methods. * Request payloads in the body, query parameters, etc. @@ -256,6 +203,6 @@ You would also have **inline errors** for everything. And whenever you update the backend code, and **regenerate** the frontend, it would have any new *path operations* available as methods, the old ones removed, and any other change would be reflected on the generated code. 🤓 -This also means that if something changed it will be **reflected** on the client code automatically. And if you **build** the client it will error out if you have any **mismatch** in the data used. +This also means that if something changed, it will be **reflected** on the client code automatically. And if you **build** the client, it will error out if you have any **mismatch** in the data used. So, you would **detect many errors** very early in the development cycle instead of having to wait for the errors to show up to your final users in production and then trying to debug where the problem is. ✨ diff --git a/docs/en/docs/advanced/index.md b/docs/en/docs/advanced/index.md index 47385e2c6..9355516fb 100644 --- a/docs/en/docs/advanced/index.md +++ b/docs/en/docs/advanced/index.md @@ -1,6 +1,6 @@ -# Advanced User Guide +# Advanced User Guide { #advanced-user-guide } -## Additional Features +## Additional Features { #additional-features } The main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} should be enough to give you a tour through all the main features of **FastAPI**. @@ -14,7 +14,7 @@ And it's possible that for your use case, the solution is in one of them. /// -## Read the Tutorial first +## Read the Tutorial first { #read-the-tutorial-first } You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank}. diff --git a/docs/en/docs/advanced/middleware.md b/docs/en/docs/advanced/middleware.md index 1d40b1c8f..d1be4afff 100644 --- a/docs/en/docs/advanced/middleware.md +++ b/docs/en/docs/advanced/middleware.md @@ -1,4 +1,4 @@ -# Advanced Middleware +# Advanced Middleware { #advanced-middleware } In the main tutorial you read how to add [Custom Middleware](../tutorial/middleware.md){.internal-link target=_blank} to your application. @@ -6,7 +6,7 @@ And then you also read how to handle [CORS with the `CORSMiddleware`](../tutoria In this section we'll see how to use other middlewares. -## Adding ASGI middlewares +## Adding ASGI middlewares { #adding-asgi-middlewares } As **FastAPI** is based on Starlette and implements the ASGI specification, you can use any ASGI middleware. @@ -39,7 +39,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") `app.add_middleware()` receives a middleware class as the first argument and any additional arguments to be passed to the middleware. -## Integrated middlewares +## Integrated middlewares { #integrated-middlewares } **FastAPI** includes several middlewares for common use cases, we'll see next how to use them. @@ -51,7 +51,7 @@ For the next examples, you could also use `from starlette.middleware.something i /// -## `HTTPSRedirectMiddleware` +## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware } Enforces that all incoming requests must either be `https` or `wss`. @@ -59,7 +59,7 @@ Any incoming request to `http` or `ws` will be redirected to the secure scheme i {* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *} -## `TrustedHostMiddleware` +## `TrustedHostMiddleware` { #trustedhostmiddleware } Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks. @@ -68,10 +68,11 @@ Enforces that all incoming requests have a correctly set `Host` header, in order The following arguments are supported: * `allowed_hosts` - A list of domain names that should be allowed as hostnames. Wildcard domains such as `*.example.com` are supported for matching subdomains. To allow any hostname either use `allowed_hosts=["*"]` or omit the middleware. +* `www_redirect` - If set to True, requests to non-www versions of the allowed hosts will be redirected to their www counterparts. Defaults to `True`. If an incoming request does not validate correctly then a `400` response will be sent. -## `GZipMiddleware` +## `GZipMiddleware` { #gzipmiddleware } Handles GZip responses for any request that includes `"gzip"` in the `Accept-Encoding` header. @@ -84,7 +85,7 @@ The following arguments are supported: * `minimum_size` - Do not GZip responses that are smaller than this minimum size in bytes. Defaults to `500`. * `compresslevel` - Used during GZip compression. It is an integer ranging from 1 to 9. Defaults to `9`. Lower value results in faster compression but larger file sizes, while higher value results in slower compression but smaller file sizes. -## Other middlewares +## Other middlewares { #other-middlewares } There are many other ASGI middlewares. diff --git a/docs/en/docs/advanced/openapi-callbacks.md b/docs/en/docs/advanced/openapi-callbacks.md index ca9065a89..059d893c2 100644 --- a/docs/en/docs/advanced/openapi-callbacks.md +++ b/docs/en/docs/advanced/openapi-callbacks.md @@ -1,4 +1,4 @@ -# OpenAPI Callbacks +# OpenAPI Callbacks { #openapi-callbacks } You could create an API with a *path operation* that could trigger a request to an *external API* created by someone else (probably the same developer that would be *using* your API). @@ -6,7 +6,7 @@ The process that happens when your API app calls the *external API* is named a " In this case, you could want to document how that external API *should* look like. What *path operation* it should have, what body it should expect, what response it should return, etc. -## An app with callbacks +## An app with callbacks { #an-app-with-callbacks } Let's see all this with an example. @@ -23,7 +23,7 @@ Then your API will (let's imagine): * Send a notification back to the API user (the external developer). * This will be done by sending a POST request (from *your API*) to some *external API* provided by that external developer (this is the "callback"). -## The normal **FastAPI** app +## The normal **FastAPI** app { #the-normal-fastapi-app } Let's first see how the normal API app would look like before adding the callback. @@ -41,7 +41,7 @@ The `callback_url` query parameter uses a Pydantic OpenAPI 3 expression (see more below) where it can use variables with parameters and parts of the original request sent to *your API*. -### The callback path expression +### The callback path expression { #the-callback-path-expression } The callback *path* can have an OpenAPI 3 expression that can contain parts of the original request sent to *your API*. @@ -163,7 +163,7 @@ Notice how the callback URL used contains the URL received as a query parameter /// -### Add the callback router +### Add the callback router { #add-the-callback-router } At this point you have the *callback path operation(s)* needed (the one(s) that the *external developer* should implement in the *external API*) in the callback router you created above. @@ -177,7 +177,7 @@ Notice that you are not passing the router itself (`invoices_callback_router`) t /// -### Check the docs +### Check the docs { #check-the-docs } Now you can start your app and go to http://127.0.0.1:8000/docs. diff --git a/docs/en/docs/advanced/openapi-webhooks.md b/docs/en/docs/advanced/openapi-webhooks.md index 97aaa41af..416cf4b75 100644 --- a/docs/en/docs/advanced/openapi-webhooks.md +++ b/docs/en/docs/advanced/openapi-webhooks.md @@ -1,4 +1,4 @@ -# OpenAPI Webhooks +# OpenAPI Webhooks { #openapi-webhooks } There are cases where you want to tell your API **users** that your app could call *their* app (sending a request) with some data, normally to **notify** of some type of **event**. @@ -6,7 +6,7 @@ This means that instead of the normal process of your users sending requests to This is normally called a **webhook**. -## Webhooks steps +## Webhooks steps { #webhooks-steps } The process normally is that **you define** in your code what is the message that you will send, the **body of the request**. @@ -16,7 +16,7 @@ And **your users** define in some way (for example in a web dashboard somewhere) All the **logic** about how to register the URLs for webhooks and the code to actually send those requests is up to you. You write it however you want to in **your own code**. -## Documenting webhooks with **FastAPI** and OpenAPI +## Documenting webhooks with **FastAPI** and OpenAPI { #documenting-webhooks-with-fastapi-and-openapi } With **FastAPI**, using OpenAPI, you can define the names of these webhooks, the types of HTTP operations that your app can send (e.g. `POST`, `PUT`, etc.) and the request **bodies** that your app would send. @@ -28,7 +28,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0` /// -## An app with webhooks +## An app with webhooks { #an-app-with-webhooks } When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`. @@ -46,7 +46,7 @@ Notice that with webhooks you are actually not declaring a *path* (like `/items/ This is because it is expected that **your users** would define the actual **URL path** where they want to receive the webhook request in some other way (e.g. a web dashboard). -### Check the docs +### Check the docs { #check-the-docs } Now you can start your app and go to http://127.0.0.1:8000/docs. diff --git a/docs/en/docs/advanced/path-operation-advanced-configuration.md b/docs/en/docs/advanced/path-operation-advanced-configuration.md index c4814ebd2..b9961f9f3 100644 --- a/docs/en/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/en/docs/advanced/path-operation-advanced-configuration.md @@ -1,6 +1,6 @@ -# Path Operation Advanced Configuration +# Path Operation Advanced Configuration { #path-operation-advanced-configuration } -## OpenAPI operationId +## OpenAPI operationId { #openapi-operationid } /// warning @@ -14,7 +14,7 @@ You would have to make sure that it is unique for each operation. {* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} -### Using the *path operation function* name as the operationId +### Using the *path operation function* name as the operationId { #using-the-path-operation-function-name-as-the-operationid } If you want to use your APIs' function names as `operationId`s, you can iterate over all of them and override each *path operation's* `operation_id` using their `APIRoute.name`. @@ -36,13 +36,13 @@ Even if they are in different modules (Python files). /// -## Exclude from OpenAPI +## Exclude from OpenAPI { #exclude-from-openapi } To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`: {* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} -## Advanced description from docstring +## Advanced description from docstring { #advanced-description-from-docstring } You can limit the lines used from the docstring of a *path operation function* for OpenAPI. @@ -52,7 +52,7 @@ It won't show up in the documentation, but other tools (such as Sphinx) will be {* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *} -## Additional Responses +## Additional Responses { #additional-responses } You probably have seen how to declare the `response_model` and `status_code` for a *path operation*. @@ -62,7 +62,7 @@ You can also declare additional responses with their models, status codes, etc. There's a whole chapter here in the documentation about it, you can read it at [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}. -## OpenAPI Extra +## OpenAPI Extra { #openapi-extra } When you declare a *path operation* in your application, **FastAPI** automatically generates the relevant metadata about that *path operation* to be included in the OpenAPI schema. @@ -88,7 +88,7 @@ If you only need to declare additional responses, a more convenient way to do it You can extend the OpenAPI schema for a *path operation* using the parameter `openapi_extra`. -### OpenAPI Extensions +### OpenAPI Extensions { #openapi-extensions } This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): @@ -129,7 +129,7 @@ And if you see the resulting OpenAPI (at `/openapi.json` in your API), you will } ``` -### Custom OpenAPI *path operation* schema +### Custom OpenAPI *path operation* schema { #custom-openapi-path-operation-schema } The dictionary in `openapi_extra` will be deeply merged with the automatically generated OpenAPI schema for the *path operation*. @@ -145,7 +145,7 @@ In this example, we didn't declare any Pydantic model. In fact, the request body Nevertheless, we can declare the expected schema for the request body. -### Custom OpenAPI content type +### Custom OpenAPI content type { #custom-openapi-content-type } Using this same trick, you could use a Pydantic model to define the JSON Schema that is then included in the custom OpenAPI schema section for the *path operation*. diff --git a/docs/en/docs/advanced/response-change-status-code.md b/docs/en/docs/advanced/response-change-status-code.md index 6d3f9f3e8..912ed0f1a 100644 --- a/docs/en/docs/advanced/response-change-status-code.md +++ b/docs/en/docs/advanced/response-change-status-code.md @@ -1,10 +1,10 @@ -# Response - Change Status Code +# Response - Change Status Code { #response-change-status-code } You probably read before that you can set a default [Response Status Code](../tutorial/response-status-code.md){.internal-link target=_blank}. But in some cases you need to return a different status code than the default. -## Use case +## Use case { #use-case } For example, imagine that you want to return an HTTP status code of "OK" `200` by default. @@ -14,7 +14,7 @@ But you still want to be able to filter and convert the data you return with a ` For those cases, you can use a `Response` parameter. -## Use a `Response` parameter +## Use a `Response` parameter { #use-a-response-parameter } You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies and headers). diff --git a/docs/en/docs/advanced/response-cookies.md b/docs/en/docs/advanced/response-cookies.md index f6d17f35d..d8f77b56a 100644 --- a/docs/en/docs/advanced/response-cookies.md +++ b/docs/en/docs/advanced/response-cookies.md @@ -1,6 +1,6 @@ -# Response Cookies +# Response Cookies { #response-cookies } -## Use a `Response` parameter +## Use a `Response` parameter { #use-a-response-parameter } You can declare a parameter of type `Response` in your *path operation function*. @@ -16,7 +16,7 @@ And if you declared a `response_model`, it will still be used to filter and conv You can also declare the `Response` parameter in dependencies, and set cookies (and headers) in them. -## Return a `Response` directly +## Return a `Response` directly { #return-a-response-directly } You can also create cookies when returning a `Response` directly in your code. @@ -36,7 +36,7 @@ And also that you are not sending any data that should have been filtered by a ` /// -### More info +### More info { #more-info } /// note | Technical Details diff --git a/docs/en/docs/advanced/response-directly.md b/docs/en/docs/advanced/response-directly.md index 759b762b5..3197e1bd4 100644 --- a/docs/en/docs/advanced/response-directly.md +++ b/docs/en/docs/advanced/response-directly.md @@ -1,4 +1,4 @@ -# Return a Response Directly +# Return a Response Directly { #return-a-response-directly } When you create a **FastAPI** *path operation* you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc. @@ -10,7 +10,7 @@ But you can return a `JSONResponse` directly from your *path operations*. It might be useful, for example, to return custom headers or cookies. -## Return a `Response` +## Return a `Response` { #return-a-response } In fact, you can return any `Response` or any sub-class of it. @@ -26,7 +26,7 @@ It won't do any data conversion with Pydantic models, it won't convert the conte This gives you a lot of flexibility. You can return any data type, override any data declaration or validation, etc. -## Using the `jsonable_encoder` in a `Response` +## Using the `jsonable_encoder` in a `Response` { #using-the-jsonable-encoder-in-a-response } Because **FastAPI** doesn't make any changes to a `Response` you return, you have to make sure its contents are ready for it. @@ -44,7 +44,7 @@ You could also use `from starlette.responses import JSONResponse`. /// -## Returning a custom `Response` +## Returning a custom `Response` { #returning-a-custom-response } The example above shows all the parts you need, but it's not very useful yet, as you could have just returned the `item` directly, and **FastAPI** would put it in a `JSONResponse` for you, converting it to a `dict`, etc. All that by default. @@ -56,7 +56,7 @@ You could put your XML content in a string, put that in a `Response`, and return {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} -## Notes +## Notes { #notes } When you return a `Response` directly its data is not validated, converted (serialized), or documented automatically. diff --git a/docs/en/docs/advanced/response-headers.md b/docs/en/docs/advanced/response-headers.md index 97e888983..19c9ff2ad 100644 --- a/docs/en/docs/advanced/response-headers.md +++ b/docs/en/docs/advanced/response-headers.md @@ -1,6 +1,6 @@ -# Response Headers +# Response Headers { #response-headers } -## Use a `Response` parameter +## Use a `Response` parameter { #use-a-response-parameter } You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies). @@ -16,7 +16,7 @@ And if you declared a `response_model`, it will still be used to filter and conv You can also declare the `Response` parameter in dependencies, and set headers (and cookies) in them. -## Return a `Response` directly +## Return a `Response` directly { #return-a-response-directly } You can also add headers when you return a `Response` directly. @@ -34,8 +34,8 @@ And as the `Response` can be used frequently to set headers and cookies, **FastA /// -## Custom Headers +## Custom Headers { #custom-headers } -Keep in mind that custom proprietary headers can be added using the 'X-' prefix. +Keep in mind that custom proprietary headers can be added using the `X-` prefix. But if you have custom headers that you want a client in a browser to be able to see, you need to add them to your CORS configurations (read more in [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), using the parameter `expose_headers` documented in Starlette's CORS docs. diff --git a/docs/en/docs/advanced/security/http-basic-auth.md b/docs/en/docs/advanced/security/http-basic-auth.md index 234e2f940..01b98eeff 100644 --- a/docs/en/docs/advanced/security/http-basic-auth.md +++ b/docs/en/docs/advanced/security/http-basic-auth.md @@ -1,4 +1,4 @@ -# HTTP Basic Auth +# HTTP Basic Auth { #http-basic-auth } For the simplest cases, you can use HTTP Basic Auth. @@ -12,7 +12,7 @@ That tells the browser to show the integrated prompt for a username and password Then, when you type that username and password, the browser sends them in the header automatically. -## Simple HTTP Basic Auth +## Simple HTTP Basic Auth { #simple-http-basic-auth } * Import `HTTPBasic` and `HTTPBasicCredentials`. * Create a "`security` scheme" using `HTTPBasic`. @@ -26,7 +26,7 @@ When you try to open the URL for the first time (or click the "Execute" button i -## Check the username +## Check the username { #check-the-username } Here's a more complete example. @@ -52,7 +52,7 @@ if not (credentials.username == "stanleyjobson") or not (credentials.password == But by using the `secrets.compare_digest()` it will be secure against a type of attacks called "timing attacks". -### Timing Attacks +### Timing Attacks { #timing-attacks } But what's a "timing attack"? @@ -80,19 +80,19 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": Python will have to compare the whole `stanleyjobso` in both `stanleyjobsox` and `stanleyjobson` before realizing that both strings are not the same. So it will take some extra microseconds to reply back "Incorrect username or password". -#### The time to answer helps the attackers +#### The time to answer helps the attackers { #the-time-to-answer-helps-the-attackers } At that point, by noticing that the server took some microseconds longer to send the "Incorrect username or password" response, the attackers will know that they got _something_ right, some of the initial letters were right. And then they can try again knowing that it's probably something more similar to `stanleyjobsox` than to `johndoe`. -#### A "professional" attack +#### A "professional" attack { #a-professional-attack } Of course, the attackers would not try all this by hand, they would write a program to do it, possibly with thousands or millions of tests per second. And they would get just one extra correct letter at a time. But doing that, in some minutes or hours the attackers would have guessed the correct username and password, with the "help" of our application, just using the time taken to answer. -#### Fix it with `secrets.compare_digest()` +#### Fix it with `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest } But in our code we are actually using `secrets.compare_digest()`. @@ -100,7 +100,7 @@ In short, it will take the same time to compare `stanleyjobsox` to `stanleyjobso That way, using `secrets.compare_digest()` in your application code, it will be safe against this whole range of security attacks. -### Return the error +### Return the error { #return-the-error } After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again: diff --git a/docs/en/docs/advanced/security/index.md b/docs/en/docs/advanced/security/index.md index edb42132e..996d716b4 100644 --- a/docs/en/docs/advanced/security/index.md +++ b/docs/en/docs/advanced/security/index.md @@ -1,6 +1,6 @@ -# Advanced Security +# Advanced Security { #advanced-security } -## Additional Features +## Additional Features { #additional-features } There are some extra features to handle security apart from the ones covered in the [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank}. @@ -12,7 +12,7 @@ And it's possible that for your use case, the solution is in one of them. /// -## Read the Tutorial first +## Read the Tutorial first { #read-the-tutorial-first } The next sections assume you already read the main [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank}. diff --git a/docs/en/docs/advanced/security/oauth2-scopes.md b/docs/en/docs/advanced/security/oauth2-scopes.md index 4cb0b39bc..67c927cd0 100644 --- a/docs/en/docs/advanced/security/oauth2-scopes.md +++ b/docs/en/docs/advanced/security/oauth2-scopes.md @@ -1,12 +1,12 @@ -# OAuth2 scopes +# OAuth2 scopes { #oauth2-scopes } You can use OAuth2 scopes directly with **FastAPI**, they are integrated to work seamlessly. This would allow you to have a more fine-grained permission system, following the OAuth2 standard, integrated into your OpenAPI application (and the API docs). -OAuth2 with scopes is the mechanism used by many big authentication providers, like Facebook, Google, GitHub, Microsoft, Twitter, etc. They use it to provide specific permissions to users and applications. +OAuth2 with scopes is the mechanism used by many big authentication providers, like Facebook, Google, GitHub, Microsoft, X (Twitter), etc. They use it to provide specific permissions to users and applications. -Every time you "log in with" Facebook, Google, GitHub, Microsoft, Twitter, that application is using OAuth2 with scopes. +Every time you "log in with" Facebook, Google, GitHub, Microsoft, X (Twitter), that application is using OAuth2 with scopes. In this section you will see how to manage authentication and authorization with the same OAuth2 with scopes in your **FastAPI** application. @@ -26,7 +26,7 @@ But if you know you need it, or you are curious, keep reading. /// -## OAuth2 scopes and OpenAPI +## OAuth2 scopes and OpenAPI { #oauth2-scopes-and-openapi } The OAuth2 specification defines "scopes" as a list of strings separated by spaces. @@ -58,15 +58,15 @@ For OAuth2 they are just strings. /// -## Global view +## Global view { #global-view } First, let's quickly see the parts that change from the examples in the main **Tutorial - User Guide** for [OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Now using OAuth2 scopes: -{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:125,129:135,140,156] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *} Now let's review those changes step by step. -## OAuth2 Security scheme +## OAuth2 Security scheme { #oauth2-security-scheme } The first change is that now we are declaring the OAuth2 security scheme with two available scopes, `me` and `items`. @@ -82,7 +82,7 @@ This is the same mechanism used when you give permissions while logging in with -## JWT token with scopes +## JWT token with scopes { #jwt-token-with-scopes } Now, modify the token *path operation* to return the scopes requested. @@ -98,9 +98,9 @@ But in your application, for security, you should make sure you only add the sco /// -{* ../../docs_src/security/tutorial005_an_py310.py hl[156] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *} -## Declare scopes in *path operations* and dependencies +## Declare scopes in *path operations* and dependencies { #declare-scopes-in-path-operations-and-dependencies } Now we declare that the *path operation* for `/users/me/items/` requires the scope `items`. @@ -124,7 +124,7 @@ We are doing it here to demonstrate how **FastAPI** handles scopes declared at d /// -{* ../../docs_src/security/tutorial005_an_py310.py hl[5,140,171] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *} /// info | Technical Details @@ -136,7 +136,7 @@ But when you import `Query`, `Path`, `Depends`, `Security` and others from `fast /// -## Use `SecurityScopes` +## Use `SecurityScopes` { #use-securityscopes } Now update the dependency `get_current_user`. @@ -152,7 +152,7 @@ This `SecurityScopes` class is similar to `Request` (`Request` was used to get t {* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *} -## Use the `scopes` +## Use the `scopes` { #use-the-scopes } The parameter `security_scopes` will be of type `SecurityScopes`. @@ -166,7 +166,7 @@ In this exception, we include the scopes required (if any) as a string separated {* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *} -## Verify the `username` and data shape +## Verify the `username` and data shape { #verify-the-username-and-data-shape } We verify that we get a `username`, and extract the scopes. @@ -180,17 +180,17 @@ Instead of, for example, a `dict`, or something else, as it could break the appl We also verify that we have a user with that username, and if not, we raise that same exception we created before. -{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:128] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *} -## Verify the `scopes` +## Verify the `scopes` { #verify-the-scopes } We now verify that all the scopes required, by this dependency and all the dependants (including *path operations*), are included in the scopes provided in the token received, otherwise raise an `HTTPException`. For this, we use `security_scopes.scopes`, that contains a `list` with all these scopes as `str`. -{* ../../docs_src/security/tutorial005_an_py310.py hl[129:135] *} +{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *} -## Dependency tree and scopes +## Dependency tree and scopes { #dependency-tree-and-scopes } Let's review again this dependency tree and the scopes. @@ -223,7 +223,7 @@ All depending on the `scopes` declared in each *path operation* and each depende /// -## More details about `SecurityScopes` +## More details about `SecurityScopes` { #more-details-about-securityscopes } You can use `SecurityScopes` at any point, and in multiple places, it doesn't have to be at the "root" dependency. @@ -233,7 +233,7 @@ Because the `SecurityScopes` will have all the scopes declared by dependants, yo They will be checked independently for each *path operation*. -## Check it +## Check it { #check-it } If you open the API docs, you can authenticate and specify which scopes you want to authorize. @@ -245,7 +245,7 @@ And if you select the scope `me` but not the scope `items`, you will be able to That's what would happen to a third party application that tried to access one of these *path operations* with a token provided by a user, depending on how many permissions the user gave the application. -## About third party integrations +## About third party integrations { #about-third-party-integrations } In this example we are using the OAuth2 "password" flow. @@ -269,6 +269,6 @@ But in the end, they are implementing the same OAuth2 standard. **FastAPI** includes utilities for all these OAuth2 authentication flows in `fastapi.security.oauth2`. -## `Security` in decorator `dependencies` +## `Security` in decorator `dependencies` { #security-in-decorator-dependencies } The same way you can define a `list` of `Depends` in the decorator's `dependencies` parameter (as explained in [Dependencies in path operation decorators](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), you could also use `Security` with `scopes` there. diff --git a/docs/en/docs/advanced/settings.md b/docs/en/docs/advanced/settings.md index 1af19a045..a218c3d01 100644 --- a/docs/en/docs/advanced/settings.md +++ b/docs/en/docs/advanced/settings.md @@ -1,4 +1,4 @@ -# Settings and Environment Variables +# Settings and Environment Variables { #settings-and-environment-variables } In many cases your application could need some external settings or configurations, for example secret keys, database credentials, credentials for email services, etc. @@ -12,17 +12,17 @@ To understand environment variables you can read [Environment Variables](../envi /// -## Types and validation +## Types and validation { #types-and-validation } These environment variables can only handle text strings, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, as Linux, Windows, macOS). That means that any value read in Python from an environment variable will be a `str`, and any conversion to a different type or any validation has to be done in code. -## Pydantic `Settings` +## Pydantic `Settings` { #pydantic-settings } Fortunately, Pydantic provides a great utility to handle these settings coming from environment variables with Pydantic: Settings management. -### Install `pydantic-settings` +### Install `pydantic-settings` { #install-pydantic-settings } First, make sure you create your [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and then install the `pydantic-settings` package: @@ -52,7 +52,7 @@ In Pydantic v1 it came included with the main package. Now it is distributed as /// -### Create the `Settings` object +### Create the `Settings` object { #create-the-settings-object } Import `BaseSettings` from Pydantic and create a sub-class, very much like with a Pydantic model. @@ -88,13 +88,13 @@ Then, when you create an instance of that `Settings` class (in this case, in the Next it will convert and validate the data. So, when you use that `settings` object, you will have data of the types you declared (e.g. `items_per_user` will be an `int`). -### Use the `settings` +### Use the `settings` { #use-the-settings } Then you can use the new `settings` object in your application: {* ../../docs_src/settings/tutorial001.py hl[18:20] *} -### Run the server +### Run the server { #run-the-server } Next, you would run the server passing the configurations as environment variables, for example you could set an `ADMIN_EMAIL` and `APP_NAME` with: @@ -120,7 +120,7 @@ The `app_name` would be `"ChimichangApp"`. And the `items_per_user` would keep its default value of `50`. -## Settings in another module +## Settings in another module { #settings-in-another-module } You could put those settings in another module file as you saw in [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}. @@ -138,13 +138,13 @@ You would also need a file `__init__.py` as you saw in [Bigger Applications - Mu /// -## Settings in a dependency +## Settings in a dependency { #settings-in-a-dependency } In some occasions it might be useful to provide the settings from a dependency, instead of having a global object with `settings` that is used everywhere. This could be especially useful during testing, as it's very easy to override a dependency with your own custom settings. -### The config file +### The config file { #the-config-file } Coming from the previous example, your `config.py` file could look like: @@ -152,7 +152,7 @@ Coming from the previous example, your `config.py` file could look like: Notice that now we don't create a default instance `settings = Settings()`. -### The main app file +### The main app file { #the-main-app-file } Now we create a dependency that returns a new `config.Settings()`. @@ -170,7 +170,7 @@ And then we can require it from the *path operation function* as a dependency an {* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *} -### Settings and testing +### Settings and testing { #settings-and-testing } Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`: @@ -180,7 +180,7 @@ In the dependency override we set a new value for the `admin_email` when creatin Then we can test that it is used. -## Reading a `.env` file +## Reading a `.env` file { #reading-a-env-file } If you have many settings that possibly change a lot, maybe in different environments, it might be useful to put them on a file and then read them from it as if they were environment variables. @@ -202,7 +202,7 @@ For this to work, you need to `pip install python-dotenv`. /// -### The `.env` file +### The `.env` file { #the-env-file } You could have a `.env` file with: @@ -211,7 +211,7 @@ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" ``` -### Read settings from `.env` +### Read settings from `.env` { #read-settings-from-env } And then update your `config.py` with: @@ -247,7 +247,7 @@ In Pydantic version 1 the configuration was done in an internal class `Config`, Here we define the config `env_file` inside of your Pydantic `Settings` class, and set the value to the filename with the dotenv file we want to use. -### Creating the `Settings` only once with `lru_cache` +### Creating the `Settings` only once with `lru_cache` { #creating-the-settings-only-once-with-lru-cache } Reading a file from disk is normally a costly (slow) operation, so you probably want to do it only once and then reuse the same settings object, instead of reading it for each request. @@ -274,7 +274,7 @@ But as we are using the `@lru_cache` decorator on top, the `Settings` object wil Then for any subsequent call of `get_settings()` in the dependencies for the next requests, instead of executing the internal code of `get_settings()` and creating a new `Settings` object, it will return the same object that was returned on the first call, again and again. -#### `lru_cache` Technical Details +#### `lru_cache` Technical Details { #lru-cache-technical-details } `@lru_cache` modifies the function it decorates to return the same value that was returned the first time, instead of computing it again, executing the code of the function every time. @@ -337,7 +337,7 @@ That way, it behaves almost as if it was just a global variable. But as it uses `@lru_cache` is part of `functools` which is part of Python's standard library, you can read more about it in the Python docs for `@lru_cache`. -## Recap +## Recap { #recap } You can use Pydantic Settings to handle the settings or configurations for your application, with all the power of Pydantic models. diff --git a/docs/en/docs/advanced/sub-applications.md b/docs/en/docs/advanced/sub-applications.md index 48e329fc1..fbd0e1af3 100644 --- a/docs/en/docs/advanced/sub-applications.md +++ b/docs/en/docs/advanced/sub-applications.md @@ -1,18 +1,18 @@ -# Sub Applications - Mounts +# Sub Applications - Mounts { #sub-applications-mounts } If you need to have two independent FastAPI applications, with their own independent OpenAPI and their own docs UIs, you can have a main app and "mount" one (or more) sub-application(s). -## Mounting a **FastAPI** application +## Mounting a **FastAPI** application { #mounting-a-fastapi-application } "Mounting" means adding a completely "independent" application in a specific path, that then takes care of handling everything under that path, with the _path operations_ declared in that sub-application. -### Top-level application +### Top-level application { #top-level-application } First, create the main, top-level, **FastAPI** application, and its *path operations*: {* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *} -### Sub-application +### Sub-application { #sub-application } Then, create your sub-application, and its *path operations*. @@ -20,7 +20,7 @@ This sub-application is just another standard FastAPI application, but this is t {* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *} -### Mount the sub-application +### Mount the sub-application { #mount-the-sub-application } In your top-level application, `app`, mount the sub-application, `subapi`. @@ -28,7 +28,7 @@ In this case, it will be mounted at the path `/subapi`: {* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *} -### Check the automatic API docs +### Check the automatic API docs { #check-the-automatic-api-docs } Now, run the `fastapi` command with your file: @@ -56,7 +56,7 @@ You will see the automatic API docs for the sub-application, including only its If you try interacting with any of the two user interfaces, they will work correctly, because the browser will be able to talk to each specific app or sub-app. -### Technical Details: `root_path` +### Technical Details: `root_path` { #technical-details-root-path } When you mount a sub-application as described above, FastAPI will take care of communicating the mount path for the sub-application using a mechanism from the ASGI specification called a `root_path`. diff --git a/docs/en/docs/advanced/templates.md b/docs/en/docs/advanced/templates.md index d9b0ca6f1..f41c47fe8 100644 --- a/docs/en/docs/advanced/templates.md +++ b/docs/en/docs/advanced/templates.md @@ -1,4 +1,4 @@ -# Templates +# Templates { #templates } You can use any template engine you want with **FastAPI**. @@ -6,7 +6,7 @@ A common choice is Jinja2, the same one used by Flask and other tools. There are utilities to configure it easily that you can use directly in your **FastAPI** application (provided by Starlette). -## Install dependencies +## Install dependencies { #install-dependencies } Make sure you create a [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and install `jinja2`: @@ -20,7 +20,7 @@ $ pip install jinja2
-## Using `Jinja2Templates` +## Using `Jinja2Templates` { #using-jinja2templates } * Import `Jinja2Templates`. * Create a `templates` object that you can reuse later. @@ -51,7 +51,7 @@ You could also use `from starlette.templating import Jinja2Templates`. /// -## Writing templates +## Writing templates { #writing-templates } Then you can write a template at `templates/item.html` with, for example: @@ -59,7 +59,7 @@ Then you can write a template at `templates/item.html` with, for example: {!../../docs_src/templates/templates/item.html!} ``` -### Template Context Values +### Template Context Values { #template-context-values } In the HTML that contains: @@ -83,7 +83,7 @@ For example, with an ID of `42`, this would render: Item ID: 42 ``` -### Template `url_for` Arguments +### Template `url_for` Arguments { #template-url-for-arguments } You can also use `url_for()` inside of the template, it takes as arguments the same arguments that would be used by your *path operation function*. @@ -105,7 +105,7 @@ For example, with an ID of `42`, this would render: ``` -## Templates and static files +## Templates and static files { #templates-and-static-files } You can also use `url_for()` inside of the template, and use it, for example, with the `StaticFiles` you mounted with the `name="static"`. @@ -121,6 +121,6 @@ In this example, it would link to a CSS file at `static/styles.css` with: And because you are using `StaticFiles`, that CSS file would be served automatically by your **FastAPI** application at the URL `/static/styles.css`. -## More details +## More details { #more-details } For more details, including how to test templates, check Starlette's docs on templates. diff --git a/docs/en/docs/advanced/testing-dependencies.md b/docs/en/docs/advanced/testing-dependencies.md index 17b4f9814..b52b47c96 100644 --- a/docs/en/docs/advanced/testing-dependencies.md +++ b/docs/en/docs/advanced/testing-dependencies.md @@ -1,6 +1,6 @@ -# Testing Dependencies with Overrides +# Testing Dependencies with Overrides { #testing-dependencies-with-overrides } -## Overriding dependencies during testing +## Overriding dependencies during testing { #overriding-dependencies-during-testing } There are some scenarios where you might want to override a dependency during testing. @@ -8,7 +8,7 @@ You don't want the original dependency to run (nor any of the sub-dependencies i Instead, you want to provide a different dependency that will be used only during tests (possibly only some specific tests), and will provide a value that can be used where the value of the original dependency was used. -### Use cases: external service +### Use cases: external service { #use-cases-external-service } An example could be that you have an external authentication provider that you need to call. @@ -20,7 +20,7 @@ You probably want to test the external provider once, but not necessarily call i In this case, you can override the dependency that calls that provider, and use a custom dependency that returns a mock user, only for your tests. -### Use the `app.dependency_overrides` attribute +### Use the `app.dependency_overrides` attribute { #use-the-app-dependency-overrides-attribute } For these cases, your **FastAPI** application has an attribute `app.dependency_overrides`, it is a simple `dict`. diff --git a/docs/en/docs/advanced/testing-events.md b/docs/en/docs/advanced/testing-events.md index 0c554c4ec..cb8881a09 100644 --- a/docs/en/docs/advanced/testing-events.md +++ b/docs/en/docs/advanced/testing-events.md @@ -1,5 +1,12 @@ -# Testing Events: startup - shutdown +# Testing Events: lifespan and startup - shutdown { #testing-events-lifespan-and-startup-shutdown } -When you need your event handlers (`startup` and `shutdown`) to run in your tests, you can use the `TestClient` with a `with` statement: +When you need `lifespan` to run in your tests, you can use the `TestClient` with a `with` statement: + +{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *} + + +You can read more details about the ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.io/lifespan/#running-lifespan-in-tests) + +For the deprecated `startup` and `shutdown` events, you can use the `TestClient` as follows: {* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *} diff --git a/docs/en/docs/advanced/testing-websockets.md b/docs/en/docs/advanced/testing-websockets.md index 60dfdc343..22f9bb4a0 100644 --- a/docs/en/docs/advanced/testing-websockets.md +++ b/docs/en/docs/advanced/testing-websockets.md @@ -1,4 +1,4 @@ -# Testing WebSockets +# Testing WebSockets { #testing-websockets } You can use the same `TestClient` to test WebSockets. diff --git a/docs/en/docs/advanced/using-request-directly.md b/docs/en/docs/advanced/using-request-directly.md index 2f88c8f20..e412ad462 100644 --- a/docs/en/docs/advanced/using-request-directly.md +++ b/docs/en/docs/advanced/using-request-directly.md @@ -1,4 +1,4 @@ -# Using the Request Directly +# Using the Request Directly { #using-the-request-directly } Up to now, you have been declaring the parts of the request that you need with their types. @@ -13,7 +13,7 @@ And by doing so, **FastAPI** is validating that data, converting it and generati But there are situations where you might need to access the `Request` object directly. -## Details about the `Request` object +## Details about the `Request` object { #details-about-the-request-object } As **FastAPI** is actually **Starlette** underneath, with a layer of several tools on top, you can use Starlette's `Request` object directly when you need to. @@ -23,7 +23,7 @@ Although any other parameter declared normally (for example, the body with a Pyd But there are specific cases where it's useful to get the `Request` object. -## Use the `Request` object directly +## Use the `Request` object directly { #use-the-request-object-directly } Let's imagine you want to get the client's IP address/host inside of your *path operation function*. @@ -43,7 +43,7 @@ The same way, you can declare any other parameter as normally, and additionally, /// -## `Request` documentation +## `Request` documentation { #request-documentation } You can read more details about the `Request` object in the official Starlette documentation site. diff --git a/docs/en/docs/advanced/websockets.md b/docs/en/docs/advanced/websockets.md index ee8e901df..917dd79bd 100644 --- a/docs/en/docs/advanced/websockets.md +++ b/docs/en/docs/advanced/websockets.md @@ -1,10 +1,10 @@ -# WebSockets +# WebSockets { #websockets } You can use WebSockets with **FastAPI**. -## Install `WebSockets` +## Install `websockets` { #install-websockets } -Make sure you create a [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and install `websockets`: +Make sure you create a [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and install `websockets` (a Python library that makes it easy to use the "WebSocket" protocol):
@@ -16,9 +16,9 @@ $ pip install websockets
-## WebSockets client +## WebSockets client { #websockets-client } -### In production +### In production { #in-production } In your production system, you probably have a frontend created with a modern framework like React, Vue.js or Angular. @@ -40,7 +40,7 @@ But it's the simplest way to focus on the server-side of WebSockets and have a w {* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} -## Create a `websocket` +## Create a `websocket` { #create-a-websocket } In your **FastAPI** application, create a `websocket`: @@ -54,7 +54,7 @@ You could also use `from starlette.websockets import WebSocket`. /// -## Await for messages and send messages +## Await for messages and send messages { #await-for-messages-and-send-messages } In your WebSocket route you can `await` for messages and send messages. @@ -62,7 +62,7 @@ In your WebSocket route you can `await` for messages and send messages. You can receive and send binary, text, and JSON data. -## Try it +## Try it { #try-it } If your file is named `main.py`, run your application with: @@ -96,7 +96,7 @@ You can send (and receive) many messages: And all of them will use the same WebSocket connection. -## Using `Depends` and others +## Using `Depends` and others { #using-depends-and-others } In WebSocket endpoints you can import from `fastapi` and use: @@ -119,7 +119,7 @@ You can use a closing code from the -## Handling disconnections and multiple clients +## Handling disconnections and multiple clients { #handling-disconnections-and-multiple-clients } When a WebSocket connection is closed, the `await websocket.receive_text()` will raise a `WebSocketDisconnect` exception, which you can then catch and handle like in this example. @@ -178,7 +178,7 @@ If you need something easy to integrate with FastAPI but that is more robust, su /// -## More info +## More info { #more-info } To learn more about the options, check Starlette's documentation for: diff --git a/docs/en/docs/advanced/wsgi.md b/docs/en/docs/advanced/wsgi.md index 296eb1364..29fd2d359 100644 --- a/docs/en/docs/advanced/wsgi.md +++ b/docs/en/docs/advanced/wsgi.md @@ -1,10 +1,10 @@ -# Including WSGI - Flask, Django, others +# Including WSGI - Flask, Django, others { #including-wsgi-flask-django-others } You can mount WSGI applications as you saw with [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank}. For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI application, for example, Flask, Django, etc. -## Using `WSGIMiddleware` +## Using `WSGIMiddleware` { #using-wsgimiddleware } You need to import `WSGIMiddleware`. @@ -14,7 +14,7 @@ And then mount that under a path. {* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *} -## Check it +## Check it { #check-it } Now, every request under the path `/v1/` will be handled by the Flask application. diff --git a/docs/en/docs/alternatives.md b/docs/en/docs/alternatives.md index 326f0dbe1..f0576bc47 100644 --- a/docs/en/docs/alternatives.md +++ b/docs/en/docs/alternatives.md @@ -1,8 +1,8 @@ -# Alternatives, Inspiration and Comparisons +# Alternatives, Inspiration and Comparisons { #alternatives-inspiration-and-comparisons } What inspired **FastAPI**, how it compares to alternatives and what it learned from them. -## Intro +## Intro { #intro } **FastAPI** wouldn't exist if not for the previous work of others. @@ -12,9 +12,9 @@ I have been avoiding the creation of a new framework for several years. First I But at some point, there was no other option than creating something that provided all these features, taking the best ideas from previous tools, and combining them in the best way possible, using language features that weren't even available before (Python 3.6+ type hints). -## Previous tools +## Previous tools { #previous-tools } -### Django +### Django { #django } It's the most popular Python framework and is widely trusted. It is used to build systems like Instagram. @@ -22,7 +22,7 @@ It's relatively tightly coupled with relational databases (like MySQL or Postgre It was created to generate the HTML in the backend, not to create APIs used by a modern frontend (like React, Vue.js and Angular) or by other systems (like IoT devices) communicating with it. -### Django REST Framework +### Django REST Framework { #django-rest-framework } Django REST framework was created to be a flexible toolkit for building Web APIs using Django underneath, to improve its API capabilities. @@ -42,7 +42,7 @@ Have an automatic API documentation web user interface. /// -### Flask +### Flask { #flask } Flask is a "microframework", it doesn't include database integrations nor many of the things that come by default in Django. @@ -64,7 +64,7 @@ Have a simple and easy to use routing system. /// -### Requests +### Requests { #requests } **FastAPI** is not actually an alternative to **Requests**. Their scope is very different. @@ -106,7 +106,7 @@ See the similarities in `requests.get(...)` and `@app.get(...)`. /// -### Swagger / OpenAPI +### Swagger / OpenAPI { #swagger-openapi } The main feature I wanted from Django REST Framework was the automatic API documentation. @@ -131,11 +131,11 @@ These two were chosen for being fairly popular and stable, but doing a quick sea /// -### Flask REST frameworks +### Flask REST frameworks { #flask-rest-frameworks } There are several Flask REST frameworks, but after investing the time and work into investigating them, I found that many are discontinued or abandoned, with several standing issues that made them unfit. -### Marshmallow +### Marshmallow { #marshmallow } One of the main features needed by API systems is data "serialization" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc. @@ -153,7 +153,7 @@ Use code to define "schemas" that provide data types and validation, automatical /// -### Webargs +### Webargs { #webargs } Another big feature required by APIs is parsing data from incoming requests. @@ -175,7 +175,7 @@ Have automatic validation of incoming request data. /// -### APISpec +### APISpec { #apispec } Marshmallow and Webargs provide validation, parsing and serialization as plug-ins. @@ -205,7 +205,7 @@ Support the open standard for APIs, OpenAPI. /// -### Flask-apispec +### Flask-apispec { #flask-apispec } It's a Flask plug-in, that ties together Webargs, Marshmallow and APISpec. @@ -237,7 +237,7 @@ Generate the OpenAPI schema automatically, from the same code that defines seria /// -### NestJS (and Angular) +### NestJS (and Angular) { #nestjs-and-angular } This isn't even Python, NestJS is a JavaScript (TypeScript) NodeJS framework inspired by Angular. @@ -259,7 +259,7 @@ Have a powerful dependency injection system. Find a way to minimize code repetit /// -### Sanic +### Sanic { #sanic } It was one of the first extremely fast Python frameworks based on `asyncio`. It was made to be very similar to Flask. @@ -279,7 +279,7 @@ That's why **FastAPI** is based on Starlette, as it is the fastest framework ava /// -### Falcon +### Falcon { #falcon } Falcon is another high performance Python framework, it is designed to be minimal, and work as the foundation of other frameworks like Hug. @@ -297,7 +297,7 @@ Although in FastAPI it's optional, and is used mainly to set headers, cookies, a /// -### Molten +### Molten { #molten } I discovered Molten in the first stages of building **FastAPI**. And it has quite similar ideas: @@ -321,7 +321,7 @@ This actually inspired updating parts of Pydantic, to support the same validatio /// -### Hug +### Hug { #hug } Hug was one of the first frameworks to implement the declaration of API parameter types using Python type hints. This was a great idea that inspired other tools to do the same. @@ -351,7 +351,7 @@ Hug inspired **FastAPI** to declare a `response` parameter in functions to set h /// -### APIStar (<= 0.5) +### APIStar (<= 0.5) { #apistar-0-5 } Right before deciding to build **FastAPI** I found **APIStar** server. It had almost everything I was looking for and had a great design. @@ -399,9 +399,9 @@ I consider **FastAPI** a "spiritual successor" to APIStar, while improving and i /// -## Used by **FastAPI** +## Used by **FastAPI** { #used-by-fastapi } -### Pydantic +### Pydantic { #pydantic } Pydantic is a library to define data validation, serialization and documentation (using JSON Schema) based on Python type hints. @@ -417,7 +417,7 @@ Handle all the data validation, data serialization and automatic model documenta /// -### Starlette +### Starlette { #starlette } Starlette is a lightweight ASGI framework/toolkit, which is ideal for building high-performance asyncio services. @@ -462,7 +462,7 @@ So, anything that you can do with Starlette, you can do it directly with **FastA /// -### Uvicorn +### Uvicorn { #uvicorn } Uvicorn is a lightning-fast ASGI server, built on uvloop and httptools. @@ -480,6 +480,6 @@ Check more details in the [Deployment](deployment/index.md){.internal-link targe /// -## Benchmarks and speed +## Benchmarks and speed { #benchmarks-and-speed } To understand, compare, and see the difference between Uvicorn, Starlette and FastAPI, check the section about [Benchmarks](benchmarks.md){.internal-link target=_blank}. diff --git a/docs/en/docs/async.md b/docs/en/docs/async.md index 8207ec480..eac473bde 100644 --- a/docs/en/docs/async.md +++ b/docs/en/docs/async.md @@ -1,8 +1,8 @@ -# Concurrency and async / await +# Concurrency and async / await { #concurrency-and-async-await } Details about the `async def` syntax for *path operation functions* and some background about asynchronous code, concurrency, and parallelism. -## In a hurry? +## In a hurry? { #in-a-hurry } TL;DR: @@ -54,7 +54,7 @@ Anyway, in any of the cases above, FastAPI will still work asynchronously and be But by following the steps above, it will be able to do some performance optimizations. -## Technical Details +## Technical Details { #technical-details } Modern versions of Python have support for **"asynchronous code"** using something called **"coroutines"**, with **`async` and `await`** syntax. @@ -64,7 +64,7 @@ Let's see that phrase by parts in the sections below: * **`async` and `await`** * **Coroutines** -## Asynchronous Code +## Asynchronous Code { #asynchronous-code } Asynchronous code just means that the language đŸ’Ŧ has a way to tell the computer / program 🤖 that at some point in the code, it 🤖 will have to wait for *something else* to finish somewhere else. Let's say that *something else* is called "slow-file" 📝. @@ -93,7 +93,7 @@ Instead of that, by being an "asynchronous" system, once finished, the task can For "synchronous" (contrary to "asynchronous") they commonly also use the term "sequential", because the computer / program follows all the steps in sequence before switching to a different task, even if those steps involve waiting. -### Concurrency and Burgers +### Concurrency and Burgers { #concurrency-and-burgers } This idea of **asynchronous** code described above is also sometimes called **"concurrency"**. It is different from **"parallelism"**. @@ -103,7 +103,7 @@ But the details between *concurrency* and *parallelism* are quite different. To see the difference, imagine the following story about burgers: -### Concurrent Burgers +### Concurrent Burgers { #concurrent-burgers } You go with your crush to get fast food, you stand in line while the cashier takes the orders from the people in front of you. 😍 @@ -163,7 +163,7 @@ So you wait for your crush to finish the story (finish the current work ⏯ / ta Then you go to the counter 🔀, to the initial task that is now finished ⏯, pick the burgers, say thanks and take them to the table. That finishes that step / task of interaction with the counter ⏚. That in turn, creates a new task, of "eating burgers" 🔀 ⏯, but the previous one of "getting burgers" is finished ⏚. -### Parallel Burgers +### Parallel Burgers { #parallel-burgers } Now let's imagine these aren't "Concurrent Burgers", but "Parallel Burgers". @@ -233,7 +233,7 @@ And you have to wait 🕙 in the line for a long time or you lose your turn. You probably wouldn't want to take your crush 😍 with you to run errands at the bank đŸĻ. -### Burger Conclusion +### Burger Conclusion { #burger-conclusion } In this scenario of "fast food burgers with your crush", as there is a lot of waiting 🕙, it makes a lot more sense to have a concurrent system â¸đŸ”€â¯. @@ -253,7 +253,7 @@ And that's the same level of performance you get with **FastAPI**. And as you can have parallelism and asynchronicity at the same time, you get higher performance than most of the tested NodeJS frameworks and on par with Go, which is a compiled language closer to C (all thanks to Starlette). -### Is concurrency better than parallelism? +### Is concurrency better than parallelism? { #is-concurrency-better-than-parallelism } Nope! That's not the moral of the story. @@ -290,7 +290,7 @@ For example: * **Machine Learning**: it normally requires lots of "matrix" and "vector" multiplications. Think of a huge spreadsheet with numbers and multiplying all of them together at the same time. * **Deep Learning**: this is a sub-field of Machine Learning, so, the same applies. It's just that there is not a single spreadsheet of numbers to multiply, but a huge set of them, and in many cases, you use a special processor to build and / or use those models. -### Concurrency + Parallelism: Web + Machine Learning +### Concurrency + Parallelism: Web + Machine Learning { #concurrency-parallelism-web-machine-learning } With **FastAPI** you can take advantage of concurrency that is very common for web development (the same main attraction of NodeJS). @@ -300,7 +300,7 @@ That, plus the simple fact that Python is the main language for **Data Science** To see how to achieve this parallelism in production see the section about [Deployment](deployment/index.md){.internal-link target=_blank}. -## `async` and `await` +## `async` and `await` { #async-and-await } Modern versions of Python have a very intuitive way to define asynchronous code. This makes it look just like normal "sequential" code and do the "awaiting" for you at the right moments. @@ -349,7 +349,7 @@ async def read_burgers(): return burgers ``` -### More technical details +### More technical details { #more-technical-details } You might have noticed that `await` can only be used inside of functions defined with `async def`. @@ -361,7 +361,7 @@ If you are working with **FastAPI** you don't have to worry about that, because But if you want to use `async` / `await` without FastAPI, you can do it as well. -### Write your own async code +### Write your own async code { #write-your-own-async-code } Starlette (and **FastAPI**) are based on AnyIO, which makes it compatible with both Python's standard library asyncio and Trio. @@ -371,7 +371,7 @@ And even if you were not using FastAPI, you could also write your own async appl I created another library on top of AnyIO, as a thin layer on top, to improve a bit the type annotations and get better **autocompletion**, **inline errors**, etc. It also has a friendly introduction and tutorial to help you **understand** and write **your own async code**: Asyncer. It would be particularly useful if you need to **combine async code with regular** (blocking/synchronous) code. -### Other forms of asynchronous code +### Other forms of asynchronous code { #other-forms-of-asynchronous-code } This style of using `async` and `await` is relatively new in the language. @@ -383,15 +383,15 @@ But before that, handling asynchronous code was quite more complex and difficult In previous versions of Python, you could have used threads or Gevent. But the code is way more complex to understand, debug, and think about. -In previous versions of NodeJS / Browser JavaScript, you would have used "callbacks". Which leads to callback hell. +In previous versions of NodeJS / Browser JavaScript, you would have used "callbacks". Which leads to "callback hell". -## Coroutines +## Coroutines { #coroutines } **Coroutine** is just the very fancy term for the thing returned by an `async def` function. Python knows that it is something like a function, that it can start and that it will end at some point, but that it might be paused ⏸ internally too, whenever there is an `await` inside of it. But all this functionality of using asynchronous code with `async` and `await` is many times summarized as using "coroutines". It is comparable to the main key feature of Go, the "Goroutines". -## Conclusion +## Conclusion { #conclusion } Let's see the same phrase from above: @@ -401,7 +401,7 @@ That should make more sense now. ✨ All that is what powers FastAPI (through Starlette) and what makes it have such an impressive performance. -## Very Technical Details +## Very Technical Details { #very-technical-details } /// warning @@ -413,7 +413,7 @@ If you have quite some technical knowledge (coroutines, threads, blocking, etc.) /// -### Path operation functions +### Path operation functions { #path-operation-functions } When you declare a *path operation function* with normal `def` instead of `async def`, it is run in an external threadpool that is then awaited, instead of being called directly (as it would block the server). @@ -421,15 +421,15 @@ If you are coming from another async framework that does not work in the way des Still, in both situations, chances are that **FastAPI** will [still be faster](index.md#performance){.internal-link target=_blank} than (or at least comparable to) your previous framework. -### Dependencies +### Dependencies { #dependencies } The same applies for [dependencies](tutorial/dependencies/index.md){.internal-link target=_blank}. If a dependency is a standard `def` function instead of `async def`, it is run in the external threadpool. -### Sub-dependencies +### Sub-dependencies { #sub-dependencies } You can have multiple dependencies and [sub-dependencies](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} requiring each other (as parameters of the function definitions), some of them might be created with `async def` and some with normal `def`. It would still work, and the ones created with normal `def` would be called on an external thread (from the threadpool) instead of being "awaited". -### Other utility functions +### Other utility functions { #other-utility-functions } Any other utility function that you call directly can be created with normal `def` or `async def` and FastAPI won't affect the way you call it. diff --git a/docs/en/docs/benchmarks.md b/docs/en/docs/benchmarks.md index 62266c449..551f6316d 100644 --- a/docs/en/docs/benchmarks.md +++ b/docs/en/docs/benchmarks.md @@ -1,10 +1,10 @@ -# Benchmarks +# Benchmarks { #benchmarks } Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). But when checking benchmarks and comparisons you should keep the following in mind. -## Benchmarks and speed +## Benchmarks and speed { #benchmarks-and-speed } When you check the benchmarks, it is common to see several tools of different types compared as equivalent. diff --git a/docs/en/docs/contributing.md b/docs/en/docs/contributing.md index 91c39c927..ae99059f4 100644 --- a/docs/en/docs/contributing.md +++ b/docs/en/docs/contributing.md @@ -10,10 +10,12 @@ If you already cloned the
`uv`: + +
+ +```console +$ uv pip install -r requirements.txt + +---> 100% +``` + +
+ +//// + It will install all the dependencies and your local FastAPI in your local environment. ### Using your local FastAPI @@ -315,30 +335,47 @@ Now you can translate it all and see how it looks as you save the file. Some of these files are updated very frequently and a translation would always be behind, or they include the main content from English source files, etc. +#### Request a New Language + +Let's say that you want to request translations for a language that is not yet translated, not even some pages. For example, Latin. + +If there is no discussion for that language, you can start by requesting the new language. For that, you can follow these steps: + +* Create a new discussion following the template. +* Get a few native speakers to comment on the discussion and commit to help review translations for that language. + +Once there are several people in the discussion, the FastAPI team can evaluate it and can make it an official translation. + +Then the docs will be automatically translated using AI, and the team of native speakers can review the translation, and help tweak the AI prompts. + +Once there's a new translation, for example if docs are updated or there's a new section, there will be a comment in the same discussion with the link to the new translation to review. + #### New Language -Let's say that you want to add translations for a language that is not yet translated, not even some pages. +/// note -Let's say you want to add translations for Creole, and it's not yet there in the docs. +These steps will be performed by the FastAPI team. -Checking the link from above, the code for "Creole" is `ht`. +/// -The next step is to run the script to generate a new translation directory: +Checking the link from above (List of ISO 639-1 codes), you can see that the 2-letter code for Latin is `la`. + +Now you can create a new directory for the new language, running the following script:
```console // Use the command new-lang, pass the language code as a CLI argument -$ python ./scripts/docs.py new-lang ht +$ python ./scripts/docs.py new-lang la -Successfully initialized: docs/ht +Successfully initialized: docs/la ```
-Now you can check in your code editor the newly created directory `docs/ht/`. +Now you can check in your code editor the newly created directory `docs/la/`. -That command created a file `docs/ht/mkdocs.yml` with a simple config that inherits everything from the `en` version: +That command created a file `docs/la/mkdocs.yml` with a simple config that inherits everything from the `en` version: ```yaml INHERIT: ../en/mkdocs.yml @@ -350,11 +387,11 @@ You could also simply create that file with those contents manually. /// -That command also created a dummy file `docs/ht/index.md` for the main page, you can start by translating that one. +That command also created a dummy file `docs/la/index.md` for the main page, you can start by translating that one. You can continue with the previous instructions for an "Existing Language" for that process. -You can make the first pull request with those two files, `docs/ht/mkdocs.yml` and `docs/ht/index.md`. 🎉 +You can make the first pull request with those two files, `docs/la/mkdocs.yml` and `docs/la/index.md`. 🎉 #### Preview the result diff --git a/docs/en/docs/css/custom.css b/docs/en/docs/css/custom.css index b192f6123..a38df772f 100644 --- a/docs/en/docs/css/custom.css +++ b/docs/en/docs/css/custom.css @@ -102,7 +102,15 @@ a.announce-link:hover { align-items: center; } -.announce-wrapper div.item { +.announce-wrapper #announce-left div.item { + display: none; +} + +.announce-wrapper #announce-right { + display: none; +} + +.announce-wrapper #announce-right div.item { display: none; } @@ -112,7 +120,7 @@ a.announce-link:hover { top: -10px; right: 0; font-size: 0.5rem; - color: #999; + color: #e6e6e6; background-color: #666; border-radius: 10px; padding: 0 10px; diff --git a/docs/en/docs/deployment/cloud.md b/docs/en/docs/deployment/cloud.md index d713379c3..c88c4b51a 100644 --- a/docs/en/docs/deployment/cloud.md +++ b/docs/en/docs/deployment/cloud.md @@ -1,10 +1,10 @@ -# Deploy FastAPI on Cloud Providers +# Deploy FastAPI on Cloud Providers { #deploy-fastapi-on-cloud-providers } You can use virtually **any cloud provider** to deploy your FastAPI application. In most of the cases, the main cloud providers have guides to deploy FastAPI with them. -## Cloud Providers - Sponsors +## Cloud Providers - Sponsors { #cloud-providers-sponsors } Some cloud providers ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**. @@ -12,6 +12,5 @@ And it shows their true commitment to FastAPI and its **community** (you), as th You might want to try their services and follow their guides: -* Platform.sh -* Porter * Render +* Railway diff --git a/docs/en/docs/deployment/concepts.md b/docs/en/docs/deployment/concepts.md index ed635a920..2174443f0 100644 --- a/docs/en/docs/deployment/concepts.md +++ b/docs/en/docs/deployment/concepts.md @@ -1,4 +1,4 @@ -# Deployments Concepts +# Deployments Concepts { #deployments-concepts } When deploying a **FastAPI** application, or actually, any type of web API, there are several concepts that you probably care about, and using them you can find the **most appropriate** way to **deploy your application**. @@ -23,7 +23,7 @@ In the next chapters, I'll give you more **concrete recipes** to deploy FastAPI But for now, let's check these important **conceptual ideas**. These concepts also apply to any other type of web API. 💡 -## Security - HTTPS +## Security - HTTPS { #security-https } In the [previous chapter about HTTPS](https.md){.internal-link target=_blank} we learned about how HTTPS provides encryption for your API. @@ -31,7 +31,7 @@ We also saw that HTTPS is normally provided by a component **external** to your And there has to be something in charge of **renewing the HTTPS certificates**, it could be the same component or it could be something different. -### Example Tools for HTTPS +### Example Tools for HTTPS { #example-tools-for-https } Some of the tools you could use as a TLS Termination Proxy are: @@ -55,11 +55,11 @@ I'll show you some concrete examples in the next chapters. Then the next concepts to consider are all about the program running your actual API (e.g. Uvicorn). -## Program and Process +## Program and Process { #program-and-process } We will talk a lot about the running "**process**", so it's useful to have clarity about what it means, and what's the difference with the word "**program**". -### What is a Program +### What is a Program { #what-is-a-program } The word **program** is commonly used to describe many things: @@ -67,7 +67,7 @@ The word **program** is commonly used to describe many things: * The **file** that can be **executed** by the operating system, for example: `python`, `python.exe` or `uvicorn`. * A particular program while it is **running** on the operating system, using the CPU, and storing things in memory. This is also called a **process**. -### What is a Process +### What is a Process { #what-is-a-process } The word **process** is normally used in a more specific way, only referring to the thing that is running in the operating system (like in the last point above): @@ -88,11 +88,11 @@ And, for example, you will probably see that there are multiple processes runnin Now that we know the difference between the terms **process** and **program**, let's continue talking about deployments. -## Running on Startup +## Running on Startup { #running-on-startup } In most cases, when you create a web API, you want it to be **always running**, uninterrupted, so that your clients can always access it. This is of course, unless you have a specific reason why you want it to run only in certain situations, but most of the time you want it constantly running and **available**. -### In a Remote Server +### In a Remote Server { #in-a-remote-server } When you set up a remote server (a cloud server, a virtual machine, etc.) the simplest thing you can do is use `fastapi run` (which uses Uvicorn) or something similar, manually, the same way you do when developing locally. @@ -102,15 +102,15 @@ But if your connection to the server is lost, the **running process** will proba And if the server is restarted (for example after updates, or migrations from the cloud provider) you probably **won't notice it**. And because of that, you won't even know that you have to restart the process manually. So, your API will just stay dead. 😱 -### Run Automatically on Startup +### Run Automatically on Startup { #run-automatically-on-startup } In general, you will probably want the server program (e.g. Uvicorn) to be started automatically on server startup, and without needing any **human intervention**, to have a process always running with your API (e.g. Uvicorn running your FastAPI app). -### Separate Program +### Separate Program { #separate-program } To achieve this, you will normally have a **separate program** that would make sure your application is run on startup. And in many cases, it would also make sure other components or applications are also run, for example, a database. -### Example Tools to Run at Startup +### Example Tools to Run at Startup { #example-tools-to-run-at-startup } Some examples of the tools that can do this job are: @@ -125,29 +125,29 @@ Some examples of the tools that can do this job are: I'll give you more concrete examples in the next chapters. -## Restarts +## Restarts { #restarts } Similar to making sure your application is run on startup, you probably also want to make sure it is **restarted** after failures. -### We Make Mistakes +### We Make Mistakes { #we-make-mistakes } We, as humans, make **mistakes**, all the time. Software almost *always* has **bugs** hidden in different places. 🐛 And we as developers keep improving the code as we find those bugs and as we implement new features (possibly adding new bugs too 😅). -### Small Errors Automatically Handled +### Small Errors Automatically Handled { #small-errors-automatically-handled } When building web APIs with FastAPI, if there's an error in our code, FastAPI will normally contain it to the single request that triggered the error. 🛡 The client will get a **500 Internal Server Error** for that request, but the application will continue working for the next requests instead of just crashing completely. -### Bigger Errors - Crashes +### Bigger Errors - Crashes { #bigger-errors-crashes } Nevertheless, there might be cases where we write some code that **crashes the entire application** making Uvicorn and Python crash. đŸ’Ĩ And still, you would probably not want the application to stay dead because there was an error in one place, you probably want it to **continue running** at least for the *path operations* that are not broken. -### Restart After Crash +### Restart After Crash { #restart-after-crash } But in those cases with really bad errors that crash the running **process**, you would want an external component that is in charge of **restarting** the process, at least a couple of times... @@ -161,7 +161,7 @@ So let's focus on the main cases, where it could crash entirely in some particul You would probably want to have the thing in charge of restarting your application as an **external component**, because by that point, the same application with Uvicorn and Python already crashed, so there's nothing in the same code of the same app that could do anything about it. -### Example Tools to Restart Automatically +### Example Tools to Restart Automatically { #example-tools-to-restart-automatically } In most cases, the same tool that is used to **run the program on startup** is also used to handle automatic **restarts**. @@ -176,19 +176,19 @@ For example, this could be handled by: * Handled internally by a cloud provider as part of their services * Others... -## Replication - Processes and Memory +## Replication - Processes and Memory { #replication-processes-and-memory } With a FastAPI application, using a server program like the `fastapi` command that runs Uvicorn, running it once in **one process** can serve multiple clients concurrently. But in many cases, you will want to run several worker processes at the same time. -### Multiple Processes - Workers +### Multiple Processes - Workers { #multiple-processes-workers } If you have more clients than what a single process can handle (for example if the virtual machine is not too big) and you have **multiple cores** in the server's CPU, then you could have **multiple processes** running with the same application at the same time, and distribute all the requests among them. When you run **multiple processes** of the same API program, they are commonly called **workers**. -### Worker Processes and Ports +### Worker Processes and Ports { #worker-processes-and-ports } Remember from the docs [About HTTPS](https.md){.internal-link target=_blank} that only one process can be listening on one combination of port and IP address in a server? @@ -196,19 +196,19 @@ This is still true. So, to be able to have **multiple processes** at the same time, there has to be a **single process listening on a port** that then transmits the communication to each worker process in some way. -### Memory per Process +### Memory per Process { #memory-per-process } Now, when the program loads things in memory, for example, a machine learning model in a variable, or the contents of a large file in a variable, all that **consumes a bit of the memory (RAM)** of the server. And multiple processes normally **don't share any memory**. This means that each running process has its own things, variables, and memory. And if you are consuming a large amount of memory in your code, **each process** will consume an equivalent amount of memory. -### Server Memory +### Server Memory { #server-memory } For example, if your code loads a Machine Learning model with **1 GB in size**, when you run one process with your API, it will consume at least 1 GB of RAM. And if you start **4 processes** (4 workers), each will consume 1 GB of RAM. So in total, your API will consume **4 GB of RAM**. And if your remote server or virtual machine only has 3 GB of RAM, trying to load more than 4 GB of RAM will cause problems. 🚨 -### Multiple Processes - An Example +### Multiple Processes - An Example { #multiple-processes-an-example } In this example, there's a **Manager Process** that starts and controls two **Worker Processes**. @@ -224,7 +224,7 @@ An interesting detail is that the percentage of the **CPU used** by each process If you have an API that does a comparable amount of computations every time and you have a lot of clients, then the **CPU utilization** will probably *also be stable* (instead of constantly going up and down quickly). -### Examples of Replication Tools and Strategies +### Examples of Replication Tools and Strategies { #examples-of-replication-tools-and-strategies } There can be several approaches to achieve this, and I'll tell you more about specific strategies in the next chapters, for example when talking about Docker and containers. @@ -247,7 +247,7 @@ I'll tell you more about container images, Docker, Kubernetes, etc. in a future /// -## Previous Steps Before Starting +## Previous Steps Before Starting { #previous-steps-before-starting } There are many cases where you want to perform some steps **before starting** your application. @@ -269,7 +269,7 @@ In that case, you wouldn't have to worry about any of this. 🤷 /// -### Examples of Previous Steps Strategies +### Examples of Previous Steps Strategies { #examples-of-previous-steps-strategies } This will **depend heavily** on the way you **deploy your system**, and it would probably be connected to the way you start programs, handling restarts, etc. @@ -285,7 +285,7 @@ I'll give you more concrete examples for doing this with containers in a future /// -## Resource Utilization +## Resource Utilization { #resource-utilization } Your server(s) is (are) a **resource**, you can consume or **utilize**, with your programs, the computation time on the CPUs, and the RAM memory available. @@ -305,7 +305,7 @@ You could put an **arbitrary number** to target, for example, something **betwee You can use simple tools like `htop` to see the CPU and RAM used in your server or the amount used by each process. Or you can use more complex monitoring tools, which may be distributed across servers, etc. -## Recap +## Recap { #recap } You have been reading here some of the main concepts that you would probably need to keep in mind when deciding how to deploy your application: diff --git a/docs/en/docs/deployment/docker.md b/docs/en/docs/deployment/docker.md index b106f7ac3..6b71f7360 100644 --- a/docs/en/docs/deployment/docker.md +++ b/docs/en/docs/deployment/docker.md @@ -1,4 +1,4 @@ -# FastAPI in Containers - Docker +# FastAPI in Containers - Docker { #fastapi-in-containers-docker } When deploying FastAPI applications a common approach is to build a **Linux container image**. It's normally done using **Docker**. You can then deploy that container image in one of a few possible ways. @@ -32,7 +32,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"] -## What is a Container +## What is a Container { #what-is-a-container } Containers (mainly Linux containers) are a very **lightweight** way to package applications including all their dependencies and necessary files while keeping them isolated from other containers (other applications or components) in the same system. @@ -42,7 +42,7 @@ This way, containers consume **little resources**, an amount comparable to runni Containers also have their own **isolated** running processes (commonly just one process), file system, and network, simplifying deployment, security, development, etc. -## What is a Container Image +## What is a Container Image { #what-is-a-container-image } A **container** is run from a **container image**. @@ -56,7 +56,7 @@ A container image is comparable to the **program** file and contents, e.g. `pyth And the **container** itself (in contrast to the **container image**) is the actual running instance of the image, comparable to a **process**. In fact, a container is running only when it has a **process running** (and normally it's only a single process). The container stops when there's no process running in it. -## Container Images +## Container Images { #container-images } Docker has been one of the main tools to create and manage **container images** and **containers**. @@ -79,7 +79,7 @@ So, you would run **multiple containers** with different things, like a database All the container management systems (like Docker or Kubernetes) have these networking features integrated into them. -## Containers and Processes +## Containers and Processes { #containers-and-processes } A **container image** normally includes in its metadata the default program or command that should be run when the **container** is started and the parameters to be passed to that program. Very similar to what would be if it was in the command line. @@ -91,7 +91,7 @@ A container normally has a **single process**, but it's also possible to start s But it's not possible to have a running container without **at least one running process**. If the main process stops, the container stops. -## Build a Docker Image for FastAPI +## Build a Docker Image for FastAPI { #build-a-docker-image-for-fastapi } Okay, let's build something now! 🚀 @@ -103,7 +103,7 @@ This is what you would want to do in **most cases**, for example: * When running on a **Raspberry Pi** * Using a cloud service that would run a container image for you, etc. -### Package Requirements +### Package Requirements { #package-requirements } You would normally have the **package requirements** for your application in some file. @@ -138,7 +138,7 @@ There are other formats and tools to define and install package dependencies. /// -### Create the **FastAPI** Code +### Create the **FastAPI** Code { #create-the-fastapi-code } * Create an `app` directory and enter it. * Create an empty file `__init__.py`. @@ -162,7 +162,7 @@ def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` -### Dockerfile +### Dockerfile { #dockerfile } Now in the same project directory create a file `Dockerfile` with: @@ -238,7 +238,7 @@ Make sure to **always** use the **exec form** of the `CMD` instruction, as expla /// -#### Use `CMD` - Exec Form +#### Use `CMD` - Exec Form { #use-cmd-exec-form } The `CMD` Docker instruction can be written using two forms: @@ -262,7 +262,7 @@ You can read more about it in the Why do my services take 10 seconds to recreate or stop?. -#### Directory Structure +#### Directory Structure { #directory-structure } You should now have a directory structure like: @@ -275,7 +275,7 @@ You should now have a directory structure like: └── requirements.txt ``` -#### Behind a TLS Termination Proxy +#### Behind a TLS Termination Proxy { #behind-a-tls-termination-proxy } If you are running your container behind a TLS Termination Proxy (load balancer) like Nginx or Traefik, add the option `--proxy-headers`, this will tell Uvicorn (through the FastAPI CLI) to trust the headers sent by that proxy telling it that the application is running behind HTTPS, etc. @@ -283,7 +283,7 @@ If you are running your container behind a TLS Termination Proxy (load balancer) CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"] ``` -#### Docker Cache +#### Docker Cache { #docker-cache } There's an important trick in this `Dockerfile`, we first copy the **file with the dependencies alone**, not the rest of the code. Let me tell you why is that. @@ -315,7 +315,7 @@ Then, near the end of the `Dockerfile`, we copy all the code. As this is what ** COPY ./app /code/app ``` -### Build the Docker Image +### Build the Docker Image { #build-the-docker-image } Now that all the files are in place, let's build the container image. @@ -340,7 +340,7 @@ In this case, it's the same current directory (`.`). /// -### Start the Docker Container +### Start the Docker Container { #start-the-docker-container } * Run a container based on your image: @@ -352,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
-## Check it +## Check it { #check-it } You should be able to check it in your Docker container's URL, for example: http://192.168.99.100/items/5?q=somequery or http://127.0.0.1/items/5?q=somequery (or equivalent, using your Docker host). @@ -362,7 +362,7 @@ You will see something like: {"item_id": 5, "q": "somequery"} ``` -## Interactive API docs +## Interactive API docs { #interactive-api-docs } Now you can go to http://192.168.99.100/docs or http://127.0.0.1/docs (or equivalent, using your Docker host). @@ -370,7 +370,7 @@ You will see the automatic interactive API documentation (provided by http://192.168.99.100/redoc or http://127.0.0.1/redoc (or equivalent, using your Docker host). @@ -378,7 +378,7 @@ You will see the alternative automatic documentation (provided by cluster of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container. @@ -462,7 +462,7 @@ One of those distributed container management systems like Kubernetes normally h In those cases, you would probably want to build a **Docker image from scratch** as [explained above](#dockerfile), installing your dependencies, and running **a single Uvicorn process** instead of using multiple Uvicorn workers. -### Load Balancer +### Load Balancer { #load-balancer } When using containers, you would normally have some component **listening on the main port**. It could possibly be another container that is also a **TLS Termination Proxy** to handle **HTTPS** or some similar tool. @@ -476,7 +476,7 @@ The same **TLS Termination Proxy** component used for HTTPS would probably also And when working with containers, the same system you use to start and manage them would already have internal tools to transmit the **network communication** (e.g. HTTP requests) from that **load balancer** (that could also be a **TLS Termination Proxy**) to the container(s) with your app. -### One Load Balancer - Multiple Worker Containers +### One Load Balancer - Multiple Worker Containers { #one-load-balancer-multiple-worker-containers } When working with **Kubernetes** or similar distributed container management systems, using their internal networking mechanisms would allow the single **load balancer** that is listening on the main **port** to transmit communication (requests) to possibly **multiple containers** running your app. @@ -486,15 +486,15 @@ And the distributed container system with the **load balancer** would **distribu And normally this **load balancer** would be able to handle requests that go to *other* apps in your cluster (e.g. to a different domain, or under a different URL path prefix), and would transmit that communication to the right containers for *that other* application running in your cluster. -### One Process per Container +### One Process per Container { #one-process-per-container } In this type of scenario, you probably would want to have **a single (Uvicorn) process per container**, as you would already be handling replication at the cluster level. -So, in this case, you **would not** want to have a multiple workers in the container, for example with the `--workers` command line option.You would want to have just a **single Uvicorn process** per container (but probably multiple containers). +So, in this case, you **would not** want to have a multiple workers in the container, for example with the `--workers` command line option. You would want to have just a **single Uvicorn process** per container (but probably multiple containers). Having another process manager inside the container (as would be with multiple workers) would only add **unnecessary complexity** that you are most probably already taking care of with your cluster system. -### Containers with Multiple Processes and Special Cases +### Containers with Multiple Processes and Special Cases { #containers-with-multiple-processes-and-special-cases } Of course, there are **special cases** where you could want to have **a container** with several **Uvicorn worker processes** inside. @@ -519,11 +519,11 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"] Here are some examples of when that could make sense: -#### A Simple App +#### A Simple App { #a-simple-app } You could want a process manager in the container if your application is **simple enough** that can run it on a **single server**, not a cluster. -#### Docker Compose +#### Docker Compose { #docker-compose } You could be deploying to a **single server** (not a cluster) with **Docker Compose**, so you wouldn't have an easy way to manage replication of containers (with Docker Compose) while preserving the shared network and **load balancing**. @@ -540,7 +540,7 @@ The main point is, **none** of these are **rules written in stone** that you hav * Memory * Previous steps before starting -## Memory +## Memory { #memory } If you run **a single process per container** you will have a more or less well-defined, stable, and limited amount of memory consumed by each of those containers (more than one if they are replicated). @@ -550,11 +550,11 @@ If your application is **simple**, this will probably **not be a problem**, and If you run **multiple processes per container** you will have to make sure that the number of processes started doesn't **consume more memory** than what is available. -## Previous Steps Before Starting and Containers +## Previous Steps Before Starting and Containers { #previous-steps-before-starting-and-containers } If you are using containers (e.g. Docker, Kubernetes), then there are two main approaches you can use. -### Multiple Containers +### Multiple Containers { #multiple-containers } If you have **multiple containers**, probably each one running a **single process** (for example, in a **Kubernetes** cluster), then you would probably want to have a **separate container** doing the work of the **previous steps** in a single container, running a single process, **before** running the replicated worker containers. @@ -566,11 +566,11 @@ If you are using Kubernetes, this would probably be an tiangolo/uvicorn-gunicorn-fastapi. But it is now deprecated. â›”ī¸ @@ -588,7 +588,7 @@ But now that Uvicorn (and the `fastapi` command) support using `--workers`, ther /// -## Deploy the Container Image +## Deploy the Container Image { #deploy-the-container-image } After having a Container (Docker) Image there are several ways to deploy it. @@ -600,11 +600,11 @@ For example: * With another tool like Nomad * With a cloud service that takes your container image and deploys it -## Docker Image with `uv` +## Docker Image with `uv` { #docker-image-with-uv } If you are using uv to install and manage your project, you can follow their uv Docker guide. -## Recap +## Recap { #recap } Using container systems (e.g. with **Docker** and **Kubernetes**) it becomes fairly straightforward to handle all the **deployment concepts**: diff --git a/docs/en/docs/deployment/https.md b/docs/en/docs/deployment/https.md index 8b4a08dbe..a249a3672 100644 --- a/docs/en/docs/deployment/https.md +++ b/docs/en/docs/deployment/https.md @@ -1,4 +1,4 @@ -# About HTTPS +# About HTTPS { #about-https } It is easy to assume that HTTPS is something that is just "enabled" or not. @@ -43,7 +43,7 @@ Some of the options you could use as a TLS Termination Proxy are: * Nginx * HAProxy -## Let's Encrypt +## Let's Encrypt { #lets-encrypt } Before Let's Encrypt, these **HTTPS certificates** were sold by trusted third parties. @@ -57,11 +57,11 @@ The domains are securely verified and the certificates are generated automatical The idea is to automate the acquisition and renewal of these certificates so that you can have **secure HTTPS, for free, forever**. -## HTTPS for Developers +## HTTPS for Developers { #https-for-developers } Here's an example of how an HTTPS API could look like, step by step, paying attention mainly to the ideas important for developers. -### Domain Name +### Domain Name { #domain-name } It would probably all start by you **acquiring** some **domain name**. Then, you would configure it in a DNS server (possibly your same cloud provider). @@ -77,7 +77,7 @@ This Domain Name part is way before HTTPS, but as everything depends on the doma /// -### DNS +### DNS { #dns } Now let's focus on all the actual HTTPS parts. @@ -87,7 +87,7 @@ The DNS servers would tell the browser to use some specific **IP address**. That -### TLS Handshake Start +### TLS Handshake Start { #tls-handshake-start } The browser would then communicate with that IP address on **port 443** (the HTTPS port). @@ -97,7 +97,7 @@ The first part of the communication is just to establish the connection between This interaction between the client and the server to establish the TLS connection is called the **TLS handshake**. -### TLS with SNI Extension +### TLS with SNI Extension { #tls-with-sni-extension } **Only one process** in the server can be listening on a specific **port** in a specific **IP address**. There could be other processes listening on other ports in the same IP address, but only one for each combination of IP address and port. @@ -127,7 +127,7 @@ Notice that the encryption of the communication happens at the **TCP level**, no /// -### HTTPS Request +### HTTPS Request { #https-request } Now that the client and server (specifically the browser and the TLS Termination Proxy) have an **encrypted TCP connection**, they can start the **HTTP communication**. @@ -135,19 +135,19 @@ So, the client sends an **HTTPS request**. This is just an HTTP request through -### Decrypt the Request +### Decrypt the Request { #decrypt-the-request } The TLS Termination Proxy would use the encryption agreed to **decrypt the request**, and would transmit the **plain (decrypted) HTTP request** to the process running the application (for example a process with Uvicorn running the FastAPI application). -### HTTP Response +### HTTP Response { #http-response } The application would process the request and send a **plain (unencrypted) HTTP response** to the TLS Termination Proxy. -### HTTPS Response +### HTTPS Response { #https-response } The TLS Termination Proxy would then **encrypt the response** using the cryptography agreed before (that started with the certificate for `someapp.example.com`), and send it back to the browser. @@ -157,7 +157,7 @@ Next, the browser would verify that the response is valid and encrypted with the The client (browser) will know that the response comes from the correct server because it is using the cryptography they agreed using the **HTTPS certificate** before. -### Multiple Applications +### Multiple Applications { #multiple-applications } In the same server (or servers), there could be **multiple applications**, for example, other API programs or a database. @@ -167,7 +167,7 @@ Only one process can be handling the specific IP and port (the TLS Termination P That way, the TLS Termination Proxy could handle HTTPS and certificates for **multiple domains**, for multiple applications, and then transmit the requests to the right application in each case. -### Certificate Renewal +### Certificate Renewal { #certificate-renewal } At some point in the future, each certificate would **expire** (about 3 months after acquiring it). @@ -190,7 +190,39 @@ To do that, and to accommodate different application needs, there are several wa All this renewal process, while still serving the app, is one of the main reasons why you would want to have a **separate system to handle HTTPS** with a TLS Termination Proxy instead of just using the TLS certificates with the application server directly (e.g. Uvicorn). -## Recap +## Proxy Forwarded Headers { #proxy-forwarded-headers } + +When using a proxy to handle HTTPS, your **application server** (for example Uvicorn via FastAPI CLI) doesn't known anything about the HTTPS process, it communicates with plain HTTP with the **TLS Termination Proxy**. + +This **proxy** would normally set some HTTP headers on the fly before transmitting the request to the **application server**, to let the application server know that the request is being **forwarded** by the proxy. + +/// note | Technical Details + +The proxy headers are: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +Nevertheless, as the **application server** doesn't know it is behind a trusted **proxy**, by default, it wouldn't trust those headers. + +But you can configure the **application server** to trust the *forwarded* headers sent by the **proxy**. If you are using FastAPI CLI, you can use the *CLI Option* `--forwarded-allow-ips` to tell it from which IPs it should trust those *forwarded* headers. + +For example, if the **application server** is only receiving communication from the trusted **proxy**, you can set it to `--forwarded-allow-ips="*"` to make it trust all incoming IPs, as it will only receive requests from whatever is the IP used by the **proxy**. + +This way the application would be able to know what is its own public URL, if it is using HTTPS, the domain, etc. + +This would be useful for example to properly handle redirects. + +/// tip + +You can learn more about this in the documentation for [Behind a Proxy - Enable Proxy Forwarded Headers](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} + +/// + +## Recap { #recap } Having **HTTPS** is very important, and quite **critical** in most cases. Most of the effort you as a developer have to put around HTTPS is just about **understanding these concepts** and how they work. diff --git a/docs/en/docs/deployment/index.md b/docs/en/docs/deployment/index.md index b43bd050a..2364791a7 100644 --- a/docs/en/docs/deployment/index.md +++ b/docs/en/docs/deployment/index.md @@ -1,8 +1,8 @@ -# Deployment +# Deployment { #deployment } Deploying a **FastAPI** application is relatively easy. -## What Does Deployment Mean +## What Does Deployment Mean { #what-does-deployment-mean } To **deploy** an application means to perform the necessary steps to make it **available to the users**. @@ -10,7 +10,7 @@ For a **web API**, it normally involves putting it in a **remote machine**, with This is in contrast to the **development** stages, where you are constantly changing the code, breaking it and fixing it, stopping and restarting the development server, etc. -## Deployment Strategies +## Deployment Strategies { #deployment-strategies } There are several ways to do it depending on your specific use case and the tools that you use. diff --git a/docs/en/docs/deployment/manually.md b/docs/en/docs/deployment/manually.md index 19ba98075..8bb3945bc 100644 --- a/docs/en/docs/deployment/manually.md +++ b/docs/en/docs/deployment/manually.md @@ -1,6 +1,6 @@ -# Run a Server Manually +# Run a Server Manually { #run-a-server-manually } -## Use the `fastapi run` Command +## Use the `fastapi run` Command { #use-the-fastapi-run-command } In short, use `fastapi run` to serve your FastAPI application: @@ -42,7 +42,7 @@ That would work for most of the cases. 😎 You could use that command for example to start your **FastAPI** app in a container, in a server, etc. -## ASGI Servers +## ASGI Servers { #asgi-servers } Let's go a little deeper into the details. @@ -58,7 +58,7 @@ There are several alternatives, including: * Granian: A Rust HTTP server for Python applications. * NGINX Unit: NGINX Unit is a lightweight and versatile web application runtime. -## Server Machine and Server Program +## Server Machine and Server Program { #server-machine-and-server-program } There's a small detail about names to keep in mind. 💡 @@ -68,7 +68,7 @@ Just keep in mind that when you read "server" in general, it could refer to one When referring to the remote machine, it's common to call it **server**, but also **machine**, **VM** (virtual machine), **node**. Those all refer to some type of remote machine, normally running Linux, where you run programs. -## Install the Server Program +## Install the Server Program { #install-the-server-program } When you install FastAPI, it comes with a production server, Uvicorn, and you can start it with the `fastapi run` command. @@ -100,7 +100,7 @@ When you install FastAPI with something like `pip install "fastapi[standard]"` y /// -## Run the Server Program +## Run the Server Program { #run-the-server-program } If you installed an ASGI server manually, you would normally need to pass an import string in a special format for it to import your FastAPI application: @@ -141,7 +141,7 @@ It helps a lot during **development**, but you **shouldn't** use it in **product /// -## Deployment Concepts +## Deployment Concepts { #deployment-concepts } These examples run the server program (e.g Uvicorn), starting **a single process**, listening on all the IPs (`0.0.0.0`) on a predefined port (e.g. `80`). diff --git a/docs/en/docs/deployment/server-workers.md b/docs/en/docs/deployment/server-workers.md index 5d6b0d00a..0351e8b5e 100644 --- a/docs/en/docs/deployment/server-workers.md +++ b/docs/en/docs/deployment/server-workers.md @@ -1,4 +1,4 @@ -# Server Workers - Uvicorn with Workers +# Server Workers - Uvicorn with Workers { #server-workers-uvicorn-with-workers } Let's check back those deployment concepts from before: @@ -25,7 +25,7 @@ In particular, when running on **Kubernetes** you will probably **not** want to /// -## Multiple Workers +## Multiple Workers { #multiple-workers } You can start multiple workers with the `--workers` command line option: @@ -111,7 +111,7 @@ The only new option here is `--workers` telling Uvicorn to start 4 worker proces You can also see that it shows the **PID** of each process, `27365` for the parent process (this is the **process manager**) and one for each worker process: `27368`, `27369`, `27370`, and `27367`. -## Deployment Concepts +## Deployment Concepts { #deployment-concepts } Here you saw how to use multiple **workers** to **parallelize** the execution of the application, take advantage of **multiple cores** in the CPU, and be able to serve **more requests**. @@ -124,13 +124,13 @@ From the list of deployment concepts from above, using workers would mainly help * **Memory** * **Previous steps before starting** -## Containers and Docker +## Containers and Docker { #containers-and-docker } In the next chapter about [FastAPI in Containers - Docker](docker.md){.internal-link target=_blank} I'll explain some strategies you could use to handle the other **deployment concepts**. I'll show you how to **build your own image from scratch** to run a single Uvicorn process. It is a simple process and is probably what you would want to do when using a distributed container management system like **Kubernetes**. -## Recap +## Recap { #recap } You can use multiple worker processes with the `--workers` CLI option with the `fastapi` or `uvicorn` commands to take advantage of **multi-core CPUs**, to run **multiple processes in parallel**. diff --git a/docs/en/docs/deployment/versions.md b/docs/en/docs/deployment/versions.md index 23f49cf99..15b449184 100644 --- a/docs/en/docs/deployment/versions.md +++ b/docs/en/docs/deployment/versions.md @@ -1,4 +1,4 @@ -# About FastAPI versions +# About FastAPI versions { #about-fastapi-versions } **FastAPI** is already being used in production in many applications and systems. And the test coverage is kept at 100%. But its development is still moving quickly. @@ -8,7 +8,7 @@ That's why the current versions are still `0.x.x`, this reflects that each versi You can create production applications with **FastAPI** right now (and you have probably been doing it for some time), you just have to make sure that you use a version that works correctly with the rest of your code. -## Pin your `fastapi` version +## Pin your `fastapi` version { #pin-your-fastapi-version } The first thing you should do is to "pin" the version of **FastAPI** you are using to the specific latest version that you know works correctly for your application. @@ -32,11 +32,11 @@ that would mean that you would use the versions `0.112.0` or above, but less tha If you use any other tool to manage your installations, like `uv`, Poetry, Pipenv, or others, they all have a way that you can use to define specific versions for your packages. -## Available versions +## Available versions { #available-versions } You can see the available versions (e.g. to check what is the current latest) in the [Release Notes](../release-notes.md){.internal-link target=_blank}. -## About versions +## About versions { #about-versions } Following the Semantic Versioning conventions, any version below `1.0.0` could potentially add breaking changes. @@ -62,7 +62,7 @@ The "MINOR" is the number in the middle, for example, in `0.2.3`, the MINOR vers /// -## Upgrading the FastAPI versions +## Upgrading the FastAPI versions { #upgrading-the-fastapi-versions } You should add tests for your app. @@ -72,7 +72,7 @@ After you have tests, then you can upgrade the **FastAPI** version to a more rec If everything is working, or after you make the necessary changes, and all your tests are passing, then you can pin your `fastapi` to that new recent version. -## About Starlette +## About Starlette { #about-starlette } You shouldn't pin the version of `starlette`. @@ -80,7 +80,7 @@ Different versions of **FastAPI** will use a specific newer version of Starlette So, you can just let **FastAPI** use the correct Starlette version. -## About Pydantic +## About Pydantic { #about-pydantic } Pydantic includes the tests for **FastAPI** with its own tests, so new versions of Pydantic (above `1.0.0`) are always compatible with FastAPI. diff --git a/docs/en/docs/environment-variables.md b/docs/en/docs/environment-variables.md index 43dd06add..1dbd93570 100644 --- a/docs/en/docs/environment-variables.md +++ b/docs/en/docs/environment-variables.md @@ -1,4 +1,4 @@ -# Environment Variables +# Environment Variables { #environment-variables } /// tip @@ -10,7 +10,7 @@ An environment variable (also known as "**env var**") is a variable that lives * Environment variables could be useful for handling application **settings**, as part of the **installation** of Python, etc. -## Create and Use Env Vars +## Create and Use Env Vars { #create-and-use-env-vars } You can **create** and use environment variables in the **shell (terminal)**, without needing Python: @@ -50,7 +50,7 @@ Hello Wade Wilson //// -## Read env vars in Python +## Read env vars in Python { #read-env-vars-in-python } You could also create environment variables **outside** of Python, in the terminal (or with any other method), and then **read them in Python**. @@ -157,7 +157,7 @@ You can read more about it at Uvicorn, a high-performance, production-ready, ASGI server. 😎 -## `fastapi dev` +## `fastapi dev` { #fastapi-dev } Running `fastapi dev` initiates development mode. By default, **auto-reload** is enabled, automatically reloading the server when you make changes to your code. This is resource-intensive and could be less stable than when it's disabled. You should only use it for development. It also listens on the IP address `127.0.0.1`, which is the IP for your machine to communicate with itself alone (`localhost`). -## `fastapi run` +## `fastapi run` { #fastapi-run } Executing `fastapi run` starts FastAPI in production mode by default. diff --git a/docs/en/docs/features.md b/docs/en/docs/features.md index 9c38a4bd2..d44d7a6ac 100644 --- a/docs/en/docs/features.md +++ b/docs/en/docs/features.md @@ -1,17 +1,17 @@ -# Features +# Features { #features } -## FastAPI features +## FastAPI features { #fastapi-features } **FastAPI** gives you the following: -### Based on open standards +### Based on open standards { #based-on-open-standards } * OpenAPI for API creation, including declarations of path operations, parameters, request bodies, security, etc. * Automatic data model documentation with JSON Schema (as OpenAPI itself is based on JSON Schema). * Designed around these standards, after a meticulous study. Instead of an afterthought layer on top. * This also allows using automatic **client code generation** in many languages. -### Automatic docs +### Automatic docs { #automatic-docs } Interactive API documentation and exploration web user interfaces. As the framework is based on OpenAPI, there are multiple options, 2 included by default. @@ -23,7 +23,7 @@ Interactive API documentation and exploration web user interfaces. As the framew ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### Just Modern Python +### Just Modern Python { #just-modern-python } It's all based on standard **Python type** declarations (thanks to Pydantic). No new syntax to learn. Just standard modern Python. @@ -71,7 +71,7 @@ Pass the keys and values of the `second_user_data` dict directly as key-value ar /// -### Editor support +### Editor support { #editor-support } All the framework was designed to be easy and intuitive to use, all the decisions were tested on multiple editors even before starting development, to ensure the best development experience. @@ -95,13 +95,13 @@ You will get completion in code you might even consider impossible before. As fo No more typing the wrong key names, coming back and forth between docs, or scrolling up and down to find if you finally used `username` or `user_name`. -### Short +### Short { #short } It has sensible **defaults** for everything, with optional configurations everywhere. All the parameters can be fine-tuned to do what you need and to define the API you need. But by default, it all **"just works"**. -### Validation +### Validation { #validation } * Validation for most (or all?) Python **data types**, including: * JSON objects (`dict`). @@ -117,7 +117,7 @@ But by default, it all **"just works"**. All the validation is handled by the well-established and robust **Pydantic**. -### Security and authentication +### Security and authentication { #security-and-authentication } Security and authentication integrated. Without any compromise with databases or data models. @@ -134,7 +134,7 @@ Plus all the security features from Starlette (including **session cookies**). All built as reusable tools and components that are easy to integrate with your systems, data stores, relational and NoSQL databases, etc. -### Dependency Injection +### Dependency Injection { #dependency-injection } FastAPI includes an extremely easy to use, but extremely powerful Dependency Injection system. @@ -145,19 +145,19 @@ FastAPI includes an extremely easy to use, but extremely powerful Pydantic. So, any additional Pydantic code you have, will also work. @@ -190,7 +190,7 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on * **No brainfuck**: * No new schema definition micro-language to learn. * If you know Python types you know how to use Pydantic. -* Plays nicely with your **IDE/linter/brain**: +* Plays nicely with your **IDE/linter/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. * Validate **complex structures**: * Use of hierarchical Pydantic models, Python `typing`’s `List` and `Dict`, etc. diff --git a/docs/en/docs/help-fastapi.md b/docs/en/docs/help-fastapi.md index 35d2e7b84..c7acd69a6 100644 --- a/docs/en/docs/help-fastapi.md +++ b/docs/en/docs/help-fastapi.md @@ -1,4 +1,4 @@ -# Help FastAPI - Get Help +# Help FastAPI - Get Help { #help-fastapi-get-help } Do you like **FastAPI**? @@ -10,7 +10,7 @@ There are very simple ways to help (several involve just one or two clicks). And there are several ways to get help too. -## Subscribe to the newsletter +## Subscribe to the newsletter { #subscribe-to-the-newsletter } You can subscribe to the (infrequent) [**FastAPI and friends** newsletter](newsletter.md){.internal-link target=_blank} to stay updated about: @@ -20,17 +20,17 @@ You can subscribe to the (infrequent) [**FastAPI and friends** newsletter](newsl * Breaking changes 🚨 * Tips and tricks ✅ -## Follow FastAPI on Twitter +## Follow FastAPI on X (Twitter) { #follow-fastapi-on-x-twitter } -Follow @fastapi on **Twitter** to get the latest news about **FastAPI**. đŸĻ +Follow @fastapi on **X (Twitter)** to get the latest news about **FastAPI**. đŸĻ -## Star **FastAPI** in GitHub +## Star **FastAPI** in GitHub { #star-fastapi-in-github } You can "star" FastAPI in GitHub (clicking the star button at the top right): https://github.com/fastapi/fastapi. â­ī¸ By adding a star, other users will be able to find it more easily and see that it has been already useful for others. -## Watch the GitHub repository for releases +## Watch the GitHub repository for releases { #watch-the-github-repository-for-releases } You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): https://github.com/fastapi/fastapi. 👀 @@ -38,7 +38,7 @@ There you can select "Releases only". By doing it, you will receive notifications (in your email) whenever there's a new release (a new version) of **FastAPI** with bug fixes and new features. -## Connect with the author +## Connect with the author { #connect-with-the-author } You can connect with me (SebastiÃĄn Ramírez / `tiangolo`), the author. @@ -47,29 +47,29 @@ You can: * Follow me on **GitHub**. * See other Open Source projects I have created that could help you. * Follow me to see when I create a new Open Source project. -* Follow me on **Twitter** or Mastodon. +* Follow me on **X (Twitter)** or Mastodon. * Tell me how you use FastAPI (I love to hear that). * Hear when I make announcements or release new tools. - * You can also follow @fastapi on Twitter (a separate account). + * You can also follow @fastapi on X (Twitter) (a separate account). * Follow me on **LinkedIn**. - * Hear when I make announcements or release new tools (although I use Twitter more often 🤷‍♂). + * Hear when I make announcements or release new tools (although I use X (Twitter) more often 🤷‍♂). * Read what I write (or follow me) on **Dev.to** or **Medium**. * Read other ideas, articles, and read about tools I have created. * Follow me to read when I publish something new. -## Tweet about **FastAPI** +## Tweet about **FastAPI** { #tweet-about-fastapi } -Tweet about **FastAPI** and let me and others know why you like it. 🎉 +Tweet about **FastAPI** and let me and others know why you like it. 🎉 I love to hear about how **FastAPI** is being used, what you have liked in it, in which project/company are you using it, etc. -## Vote for FastAPI +## Vote for FastAPI { #vote-for-fastapi } * Vote for **FastAPI** in Slant. * Vote for **FastAPI** in AlternativeTo. * Say you use **FastAPI** on StackShare. -## Help others with questions in GitHub +## Help others with questions in GitHub { #help-others-with-questions-in-github } You can try and help others with their questions in: @@ -88,7 +88,7 @@ The idea is for the **FastAPI** community to be kind and welcoming. At the same Here's how to help others with questions (in discussions or issues): -### Understand the question +### Understand the question { #understand-the-question } * Check if you can understand what is the **purpose** and use case of the person asking. @@ -98,7 +98,7 @@ Here's how to help others with questions (in discussions or issues): * If you can't understand the question, ask for more **details**. -### Reproduce the problem +### Reproduce the problem { #reproduce-the-problem } For most of the cases and most of the questions there's something related to the person's **original code**. @@ -108,13 +108,13 @@ In many cases they will only copy a fragment of the code, but that's not enough * If you are feeling too generous, you can try to **create an example** like that yourself, just based on the description of the problem. Just keep in mind that this might take a lot of time and it might be better to ask them to clarify the problem first. -### Suggest solutions +### Suggest solutions { #suggest-solutions } * After being able to understand the question, you can give them a possible **answer**. * In many cases, it's better to understand their **underlying problem or use case**, because there might be a better way to solve it than what they are trying to do. -### Ask to close +### Ask to close { #ask-to-close } If they reply, there's a high chance you would have solved their problem, congrats, **you're a hero**! đŸĻ¸ @@ -123,7 +123,7 @@ If they reply, there's a high chance you would have solved their problem, congra * In GitHub Discussions: mark the comment as the **answer**. * In GitHub Issues: **close** the issue. -## Watch the GitHub repository +## Watch the GitHub repository { #watch-the-github-repository } You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): https://github.com/fastapi/fastapi. 👀 @@ -131,7 +131,7 @@ If you select "Watching" instead of "Releases only" you will receive notificatio Then you can try and help them solve those questions. -## Ask Questions +## Ask Questions { #ask-questions } You can create a new question in the GitHub repository, for example to: @@ -140,7 +140,7 @@ You can Discord chat server đŸ‘Ĩ and hang out with others in the FastAPI community. @@ -237,7 +237,7 @@ Use the chat only for other general conversations. /// -### Don't use the chat for questions +### Don't use the chat for questions { #dont-use-the-chat-for-questions } Keep in mind that as chats allow more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers. @@ -247,7 +247,7 @@ Conversations in the chat systems are also not as easily searchable as in GitHub On the other side, there are thousands of users in the chat systems, so there's a high chance you'll find someone to talk to there, almost all the time. 😄 -## Sponsor the author +## Sponsor the author { #sponsor-the-author } If your **product/company** depends on or is related to **FastAPI** and you want to reach its users, you can sponsor the author (me) through GitHub sponsors. Depending on the tier, you could get some extra benefits, like a badge in the docs. 🎁 diff --git a/docs/en/docs/history-design-future.md b/docs/en/docs/history-design-future.md index b4a744d64..2182c415c 100644 --- a/docs/en/docs/history-design-future.md +++ b/docs/en/docs/history-design-future.md @@ -1,4 +1,4 @@ -# History, Design and Future +# History, Design and Future { #history-design-and-future } Some time ago, a **FastAPI** user asked: @@ -6,7 +6,7 @@ Some time ago, **Pydantic** for its advantages. @@ -60,11 +60,11 @@ Then I contributed to it, to make it fully compliant with JSON Schema, to suppor During the development, I also contributed to **Starlette**, the other key requirement. -## Development +## Development { #development } By the time I started creating **FastAPI** itself, most of the pieces were already in place, the design was defined, the requirements and tools were ready, and the knowledge about the standards and specifications was clear and fresh. -## Future +## Future { #future } By this point, it's already clear that **FastAPI** with its ideas is being useful for many people. diff --git a/docs/en/docs/how-to/conditional-openapi.md b/docs/en/docs/how-to/conditional-openapi.md index bd6cad9a8..e5893e584 100644 --- a/docs/en/docs/how-to/conditional-openapi.md +++ b/docs/en/docs/how-to/conditional-openapi.md @@ -1,8 +1,8 @@ -# Conditional OpenAPI +# Conditional OpenAPI { #conditional-openapi } If you needed to, you could use settings and environment variables to configure OpenAPI conditionally depending on the environment, and even disable it entirely. -## About security, APIs, and docs +## About security, APIs, and docs { #about-security-apis-and-docs } Hiding your documentation user interfaces in production *shouldn't* be the way to protect your API. @@ -17,13 +17,13 @@ If you want to secure your API, there are several better things you can do, for * Make sure you have well defined Pydantic models for your request bodies and responses. * Configure any required permissions and roles using dependencies. * Never store plaintext passwords, only password hashes. -* Implement and use well-known cryptographic tools, like Passlib and JWT tokens, etc. +* Implement and use well-known cryptographic tools, like pwdlib and JWT tokens, etc. * Add more granular permission controls with OAuth2 scopes where needed. * ...etc. Nevertheless, you might have a very specific use case where you really need to disable the API docs for some environment (e.g. for production) or depending on configurations from environment variables. -## Conditional OpenAPI from settings and env vars +## Conditional OpenAPI from settings and env vars { #conditional-openapi-from-settings-and-env-vars } You can easily use the same Pydantic settings to configure your generated OpenAPI and the docs UIs. diff --git a/docs/en/docs/how-to/configure-swagger-ui.md b/docs/en/docs/how-to/configure-swagger-ui.md index a8a8de48f..2d7b99f8f 100644 --- a/docs/en/docs/how-to/configure-swagger-ui.md +++ b/docs/en/docs/how-to/configure-swagger-ui.md @@ -1,4 +1,4 @@ -# Configure Swagger UI +# Configure Swagger UI { #configure-swagger-ui } You can configure some extra Swagger UI parameters. @@ -8,7 +8,7 @@ To configure them, pass the `swagger_ui_parameters` argument when creating the ` FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs. -## Disable Syntax Highlighting +## Disable Syntax Highlighting { #disable-syntax-highlighting } For example, you could disable syntax highlighting in Swagger UI. @@ -24,7 +24,7 @@ But you can disable it by setting `syntaxHighlight` to `False`: -## Change the Theme +## Change the Theme { #change-the-theme } The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle): @@ -34,7 +34,7 @@ That configuration would change the syntax highlighting color theme: -## Change Default Swagger UI Parameters +## Change Default Swagger UI Parameters { #change-default-swagger-ui-parameters } FastAPI includes some default configuration parameters appropriate for most of the use cases. @@ -48,11 +48,11 @@ For example, to disable `deepLinking` you could pass these settings to `swagger_ {* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *} -## Other Swagger UI Parameters +## Other Swagger UI Parameters { #other-swagger-ui-parameters } To see all the other possible configurations you can use, read the official docs for Swagger UI parameters. -## JavaScript-only settings +## JavaScript-only settings { #javascript-only-settings } Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions). diff --git a/docs/en/docs/how-to/custom-docs-ui-assets.md b/docs/en/docs/how-to/custom-docs-ui-assets.md index 9d2238e4f..91228c8c9 100644 --- a/docs/en/docs/how-to/custom-docs-ui-assets.md +++ b/docs/en/docs/how-to/custom-docs-ui-assets.md @@ -1,4 +1,4 @@ -# Custom Docs UI Static Assets (Self-Hosting) +# Custom Docs UI Static Assets (Self-Hosting) { #custom-docs-ui-static-assets-self-hosting } The API docs use **Swagger UI** and **ReDoc**, and each of those need some JavaScript and CSS files. @@ -6,13 +6,13 @@ By default, those files are served from a CDN, for example you want to use `https://unpkg.com/`. This could be useful if for example you live in a country that restricts some URLs. -### Disable the automatic docs +### Disable the automatic docs { #disable-the-automatic-docs } The first step is to disable the automatic docs, as by default, those use the default CDN. @@ -20,7 +20,7 @@ To disable them, set their URLs to `None` when creating your `FastAPI` app: {* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *} -### Include the custom docs +### Include the custom docs { #include-the-custom-docs } Now you can create the *path operations* for the custom docs. @@ -46,23 +46,23 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect /// -### Create a *path operation* to test it +### Create a *path operation* to test it { #create-a-path-operation-to-test-it } Now, to be able to test that everything works, create a *path operation*: {* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *} -### Test it +### Test it { #test-it } Now, you should be able to go to your docs at http://127.0.0.1:8000/docs, and reload the page, it will load those assets from the new CDN. -## Self-hosting JavaScript and CSS for docs +## Self-hosting JavaScript and CSS for docs { #self-hosting-javascript-and-css-for-docs } Self-hosting the JavaScript and CSS could be useful if, for example, you need your app to keep working even while offline, without open Internet access, or in a local network. Here you'll see how to serve those files yourself, in the same FastAPI app, and configure the docs to use them. -### Project file structure +### Project file structure { #project-file-structure } Let's say your project file structure looks like this: @@ -85,11 +85,11 @@ Your new file structure could look like this: └── static/ ``` -### Download the files +### Download the files { #download-the-files } Download the static files needed for the docs and put them on that `static/` directory. -You can probably right-click each link and select an option similar to `Save link as...`. +You can probably right-click each link and select an option similar to "Save link as...". **Swagger UI** uses the files: @@ -113,14 +113,14 @@ After that, your file structure could look like: └── swagger-ui.css ``` -### Serve the static files +### Serve the static files { #serve-the-static-files } * Import `StaticFiles`. * "Mount" a `StaticFiles()` instance in a specific path. {* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *} -### Test the static files +### Test the static files { #test-the-static-files } Start your application and go to http://127.0.0.1:8000/static/redoc.standalone.js. @@ -138,7 +138,7 @@ That confirms that you are being able to serve static files from your app, and t Now we can configure the app to use those static files for the docs. -### Disable the automatic docs for static files +### Disable the automatic docs for static files { #disable-the-automatic-docs-for-static-files } The same as when using a custom CDN, the first step is to disable the automatic docs, as those use the CDN by default. @@ -146,7 +146,7 @@ To disable them, set their URLs to `None` when creating your `FastAPI` app: {* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *} -### Include the custom docs for static files +### Include the custom docs for static files { #include-the-custom-docs-for-static-files } And the same way as with a custom CDN, now you can create the *path operations* for the custom docs. @@ -172,13 +172,13 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect /// -### Create a *path operation* to test static files +### Create a *path operation* to test static files { #create-a-path-operation-to-test-static-files } Now, to be able to test that everything works, create a *path operation*: {* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *} -### Test Static Files UI +### Test Static Files UI { #test-static-files-ui } Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page. diff --git a/docs/en/docs/how-to/custom-request-and-route.md b/docs/en/docs/how-to/custom-request-and-route.md index 9b4160d75..6df24a080 100644 --- a/docs/en/docs/how-to/custom-request-and-route.md +++ b/docs/en/docs/how-to/custom-request-and-route.md @@ -1,4 +1,4 @@ -# Custom Request and APIRoute class +# Custom Request and APIRoute class { #custom-request-and-apiroute-class } In some cases, you may want to override the logic used by the `Request` and `APIRoute` classes. @@ -14,7 +14,7 @@ If you are just starting with **FastAPI** you might want to skip this section. /// -## Use cases +## Use cases { #use-cases } Some use cases include: @@ -22,13 +22,13 @@ Some use cases include: * Decompressing gzip-compressed request bodies. * Automatically logging all request bodies. -## Handling custom request body encodings +## Handling custom request body encodings { #handling-custom-request-body-encodings } Let's see how to make use of a custom `Request` subclass to decompress gzip requests. And an `APIRoute` subclass to use that custom request class. -### Create a custom `GzipRequest` class +### Create a custom `GzipRequest` class { #create-a-custom-gziprequest-class } /// tip @@ -44,7 +44,7 @@ That way, the same route class can handle gzip compressed or uncompressed reques {* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *} -### Create a custom `GzipRoute` class +### Create a custom `GzipRoute` class { #create-a-custom-gziproute-class } Next, we create a custom subclass of `fastapi.routing.APIRoute` that will make use of the `GzipRequest`. @@ -78,7 +78,7 @@ After that, all of the processing logic is the same. But because of our changes in `GzipRequest.body`, the request body will be automatically decompressed when it is loaded by **FastAPI** when needed. -## Accessing the request body in an exception handler +## Accessing the request body in an exception handler { #accessing-the-request-body-in-an-exception-handler } /// tip @@ -98,7 +98,7 @@ If an exception occurs, the`Request` instance will still be in scope, so we can {* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *} -## Custom `APIRoute` class in a router +## Custom `APIRoute` class in a router { #custom-apiroute-class-in-a-router } You can also set the `route_class` parameter of an `APIRouter`: diff --git a/docs/en/docs/how-to/extending-openapi.md b/docs/en/docs/how-to/extending-openapi.md index 26c742c20..5e672665e 100644 --- a/docs/en/docs/how-to/extending-openapi.md +++ b/docs/en/docs/how-to/extending-openapi.md @@ -1,10 +1,10 @@ -# Extending OpenAPI +# Extending OpenAPI { #extending-openapi } There are some cases where you might need to modify the generated OpenAPI schema. In this section you will see how. -## The normal process +## The normal process { #the-normal-process } The normal (default) process, is as follows. @@ -33,31 +33,31 @@ The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by Fa /// -## Overriding the defaults +## Overriding the defaults { #overriding-the-defaults } Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need. For example, let's add ReDoc's OpenAPI extension to include a custom logo. -### Normal **FastAPI** +### Normal **FastAPI** { #normal-fastapi } First, write all your **FastAPI** application as normally: {* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *} -### Generate the OpenAPI schema +### Generate the OpenAPI schema { #generate-the-openapi-schema } Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function: {* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *} -### Modify the OpenAPI schema +### Modify the OpenAPI schema { #modify-the-openapi-schema } Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema: {* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *} -### Cache the OpenAPI schema +### Cache the OpenAPI schema { #cache-the-openapi-schema } You can use the property `.openapi_schema` as a "cache", to store your generated schema. @@ -67,13 +67,13 @@ It will be generated only once, and then the same cached schema will be used for {* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *} -### Override the method +### Override the method { #override-the-method } Now you can replace the `.openapi()` method with your new function. {* ../../docs_src/extending_openapi/tutorial001.py hl[29] *} -### Check it +### Check it { #check-it } Once you go to http://127.0.0.1:8000/redoc you will see that you are using your custom logo (in this example, **FastAPI**'s logo): diff --git a/docs/en/docs/how-to/general.md b/docs/en/docs/how-to/general.md index 04367c6b7..934719260 100644 --- a/docs/en/docs/how-to/general.md +++ b/docs/en/docs/how-to/general.md @@ -1,39 +1,39 @@ -# General - How To - Recipes +# General - How To - Recipes { #general-how-to-recipes } Here are several pointers to other places in the docs, for general or frequent questions. -## Filter Data - Security +## Filter Data - Security { #filter-data-security } To ensure that you don't return more data than you should, read the docs for [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank}. -## Documentation Tags - OpenAPI +## Documentation Tags - OpenAPI { #documentation-tags-openapi } To add tags to your *path operations*, and group them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}. -## Documentation Summary and Description - OpenAPI +## Documentation Summary and Description - OpenAPI { #documentation-summary-and-description-openapi } To add a summary and description to your *path operations*, and show them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}. -## Documentation Response description - OpenAPI +## Documentation Response description - OpenAPI { #documentation-response-description-openapi } To define the description of the response, shown in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}. -## Documentation Deprecate a *Path Operation* - OpenAPI +## Documentation Deprecate a *Path Operation* - OpenAPI { #documentation-deprecate-a-path-operation-openapi } To deprecate a *path operation*, and show it in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}. -## Convert any Data to JSON-compatible +## Convert any Data to JSON-compatible { #convert-any-data-to-json-compatible } To convert any data to JSON-compatible, read the docs for [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}. -## OpenAPI Metadata - Docs +## OpenAPI Metadata - Docs { #openapi-metadata-docs } To add metadata to your OpenAPI schema, including a license, version, contact, etc, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank}. -## OpenAPI Custom URL +## OpenAPI Custom URL { #openapi-custom-url } To customize the OpenAPI URL (or remove it), read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}. -## OpenAPI Docs URLs +## OpenAPI Docs URLs { #openapi-docs-urls } To update the URLs used for the automatically generated docs user interfaces, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}. diff --git a/docs/en/docs/how-to/graphql.md b/docs/en/docs/how-to/graphql.md index 361010736..99b024d39 100644 --- a/docs/en/docs/how-to/graphql.md +++ b/docs/en/docs/how-to/graphql.md @@ -1,4 +1,4 @@ -# GraphQL +# GraphQL { #graphql } As **FastAPI** is based on the **ASGI** standard, it's very easy to integrate any **GraphQL** library also compatible with ASGI. @@ -14,7 +14,7 @@ Make sure you evaluate if the **benefits** for your use case compensate the **dr /// -## GraphQL Libraries +## GraphQL Libraries { #graphql-libraries } Here are some of the **GraphQL** libraries that have **ASGI** support. You could use them with **FastAPI**: @@ -27,7 +27,7 @@ Here are some of the **GraphQL** libraries that have **ASGI** support. You could * Graphene * With starlette-graphene3 -## GraphQL with Strawberry +## GraphQL with Strawberry { #graphql-with-strawberry } If you need or want to work with **GraphQL**, **Strawberry** is the **recommended** library as it has the design closest to **FastAPI's** design, it's all based on **type annotations**. @@ -41,7 +41,7 @@ You can learn more about Strawberry in the Strawberry with FastAPI. -## Older `GraphQLApp` from Starlette +## Older `GraphQLApp` from Starlette { #older-graphqlapp-from-starlette } Previous versions of Starlette included a `GraphQLApp` class to integrate with Graphene. @@ -53,7 +53,7 @@ If you need GraphQL, I still would recommend you check out official GraphQL documentation. diff --git a/docs/en/docs/how-to/index.md b/docs/en/docs/how-to/index.md index 730dce5d5..5a8ce08de 100644 --- a/docs/en/docs/how-to/index.md +++ b/docs/en/docs/how-to/index.md @@ -1,4 +1,4 @@ -# How To - Recipes +# How To - Recipes { #how-to-recipes } Here you will see different recipes or "how to" guides for **several topics**. diff --git a/docs/en/docs/how-to/separate-openapi-schemas.md b/docs/en/docs/how-to/separate-openapi-schemas.md index 9a27638fe..3c78a56d3 100644 --- a/docs/en/docs/how-to/separate-openapi-schemas.md +++ b/docs/en/docs/how-to/separate-openapi-schemas.md @@ -1,4 +1,4 @@ -# Separate OpenAPI Schemas for Input and Output or Not +# Separate OpenAPI Schemas for Input and Output or Not { #separate-openapi-schemas-for-input-and-output-or-not } When using **Pydantic v2**, the generated OpenAPI is a bit more exact and **correct** than before. 😎 @@ -6,13 +6,13 @@ In fact, in some cases, it will even have **two JSON Schemas** in OpenAPI for th Let's see how that works and how to change it if you need to do that. -## Pydantic Models for Input and Output +## Pydantic Models for Input and Output { #pydantic-models-for-input-and-output } Let's say you have a Pydantic model with default values, like this one: {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *} -### Model for Input +### Model for Input { #model-for-input } If you use this model as an input like here: @@ -20,7 +20,7 @@ If you use this model as an input like here: ...then the `description` field will **not be required**. Because it has a default value of `None`. -### Input Model in Docs +### Input Model in Docs { #input-model-in-docs } You can confirm that in the docs, the `description` field doesn't have a **red asterisk**, it's not marked as required: @@ -28,7 +28,7 @@ You can confirm that in the docs, the `description` field doesn't have a **red a
-### Model for Output +### Model for Output { #model-for-output } But if you use the same model as an output, like here: @@ -36,7 +36,7 @@ But if you use the same model as an output, like here: ...then because `description` has a default value, if you **don't return anything** for that field, it will still have that **default value**. -### Model for Output Response Data +### Model for Output Response Data { #model-for-output-response-data } If you interact with the docs and check the response, even though the code didn't add anything in one of the `description` fields, the JSON response contains the default value (`null`): @@ -55,7 +55,7 @@ Because of that, the JSON Schema for a model can be different depending on if it * for **input** the `description` will **not be required** * for **output** it will be **required** (and possibly `None`, or in JSON terms, `null`) -### Model for Output in Docs +### Model for Output in Docs { #model-for-output-in-docs } You can check the output model in the docs too, **both** `name` and `description` are marked as **required** with a **red asterisk**: @@ -63,7 +63,7 @@ You can check the output model in the docs too, **both** `name` and `description -### Model for Input and Output in Docs +### Model for Input and Output in Docs { #model-for-input-and-output-in-docs } And if you check all the available Schemas (JSON Schemas) in OpenAPI, you will see that there are two, one `Item-Input` and one `Item-Output`. @@ -77,7 +77,7 @@ But for `Item-Output`, `description` is **required**, it has a red asterisk. With this feature from **Pydantic v2**, your API documentation is more **precise**, and if you have autogenerated clients and SDKs, they will be more precise too, with a better **developer experience** and consistency. 🎉 -## Do not Separate Schemas +## Do not Separate Schemas { #do-not-separate-schemas } Now, there are some cases where you might want to have the **same schema for input and output**. @@ -93,7 +93,7 @@ Support for `separate_input_output_schemas` was added in FastAPI `0.102.0`. 🤓 {* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *} -### Same Schema for Input and Output Models in Docs +### Same Schema for Input and Output Models in Docs { #same-schema-for-input-and-output-models-in-docs } And now there will be one single schema for input and output for the model, only `Item`, and it will have `description` as **not required**: diff --git a/docs/en/docs/how-to/testing-database.md b/docs/en/docs/how-to/testing-database.md index d0ed15bca..400fdcfc6 100644 --- a/docs/en/docs/how-to/testing-database.md +++ b/docs/en/docs/how-to/testing-database.md @@ -1,4 +1,4 @@ -# Testing a Database +# Testing a Database { #testing-a-database } You can study about databases, SQL, and SQLModel in the SQLModel docs. 🤓 diff --git a/docs/en/docs/img/sponsors/mobbai-banner.png b/docs/en/docs/img/sponsors/mobbai-banner.png new file mode 100644 index 000000000..1f59294ab Binary files /dev/null and b/docs/en/docs/img/sponsors/mobbai-banner.png differ diff --git a/docs/en/docs/img/sponsors/mobbai.png b/docs/en/docs/img/sponsors/mobbai.png new file mode 100644 index 000000000..b519fd885 Binary files /dev/null and b/docs/en/docs/img/sponsors/mobbai.png differ diff --git a/docs/en/docs/img/sponsors/railway-banner.png b/docs/en/docs/img/sponsors/railway-banner.png new file mode 100644 index 000000000..f6146a7c1 Binary files /dev/null and b/docs/en/docs/img/sponsors/railway-banner.png differ diff --git a/docs/en/docs/img/sponsors/railway.png b/docs/en/docs/img/sponsors/railway.png new file mode 100644 index 000000000..dc6ccacc4 Binary files /dev/null and b/docs/en/docs/img/sponsors/railway.png differ diff --git a/docs/en/docs/img/sponsors/speakeasy.png b/docs/en/docs/img/sponsors/speakeasy.png index 5ddc25487..7bb9c3a18 100644 Binary files a/docs/en/docs/img/sponsors/speakeasy.png and b/docs/en/docs/img/sponsors/speakeasy.png differ diff --git a/docs/en/docs/index.md b/docs/en/docs/index.md index 938882d7d..aaadf3cc2 100644 --- a/docs/en/docs/index.md +++ b/docs/en/docs/index.md @@ -1,4 +1,4 @@ -# FastAPI +# FastAPI { #fastapi } - -

- FastAPI -

-

- ×Ē׊×Ēי×Ē FastAPI, בי×Ļו×ĸים גבוהים, קלה ללמידה, מהירה ל×Ēכנו×Ē, מוכנה לסביב×Ē ×™×™×Ļור -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**×Ēי×ĸוד**: https://fastapi.tiangolo.com - -**קוד**: https://github.com/fastapi/fastapi - ---- - -FastAPI היא ×Ē׊×Ēי×Ē ×¨×Š×Ē ×ž×•×“×¨× ×™×Ē ×•×ž×”×™×¨×” (בי×Ļו×ĸים גבוהים) לבניי×Ē ×ž×ž×Š×§×™ ×Ēכנו×Ē ×™×™×Š×•×ž×™× (API) ×ĸם פיי×Ēון 3.6+ בה×Ēבסס ×ĸל רמזי טיפוסים סטנדרטיים. - -×Ēכונו×Ē ×”×ž×¤×Ēח הן: - -- **מהירה**: בי×Ļו×ĸים גבוהים מאוד, בקנה אחד ×ĸם NodeJS ו - Go (×Ēודו×Ē ×œ - Starlette ו - Pydantic). [אח×Ē ×ž×Ē׊×Ēיו×Ē ×”×¤×™×™×Ēון המהירו×Ē ×‘×™×•×Ēר](#_14). - -- **מהירה ל×Ēכנו×Ē**: הגבירו א×Ē ×ž×”×™×¨×•×Ē ×¤×™×Ēוח ה×Ēכונו×Ē ×”×—×“×Š×•×Ē ×‘×› - %200 ×ĸד %300. \* -- **פחו×Ē ×Š×’×™××•×Ē**: מנ×ĸו כ - %40 משגיאו×Ē ×× ×•×Š (מפ×Ēחים). \* -- **אינטואיטיבי×Ē**: ×Ēמיכ×Ē ×ĸורך מ×ĸולה. השלמה בכל מקום. פחו×Ē ×–×ž×Ÿ ניפוי שגיאו×Ē. -- **קלה**: מ×Ēוכננ×Ē ×œ×”×™×•×Ē ×§×œ×” לשימוש וללמידה. פחו×Ē ×–×ž×Ÿ קריא×Ē ×Ēי×ĸוד. -- **×§×Ļרה**: מז×ĸרו שכפול קוד. מספר ×Ēכונו×Ē ×ž×›×œ הכרז×Ē ×¤×¨×ž×˜×¨. פחו×Ē ×Š×’×™××•×Ē. -- **חסונה**: קבלו קוד מוכן לסביב×Ē ×™×™×Ļור. ×ĸם ×Ēי×ĸוד אינטרקטיבי אוטומטי. -- **מבוסס×Ē ×Ą×˜× ×“×¨×˜×™×**: מבוסס×Ē ×ĸל (ו×Ēואמ×Ē ×œ×—×œ×•×˜×™×Ÿ ל -) הסטדנרטים הפ×Ēוחים לממשקי ×Ēכנו×Ē ×™×™×Š×•×ž×™×: OpenAPI (ידו×ĸים לש×ĸבר כ - Swagger) ו - JSON Schema. - -\* ה×ĸרכה מבוסס×Ē ×ĸל בדיקו×Ē ×Š×œ ×Ļוו×Ē ×¤×™×Ēוח פנימי שבונה אפליק×Ļיו×Ē ×‘×Ą×‘×™×‘×Ē ×™×™×Ļור. - -## נו×Ēני חסו×Ē - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -נו×Ēני חסו×Ē ××—×¨×™× - -## ד×ĸו×Ē - -"_[...] 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._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" - -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_I’m over the moon excited about **FastAPI**. It’s so fun!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_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._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_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 [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- - -## **Typer**, ה - FastAPI של ממשקי שור×Ē ×¤×§×•×“×” (CLI). - - - -אם א×Ēם בונים אפליק×Ļיי×Ē CLI לשימוש ×‘×ž×Ą×•×Ŗ במקום ממ׊ק ר׊×Ē, ה×ĸיפו מבט ×ĸל **Typer**. - -**Typer** היא אחו×Ēה הקטנה של FastAPI. ומטר×Ēה היא להיו×Ē ×” - **FastAPI של ממשקי שור×Ē ×¤×§×•×“×”**. âŒ¨ī¸ 🚀 - -## ×Ēלויו×Ē - -פיי×Ēון 3.6+ - -FastAPI ×ĸומד×Ē ×ĸל כ×Ēפי ×ĸנקיו×Ē: - -- Starlette לחלקי הרש×Ē. -- Pydantic לחלקי המיד×ĸ. - -## ה×Ēקנה - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -×Ē×Ļטרכו גם ׊ר×Ē ASGI כגון Uvicorn או Hypercorn. - -
- -```console -$ pip install "uvicorn[standard]" - ----> 100% -``` - -
- -## דוגמא - -### ×Ļרו או×Ēה - -- ×Ļרו קוב×Ĩ בשם `main.py` ×ĸם: - -```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} -``` - -
-או הש×Ēמשו ב - async def... - -אם הקוד שלכם מ׊×Ēמ׊ ב - `async` / `await`, הש×Ēמשו ב - `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} -``` - -**שימו לב**: - -אם אינכם יוד×ĸים, בדקו א×Ē ×¤×¨×§ "ממהרים?" ×ĸל `async` ו - `await` ב×Ēי×ĸוד. - -
- -### הרי×Ļו או×Ēה - -ה×Ēחילו א×Ē ×”×Š×¨×Ē ×ĸם: - -
- -```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. -``` - -
- -
-×ĸל הפקודה uvicorn main:app --reload... - -הפקודה `uvicorn main:app` מ×Ēייחס×Ē ×œ: - -- `main`: הקוב×Ĩ `main.py` (מודול פיי×Ēון). -- `app`: האובייקט שנו×Ļר ב×Ēוך `main.py` ×ĸם השורה app = FastAPI(). -- --reload: גרמו לשר×Ē ×œ×”×Ēא×Ēחל לאחר שינויים בקוד. ×ĸשו זא×Ē ×¨×§ בסביב×Ē ×¤×™×Ēוח. - -
- -### בדקו או×Ēה - -פ×Ēחו א×Ē ×”×“×¤×“×¤×Ÿ שלכם בכ×Ēוב×Ē http://127.0.0.1:8000/items/5?q=somequery. - -א×Ēם ×Ēראו ×Ēגוב×Ē JSON: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -כבר י×Ļר×Ēם API ׊: - -- מקבל בקשו×Ē HTTP בנ×Ēיבים `/` ו - /items/{item_id}. -- שני ה _× ×Ēיבים_ מקבלים _בקשו×Ē_ `GET` (ידו×ĸו×Ē ×’× כ*מ×Ēודו×Ē* HTTP). -- ה _× ×Ēיב_ /items/{item_id} כולל \*פרמטר × ×Ēיב\_ `item_id` שאמור להיו×Ē `int`. -- ה _× ×Ēיב_ /items/{item_id} \*פרמטר שאיל×Ēא\_ אופ×Ļיונלי `q`. - -### ×Ēי×ĸוד API אינטרקטיבי - -כ×ĸ×Ē ×¤× ×• לכ×Ēוב×Ē http://127.0.0.1:8000/docs. - -א×Ēם ×Ēראו א×Ē ×”×Ēי×ĸוד האוטומטי (מסופק ×ĸל ידי Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### ×Ēי×ĸוד אלטרנטיבי - -כ×ĸ×Ē ×¤× ×• לכ×Ēוב×Ē http://127.0.0.1:8000/redoc. - -א×Ēם ×Ēראו ×Ēי×ĸוד אלטרנטיבי (מסופק ×ĸל ידי ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## שדרוג לדוגמא - -כ×ĸ×Ē ×ĸרכו א×Ē ×”×§×•×‘×Ĩ `main.py` כך שיוכל לקבל גות מבקש×Ē `PUT`. - -הגדירו א×Ē ×”×’×•×Ŗ ב×ĸזר×Ē ×¨×ž×–×™ טיפוסים סטנדרטיים, הודו×Ē ×œ - `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} -``` - -השר×Ē ××ž×•×œ לה×Ēא×Ēחל אוטומטי×Ē (מאחר והוספ×Ēם --reload לפקוד×Ē `uvicorn` שלמ×ĸלה). - -### שדרוג ה×Ēי×ĸוד האינטרקטיבי - -כ×ĸ×Ē ×¤× ×• לכ×Ēוב×Ē http://127.0.0.1:8000/docs. - -- ה×Ēי×ĸוד האוטומטי י×Ē×ĸדכן, כולל הגות החדש: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -- לח×Ļו ×ĸל הכפ×Ēור "Try it out", הוא יאפשר לכם למלא א×Ē ×”×¤×¨×ž×˜×¨×™× ול×ĸבוד ישירו×Ē ×ž×•×œ ה - API. - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -- אחר כך לח×Ļו ×ĸל הכפ×Ēור "Execute", הא×Ēר י×Ēק׊ר ×ĸם ה - API שלכם, ישלח א×Ē ×”×¤×¨×ž×˜×¨×™×, ישיג א×Ē ×”×Ēו×Ļאו×Ē ×•××– יראה או×Ēן ×ĸל המסך: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### שדרוג ה×Ēי×ĸוד האלטרנטיבי - -כ×ĸ×Ē ×¤× ×• לכ×Ēוב×Ē http://127.0.0.1:8000/redoc. - -- ה×Ēי×ĸוד האלטרנטיבי גם יראה א×Ē ×¤×¨×ž×˜×¨ השאיל×Ēא והגות החדשים. - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### סיכום - -לסיכום, א×Ēם מכריזים ** פ×ĸם אח×Ē** ×ĸל טיפוסי הפרמטרים, גות וכו' כפרמטרים לפונק×Ļיה. - -א×Ēם ×ĸושים א×Ē ×–×” ×ĸם טיפוסי פיי×Ēון מודרניים. - -א×Ēם לא ×Ļריכים ללמוד ×Ēחביר חדש, מ×Ēודו×Ē ××• מחלקו×Ē ×Š×œ ספרייה ספי×Ļיפי×Ē, וכו' - -רק **פיי×Ēון 3.6+** סטנדרטי. - -לדוגמא, ל - `int`: - -```Python -item_id: int -``` - -או למודל `Item` מורכב יו×Ēר: - -```Python -item: Item -``` - -...ו×ĸם הכרז×Ē ×”×˜×™×¤×•×Ą האח×Ē ×”×–×• א×Ēם מקבלים: - -- ×Ēמיכ×Ē ×ĸורך, כולל: - - השלמו×Ē. - - בדיק×Ē ×˜×™×¤×•×Ą×™×. -- אימו×Ē ×ž×™×“×ĸ: - - שגיאו×Ē ×‘×¨×•×¨×•×Ē ×•××˜×•×ž×˜×™×•×Ē ×›××Š×¨ מוכנס מיד×ĸ לא חוקי . - - אימו×Ē ××¤×™×œ×• לאובייקטי JSON מקוננים. -- המרה של מיד×ĸ קלט: המרה של מיד×ĸ שמגי×ĸ מהרש×Ē ×œ×ž×™×“×ĸ וטיפוסים של פיי×Ēון. קורא מ: - - JSON. - - פרמטרי × ×Ēיב. - - פרמטרי שאיל×Ēא. - - ×ĸוגיו×Ē. - - כו×Ēרו×Ē. - - טפסים. - - קב×Ļים. -- המרה של מיד×ĸ פלט: המרה של מיד×ĸ וטיפוסים מפיי×Ēון למיד×ĸ ר׊×Ē (כ - JSON): - - המירו טיפוסי פיי×Ēון (`str`, `int`, `float`, `bool`, `list`, etc). - - ×ĸ×Ļמי `datetime`. - - ×ĸ×Ļמי `UUID`. - - מודלי בסיסי × ×Ēונים. - - ...ורבים אחרים. -- ×Ēי×ĸוד API אוטומטי ואינטרקטיבי×Ē ×›×•×œ×œ ׊×Ēי אלטרנטיבו×Ē ×œ×ž×ž×Š×§ המש×Ēמ׊: - - Swagger UI. - - ReDoc. - ---- - -בחזרה לדוגמא×Ē ×”×§×•×“ הקודמ×Ē, **FastAPI** ידאג: - -- לאמ×Ē ×Š×™×Š `item_id` בנ×Ēיב בבקשו×Ē `GET` ו - `PUT`. -- לאמ×Ē ×Š×” - `item_id` הוא מטיפוס `int` בבקשו×Ē `GET` ו - `PUT`. - - אם הוא לא, הלקוח יראה שגיאה ברורה ושימושי×Ē. -- לבדוק האם קיים פרמטר שאיל×Ēא בשם `q` (קרי `http://127.0.0.1:8000/items/foo?q=somequery`) לבקשו×Ē `GET`. - - מאחר והפרמטר `q` מוגדר ×ĸם = None, הוא אופ×Ļיונלי. - - לולא ה - `None` הוא היה חובה (כמו הגות במקרה של `PUT`). -- לבקשו×Ē `PUT` לנ×Ēיב /items/{item_id}, לקרוא א×Ē ×’×•×Ŗ הבקשה כ - JSON: - - לאמ×Ē ×Š×”×•× כולל א×Ē ×ž××¤×™×™×Ÿ החובה `name` שאמור להיו×Ē ×ž×˜×™×¤×•×Ą `str`. - - לאמ×Ē ×Š×”×•× כולל א×Ē ×ž××¤×™×™×Ÿ החובה `price` שחייב להיו×Ē ×ž×˜×™×¤×•×Ą `float`. - - לבדוק האם הוא כולל א×Ē ×ž××¤×™×™×Ÿ הרשו×Ē `is_offer` שאמור להיו×Ē ×ž×˜×™×¤×•×Ą `bool`, אם הוא נמ×Ļא. - - כל זה י×ĸבוד גם לאובייקט JSON מקונן. -- להמיר מ - JSON ול- JSON אוטומטי×Ē. -- ל×Ē×ĸד הכל באמ×Ļ×ĸו×Ē OpenAPI, ×Ēי×ĸוד שבו יוכלו להש×Ēמ׊: - - מ×ĸרכו×Ē ×Ēי×ĸוד אינטרקטיביו×Ē. - - מ×ĸרכו×Ē ×™×™×Ļור קוד אוטומטיו×Ē, להרבה שפו×Ē. -- לספק ישירו×Ē ×Š×Ēי מ×ĸרכו×Ē ×Ēי×ĸוד ר׊×Ēיו×Ē. - ---- - -רק גרדנו א×Ē ×§×Ļה הקרחון, אבל כבר יש לכם ר×ĸיון של איך הכל ×ĸובד. - -נסו לשנו×Ē ××Ē ×”×Š×•×¨×”: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...מ: - -```Python - ... "item_name": item.name ... -``` - -...ל: - -```Python - ... "item_price": item.price ... -``` - -...וראו איך ה×ĸורך שלכם משלים א×Ē ×”×ž××¤×™×™× ×™× ויוד×ĸ א×Ē ×”×˜×™×¤×•×Ą×™× שלהם: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -לדוגמא יו×Ēר שלמה שכולל×Ē ×ĸוד ×Ēכונו×Ē, ראו א×Ē ×”×ž×“×¨×™×š - למש×Ēמ׊. - -**ה×Ēרא×Ē ×Ą×¤×•×™×œ×¨×™×**: המדריך - למש×Ēמ׊ כולל: - -- הכרזה ×ĸל **פרמטרים** ממקורו×Ē ××—×¨×™× ושונים כגון: **כו×Ēרו×Ē**, **×ĸוגיו×Ē**, **טפסים** ו - **קב×Ļים**. -- איך לקבו×ĸ **מגבלו×Ē ××™×ž×•×Ē** ב×ĸזר×Ē `maximum_length` או `regex`. -- דרך חזקה וקלה להש×Ēמ׊ ב**הזרק×Ē ×Ēלויו×Ē**. -- אבטחה וה×Ēאמ×Ēו×Ē, כולל ×Ēמיכה ב - **OAuth2** ×ĸם **JWT** וה×Ēאמ×Ēו×Ē **HTTP Basic**. -- טכניקו×Ē ×ž×Ēקדמו×Ē (אבל קלו×Ē ×‘××•×Ēה מידה) להכרז×Ē ××•×‘×™×™×§×˜×™ JSON מקוננים (×Ēודו×Ē ×œ - Pydantic). -- אינטרק×Ļיה ×ĸם **GraphQL** דרך Strawberry וספריו×Ē ××—×¨×•×Ē. -- ×Ēכונו×Ē × ×•×Ą×¤×•×Ē ×¨×‘×•×Ē (×Ēודו×Ē ×œ - Starlette) כגון: - - **WebSockets** - - בדיקו×Ē ×§×œ×•×Ē ×‘×ž×™×•×—×“ מבוססו×Ē ×ĸל `requests` ו - `pytest` - - **CORS** - - **Cookie Sessions** - - ...ו×ĸוד. - -## בי×Ļו×ĸים - -בדיקו×Ē ×ĸ×Ļמאיו×Ē ×Š×œ TechEmpower הראו שאפליק×Ļיו×Ē **FastAPI** ׊ר×Ļו×Ē ×Ēח×Ē Uvicorn הן מ×Ē׊×Ēיו×Ē ×”×¤×™×™×Ēון המהירו×Ē ×‘×™×•×Ēר, רק מ×Ēח×Ē ×œ - Starlette ו - Uvicorn ×ĸ×Ļמן (׊ - FastAPI מבוסס×Ē ×ĸליהן). (\*) - -כדי להבין ×ĸוד ×ĸל הנושא, ראו א×Ē ×”×¤×¨×§ Benchmarks. - -## ×Ēלויו×Ē ××•×¤×Ļיונליו×Ē - -בשימוש Pydantic: - -- email-validator - לאימו×Ē ×›×Ēובו×Ē ××™×ž×™×™×œ. - -בשימוש Starlette: - -- httpx - דרוש אם בר×Ļונכם להש×Ēמ׊ ב - `TestClient`. -- jinja2 - דרוש אם בר×Ļונכם להש×Ēמ׊ בבריר×Ē ×”×ž×—×“×œ של ×Ē×Ļור×Ē ×”×˜×ž×¤×œ×™×™×˜×™×. -- python-multipart - דרוש אם בר×Ļונכם ל×Ēמוך ב "פרסור" טפסים, בא×Ļמ×ĸו×Ē request.form(). -- itsdangerous - דרוש אם בר×Ļונכם להש×Ēמ׊ ב - `SessionMiddleware`. -- pyyaml - דרוש אם בר×Ļונכם להש×Ēמ׊ ב - `SchemaGenerator` של Starlette (כנראה ׊א×Ēם לא ×Ļריכים א×Ē ×–×” ×ĸם FastAPI). - -בשימוש FastAPI / Starlette: - -- uvicorn - לשר×Ē ×Š×˜×•×ĸן ומגיש א×Ē ×”××¤×œ×™×§×Ļיה שלכם. -- orjson - דרוש אם בר×Ļונכם להש×Ēמ׊ ב - `ORJSONResponse`. -- ujson - דרוש אם בר×Ļונכם להש×Ēמ׊ ב - `UJSONResponse`. - -×Ēוכלו לה×Ēקין א×Ē ×›×œ אלו באמ×Ļ×ĸו×Ē pip install "fastapi[all]". - -## רשיון - -הפרויקט הזה הוא ×Ēח×Ē ×”×Ēנאים של רשיון MIT. diff --git a/docs/he/mkdocs.yml b/docs/he/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/he/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/hu/docs/index.md b/docs/hu/docs/index.md deleted file mode 100644 index 45ff49c3b..000000000 --- a/docs/hu/docs/index.md +++ /dev/null @@ -1,467 +0,0 @@ -

- FastAPI -

-

- FastAPI keretrendszer, nagy teljesítmÊny, kÃļnnyen tanulhatÃŗ, gyorsan kÃŗdolhatÃŗ, productionre kÊsz -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**DokumentÃĄciÃŗ**: https://fastapi.tiangolo.com - -**ForrÃĄs kÃŗd**: https://github.com/fastapi/fastapi - ---- -A FastAPI egy modern, gyors (nagy teljesítmÊnyÅą), webes keretrendszer API-ok ÊpítÊsÊhez Python -al, a Python szabvÃĄnyos típusjelÃļlÊseire Êpítve. - - -Kulcs funkciÃŗk: - -* **Gyors**: Nagyon nagy teljesítmÊny, a **NodeJS**-el Ês a **Go**-val egyenrangÃē (a Starlettenek Ês a Pydantic-nek kÃļszÃļnhetően). [Az egyik leggyorsabb Python keretrendszer](#performance). -* **Gyorsan kÃŗdolhatÃŗ**: A funkciÃŗk fejlesztÊsi sebessÊgÊt 200-300 szÃĄzalÊkkal megnÃļveli. * -* **Kevesebb hiba**: KÃļrÃŧlbelÃŧl 40%-al csÃļkkenti az emberi (fejlesztői) hibÃĄk szÃĄmÃĄt. * -* **Intuitív**: KivÃĄlÃŗ szerkesztő tÃĄmogatÃĄs. KiegÊszítÊs mindenhol. Kevesebb hibakeresÊssel tÃļltÃļtt idő. -* **EgyszerÅą**: EgyszerÅą tanulÃĄsra Ês hasznÃĄlatra tervezve. Kevesebb dokumentÃĄciÃŗ olvasÃĄssal tÃļltÃļtt idő. -* **RÃļvid**: KÃŗd duplikÃĄciÃŗ minimalizÃĄlÃĄsa. TÃļbb funkciÃŗ minden paramÊter deklarÃĄlÃĄsÃĄval. Kevesebb hiba. -* **Robosztus**: Production ready kÃŗd. Automatikus interaktív dokumentÃĄciÃŗ val. -* **SzabvÃĄny alapÃē**: Az API-ok nyílt szabvÃĄnyaira alapulÃŗ (Ês azokkal teljesen kompatibilis): OpenAPI (korÃĄbban Swagger nÊven ismert) Ês a JSON Schema. - -* Egy production alkalmazÃĄsokat Êpítő belső fejlesztői csapat tesztjein alapulÃŗ becslÊs. - -## Szponzorok - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -TovÃĄbbi szponzorok - -## VÊlemÊnyek - -"_[...] 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._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" - -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_I’m over the moon excited about **FastAPI**. It’s so fun!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_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._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_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 [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- - -"_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._" - -
Deon Pillsbury - Cisco (ref)
- ---- - -## **Typer**, a CLI-ok FastAPI-ja - - - -Ha egy olyan CLI alkalmazÃĄst fejlesztesz amit a parancssorban kell hasznÃĄlni webes API helyett, tekintsd meg: **Typer**. - -**Typer** a FastAPI kistestvÊre. A **CLI-k FastAPI-ja**. âŒ¨ī¸ 🚀 - -## KÃļvetelmÊnyek - -A FastAPI ÃŗriÃĄsok vÃĄllÃĄn ÃĄll: - -* Starlette a webes rÊszekhez. -* Pydantic az adat rÊszekhez. - -## TelepítÊs - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -A production-hÃļz egy ASGI szerverre is szÃŧksÊg lesz, mint pÊldÃĄul az Uvicorn vagy a Hypercorn. - -
- -```console -$ pip install "uvicorn[standard]" - ----> 100% -``` - -
- -## PÊlda - -### Hozd lÊtre - -* Hozz lÊtre a `main.py` fÃĄjlt a kÃļvetkező tartalommal: - -```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} -``` - -
-Vagy hasznÃĄld az async def-et... - -Ha a kÃŗdod `async` / `await`-et, hasznÃĄl `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} -``` - -**MegjegyzÊs**: - -Ha nem tudod, tekintsd meg a _"Sietsz?"_ szekciÃŗt `async` Ês `await`-ről dokumentÃĄciÃŗba. - -
- -### Futtasd le - -Indítsd el a szervert a kÃļvetkező paranccsal: - -
- -```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. -``` - -
- -
-A parancsrÃŗl uvicorn main:app --reload... - -A `uvicorn main:app` parancs a kÃļvetkezőre utal: - -* `main`: fÃĄjl `main.py` (a Python "modul"). -* `app`: a `main.py`-ban a `app = FastAPI()` sorral lÊtrehozott objektum. -* `--reload`: kÃŗd vÃĄltoztatÃĄs esetÊn Ãējra indítja a szervert. Csak fejlesztÊs kÃļzben hasznÃĄlandÃŗ. - -
- -### Ellenőrizd - -Nyisd meg a bÃļngÊsződ a kÃļvetkező címen: http://127.0.0.1:8000/items/5?q=somequery. - -A kÃļvetkező JSON vÃĄlaszt fogod lÃĄtni: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -MÃĄris lÊtrehoztÃĄl egy API-t ami: - -* HTTP kÊrÊseket fogad a `/` Ês `/items/{item_id}` _Ãētvonalakon_. -* MindkÊt _Ãētvonal_ a `GET` mÅąveletet hasznÃĄlja (mÃĄsik elnevezÊs: HTTP _metÃŗdus_). -* A `/items/{item_id}` _Ãētvonalnak_ van egy _path paramÊtere_, az `item_id`, aminek `int` típusÃēnak kell lennie. -* A `/items/{item_id}` _Ãētvonalnak_ mÊg van egy opcionÃĄlis, `str` típusÃē _query paramÊtere_ is, a `q`. - -### Interaktív API dokumentÃĄciÃŗ - -Most nyisd meg a http://127.0.0.1:8000/docs címet. - -Az automatikus interaktív API dokumentÃĄciÃŗt fogod lÃĄtni (amit a Swagger UI-al hozunk lÊtre): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternatív API dokumentÃĄciÃŗ - -És most menj el a http://127.0.0.1:8000/redoc címre. - -Az alternatív automatikus dokumentÃĄciÃŗt fogod lÃĄtni. (lÃĄsd ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## PÊlda frissítÊse - -MÃŗdosítsuk a `main.py` fÃĄjlt, hogy `PUT` kÊrÊsek esetÊn tudjon body-t fogadni. - -DeklarÃĄld a body-t standard Python típusokkal, a Pydantic-nak kÃļszÃļnhetően. - -```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} -``` - -A szerver automatikusan Ãējraindul (mert hozzÃĄadtuk a --reload paramÊtert a fenti `uvicorn` parancshoz). - -### Interaktív API dokumentÃĄciÃŗ frissítÊse - -Most menj el a http://127.0.0.1:8000/docs címre. - -* Az interaktív API dokumentÃĄciÃŗ automatikusan frissÃŧlt így mÃĄr benne van az Ãēj body. - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Kattints rÃĄ a "Try it out" gombra, ennek segítsÊgÊvel kitÃļltheted a paramÊtereket Ês kÃļzvetlen hasznÃĄlhatod az API-t: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* EzutÃĄn kattints az "Execute" gompra, a felhasznÃĄlÃŗi felÃŧlet kommunikÃĄlni fog az API-oddal. ElkÃŧldi a paramÊtereket Ês a visszakapott vÃĄlaszt megmutatja a kÊpernyődÃļn. - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Alternatív API dokumentÃĄciÃŗ frissítÊs - -Most menj el a http://127.0.0.1:8000/redoc címre. - -* Az alternatív dokumentÃĄciÃŗ szintÃēgy tÃŧkrÃļzni fogja az Ãēj kÊrÊsi paramÊter Ês body-t. - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### ÖsszefoglalÃĄs - -ÖsszegzÊsÃŧl, deklarÃĄlod **egyszer** a paramÊterek, body, stb típusÃĄt funkciÃŗs paramÊterekkÊnt. - -Ezt standard modern Python típusokkal csinÃĄlod. - -Nem kell Ãēj szintaxist, vagy specifikus kÃļnyvtÃĄr mert metÃŗdÃŗsait, stb. megtanulnod. - -Csak standard **Python**. - -PÊldÃĄul egy `int`-nek: - -```Python -item_id: int -``` - -Egy komplexebb `Item` modellnek: - -```Python -item: Item -``` - -... És csupÃĄn egy deklarÃĄciÃŗval megkapod a: - -* Szerkesztő tÃĄmogatÃĄst, beleÊrtve: - * SzÃļvegkiegÊszítÊs. - * Típus ellenőrzÊs. -* Adatok validÃĄciÃŗja: - * Automatikus Ês Êrthető hibÃĄk amikor az adatok hibÃĄsak. - * ValidÃĄciÃŗ mÊlyen ÃĄgyazott objektumok esetÊn is. -* Bemeneti adatok ÃĄtvÃĄltÃĄsa : a hÃĄlÃŗzatrÃŗl Êrkező Python adatokkÃĄ Ês típusokkÃĄ. Adatok olvasÃĄsa kÃļvetkező forrÃĄsokbÃŗl: - * JSON. - * Cím paramÊterek. - * Query paramÊterek. - * Cookie-k. - * Header-Ãļk. - * Formok. - * FÃĄjlok. -* Kimeneti adatok ÃĄtvÃĄltÃĄsa: Python adatok is típusokrÃŗl hÃĄlÃŗzati adatokkÃĄ: - * vÃĄlts ÃĄt Python típusokat (`str`, `int`, `float`, `bool`, `list`, etc). - * `datetime` csak objektumokat. - * `UUID` objektumokat. - * AdatbÃĄzis modelleket. - * ...És sok mÃĄst. -* Automatikus interaktív dokumentÃĄciÃŗ, beleÊrtve kÊt alternatív dokumentÃĄciÃŗt is: - * Swagger UI. - * ReDoc. - ---- - -VisszatÊrve az előző kÃŗd pÊldÃĄhoz. A **FastAPI**: - -* ValidÃĄlja hogy van egy `item_id` mező a `GET` Ês `PUT` kÊrÊsekben. -* ValidÃĄlja hogy az `item_id` `int` típusÃē a `GET` Ês `PUT` kÊrÊsekben. - * Ha nem akkor lÃĄtni fogunk egy tiszta hibÃĄt ezzel kapcsolatban. -* ellenőrzi hogyha van egy opcionÃĄlis query paramÊter `q` nÊvvel (azaz `http://127.0.0.1:8000/items/foo?q=somequery`) `GET` kÊrÊsek esetÊn. - * Mivel a `q` paramÊter `= None`-al van deklarÃĄlva, ezÊrt opcionÃĄlis. - * `None` nÊlkÃŧl ez a mező kÃļtelező lenne (mint pÊldÃĄul a body `PUT` kÊrÊsek esetÊn). -* a `/items/{item_id}` címre Êrkező `PUT` kÊrÊsek esetÊn, a JSON-t a kÃļvetkezőkÊppen olvassa be: - * Ellenőrzi hogy lÊtezik a kÃļtelező `name` nevÅą attribÃētum Ês `string`. - * Ellenőrzi hogy lÊtezik a kÃļtelező `price` nevÅą attribÃētum Ês `float`. - * Ellenőrzi hogy lÊtezik a `is_offer` nevÅą opcionÃĄlis paramÊter, ami ha lÊtezik akkor `bool` - * Ez ÃĄgyazott JSON objektumokkal is mÅąkÃļdik -* JSONről valÃŗ automatikus konvertÃĄlÃĄs. -* dokumentÃĄljuk mindent OpenAPI-al amit hasznÃĄlhatÃŗ: - * Interaktív dokumentÃĄciÃŗs rendszerekkel. - * Automatikus kliens kÃŗd generÃĄlÃŗ a rendszerekkel, tÃļbb nyelven. -* HozzÃĄ tartozik kettő interaktív dokumentÃĄciÃŗs web felÃŧlet. - ---- - -Eddig csak a felszínt kapargattuk, de a lÊnyeg hogy most mÃĄr kÃļnnyebben Êrthető hogyan mÅąkÃļdik. - -PrÃŗbÃĄld kicserÊlni a kÃļvetkező sorban: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...ezt: - -```Python - ... "item_name": item.name ... -``` - -...erre: - -```Python - ... "item_price": item.price ... -``` - -... És figyeld meg hogy a szerkesztő automatikusan tudni fogja a típusokat Ês kiegÊszíti azokat: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -Teljesebb pÊldÃĄkÊrt Ês funkciÃŗkÊrt tekintsd meg a Tutorial - User Guide -t. - -**Spoiler veszÊly**: a Tutorial - User Guidehoz tartozik: - -* **ParamÊterek** deklarÃĄciÃŗja kÃŧlÃļnbÃļző helyekről: **header-Ãļk**, **cookie-k**, **form mezők** Ês **fÃĄjlok**. -* Hogyan ÃĄllíts be **validÃĄciÃŗs feltÊteleket** mint a `maximum_length` vagy a `regex`. -* Nagyon hatÊkony Ês erős **FÃŧggősÊg InjekciÃŗ** rendszerek. -* BiztonsÃĄg Ês autentikÃĄciÃŗ beleÊrtve, **OAuth2**, **JWT tokens** Ês **HTTP Basic** tÃĄmogatÃĄst. -* TÃļbb haladÃŗ (de ugyanannyira kÃļnnyÅą) technika **mÊlyen ÃĄgyazott JSON modellek deklarÃĄciÃŗjÃĄra** (Pydantic-nek kÃļszÃļnhetően). -* **GraphQL** integrÃĄciÃŗ Strawberry-vel Ês mÃĄs kÃļnyvtÃĄrakkal. -* tÃļbb extra funkciÃŗ (Starlette-nek kÃļszÃļnhetően) pl.: - * **WebSockets** - * rendkívÃŧl kÃļnnyÅą tesztek HTTPX Ês `pytest` alapokra Êpítve - * **CORS** - * **Cookie Sessions** - * ...Ês tÃļbb. - -## TeljesítmÊny - -A fÃŧggetlen TechEmpower benchmarkok szerint az Uvicorn alatt futÃŗ **FastAPI** alkalmazÃĄsok az egyik leggyorsabb Python keretrendszerek kÃļzÊ tartoznak, Êppen lemaradva a Starlette Ês az Uvicorn (melyeket a FastAPI belsőleg hasznÃĄl) mÃļgÃļtt.(*) - -Ezeknek a tovÃĄbbi megÊrtÊsÊhez: Benchmarks. - -## OpcionÃĄlis kÃļvetelmÊnyek - -Pydantic ÃĄltal hasznÃĄlt: - -* email-validator - e-mail validÃĄciÃŗkra. -* pydantic-settings - BeÃĄllítÃĄsok kÃļvetÊsÊre. -* pydantic-extra-types - Extra típusok Pydantic-hoz. - -Starlette ÃĄltal hasznÃĄlt: - -* httpx - KÃļvetelmÊny ha a `TestClient`-et akarod hasznÃĄlni. -* jinja2 - KÃļvetelmÊny ha az alap template konfigurÃĄciÃŗt akarod hasznÃĄlni. -* python-multipart - KÃļvetelmÊny ha "parsing"-ot akarsz tÃĄmogatni, `request.form()`-al. -* itsdangerous - KÃļvetelmÊny `SessionMiddleware` tÃĄmogatÃĄshoz. -* pyyaml - KÃļvetelmÊny a Starlette `SchemaGenerator`-ÃĄnak tÃĄmogatÃĄsÃĄhoz (valÃŗszínÅąleg erre nincs szÃŧksÊg FastAPI hasznÃĄlÃĄsa esetÊn). - -FastAPI / Starlette ÃĄltal hasznÃĄlt - -* uvicorn - Szerverekhez amíg betÃļltik Ês szolgÃĄltatjÃĄk az applikÃĄciÃŗdat. -* orjson - KÃļvetelmÊny ha `ORJSONResponse`-t akarsz hasznÃĄlni. -* ujson - KÃļvetelmÊny ha `UJSONResponse`-t akarsz hasznÃĄlni. - -Ezeket mind telepítheted a `pip install "fastapi[all]"` paranccsal. - -## Licensz -Ez a projekt az MIT license, licensz alatt fut diff --git a/docs/hu/mkdocs.yml b/docs/hu/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/hu/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/id/docs/index.md b/docs/id/docs/index.md deleted file mode 100644 index 5fb0c4c9c..000000000 --- a/docs/id/docs/index.md +++ /dev/null @@ -1,495 +0,0 @@ -# FastAPI - - - -

- FastAPI -

-

- FastAPI, framework performa tinggi, mudah dipelajari, cepat untuk coding, siap untuk pengembangan -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**Dokumentasi**: https://fastapi.tiangolo.com - -**Kode Sumber**: https://github.com/fastapi/fastapi - ---- - -FastAPI adalah *framework* *web* moderen, cepat (performa-tinggi) untuk membangun API dengan Python berdasarkan tipe petunjuk Python. - -Fitur utama FastAPI: - -* **Cepat**: Performa sangat tinggi, setara **NodeJS** dan **Go** (berkat Starlette dan Pydantic). [Salah satu *framework* Python tercepat yang ada](#performa). -* **Cepat untuk coding**: Meningkatkan kecepatan pengembangan fitur dari 200% sampai 300%. * -* **Sedikit bug**: Mengurangi hingga 40% kesalahan dari manusia (pemrogram). * -* **Intuitif**: Dukungan editor hebat. Penyelesaian di mana pun. Lebih sedikit *debugging*. -* **Mudah**: Dibuat mudah digunakan dan dipelajari. Sedikit waktu membaca dokumentasi. -* **Ringkas**: Mengurasi duplikasi kode. Beragam fitur dari setiap deklarasi parameter. Lebih sedikit *bug*. -* **Handal**: Dapatkan kode siap-digunakan. Dengan dokumentasi otomatis interaktif. -* **Standar-resmi**: Berdasarkan (kompatibel dengan ) standar umum untuk API: OpenAPI (sebelumnya disebut Swagger) dan JSON Schema. - -* estimasi berdasarkan pengujian tim internal pengembangan applikasi siap pakai. - -## Sponsor - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -Sponsor lainnya - -## Opini - -"_[...] Saya banyak menggunakan **FastAPI** sekarang ini. [...] Saya berencana menggunakannya di semua tim servis ML Microsoft. Beberapa dari mereka sudah mengintegrasikan dengan produk inti *Windows** dan sebagian produk **Office**._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_Kami adopsi library **FastAPI** untuk membuat server **REST** yang melakukan kueri untuk menghasilkan **prediksi**. [untuk Ludwig]_" - -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** dengan bangga mengumumkan rilis open-source orkestrasi framework **manajemen krisis** : **Dispatch**! [dibuat dengan **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_Saya sangat senang dengan **FastAPI**. Sangat menyenangkan!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_Jujur, apa yang anda buat sangat solid dan berkualitas. Ini adalah yang saya inginkan di **Hug** - sangat menginspirasi melihat seseorang membuat ini._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_Jika anda ingin mempelajari **framework moderen** untuk membangun REST API, coba **FastAPI** [...] cepat, mudah digunakan dan dipelajari [...]_" - -"_Kami sudah pindah ke **FastAPI** untuk **API** kami [...] Saya pikir kamu juga akan suka [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- -"_Jika anda ingin membuat API Python siap pakai, saya merekomendasikan **FastAPI**. FastAPI **didesain indah**, **mudah digunakan** dan **sangat scalable**, FastAPI adalah **komponen kunci** di strategi pengembangan API pertama kami dan mengatur banyak otomatisasi dan service seperti TAC Engineer kami._" - -
Deon Pillsbury - Cisco (ref)
- ---- - -## **Typer**, CLI FastAPI - - - -Jika anda mengembangkan app CLI yang digunakan di terminal bukan sebagai API web, kunjungi **Typer**. - -**Typer** adalah saudara kecil FastAPI. Dan ditujukan sebagai **CLI FastAPI**. âŒ¨ī¸ 🚀 - -## Prayarat - -FastAPI berdiri di pundak raksasa: - -* Starlette untuk bagian web. -* Pydantic untuk bagian data. - -## Instalasi - -Buat dan aktifkan virtual environment kemudian *install* FastAPI: - -
- -```console -$ pip install "fastapi[standard]" - ----> 100% -``` - -
- -**Catatan**: Pastikan anda menulis `"fastapi[standard]"` dengan tanda petik untuk memastikan bisa digunakan di semua *terminal*. - -## Contoh - -### Buat app - -* Buat file `main.py` dengan: - -```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} -``` - -
-Atau gunakan async def... - -Jika kode anda menggunakan `async` / `await`, gunakan `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} -``` - -**Catatan**: - -Jika anda tidak paham, kunjungi _"Panduan cepat"_ bagian `async` dan `await` di dokumentasi. - -
- -### Jalankan - -Jalankan *server* dengan: - -
- -```console -$ fastapi dev main.py - - ╭────────── FastAPI CLI - Development mode ───────────╮ - │ │ - │ Serving at: http://127.0.0.1:8000 │ - │ │ - │ API docs: http://127.0.0.1:8000/docs │ - │ │ - │ Running in development mode, for production use: │ - │ │ - │ fastapi run │ - │ │ - ╰─────────────────────────────────────────────────────╯ - -INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [2248755] using WatchFiles -INFO: Started server process [2248757] -INFO: Waiting for application startup. -INFO: Application startup complete. -``` - -
- -
-Mengenai perintah fastapi dev main.py... - -Perintah `fastapi dev` membaca file `main.py`, memeriksa app **FastAPI** di dalamnya, dan menjalan server dengan Uvicorn. - -Secara otomatis, `fastapi dev` akan mengaktifkan *auto-reload* untuk pengembangan lokal. - -Informasi lebih lanjut kunjungi Dokumen FastAPI CLI. - -
- -### Periksa - -Buka *browser* di http://127.0.0.1:8000/items/5?q=somequery. - -Anda akan melihat respon JSON berikut: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -Anda telah membuat API: - -* Menerima permintaan HTTP di _path_ `/` dan `/items/{item_id}`. -* Kedua _paths_ menerima operasi `GET` (juga disebut _metode_ HTTP). -* _path_ `/items/{item_id}` memiliki _parameter path_ `item_id` yang harus berjenis `int`. -* _path_ `/items/{item_id}` memiliki _query parameter_ `q` berjenis `str`. - -### Dokumentasi API interaktif - -Sekarang kunjungi http://127.0.0.1:8000/docs. - -Anda akan melihat dokumentasi API interaktif otomatis (dibuat oleh Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Dokumentasi API alternatif - -Kemudian kunjungi http://127.0.0.1:8000/redoc. - -Anda akan melihat dokumentasi alternatif otomatis (dibuat oleh ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## Contoh upgrade - -Sekarang ubah `main.py` untuk menerima struktur permintaan `PUT`. - -Deklarasikan struktur menggunakan tipe standar Python, berkat 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} -``` - -Server `fastapi dev` akan otomatis memuat kembali. - -### Upgrade dokumentasi API interaktif - -Kunjungi http://127.0.0.1:8000/docs. - -* Dokumentasi API interaktif akan otomatis diperbarui, termasuk kode yang baru: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Klik tombol "Try it out", anda dapat mengisi parameter dan langsung berinteraksi dengan API: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Kemudian klik tombol "Execute", tampilan pengguna akan berkomunikasi dengan API, mengirim parameter, mendapatkan dan menampilkan hasil ke layar: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Upgrade dokumentasi API alternatif - -Kunjungi http://127.0.0.1:8000/redoc. - -* Dokumentasi alternatif akan menampilkan parameter *query* dan struktur *request*: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Ringkasan - -Singkatnya, anda mendeklarasikan **sekali** jenis parameter, struktur, dll. sebagai parameter fungsi. - -Anda melakukannya dengan tipe standar moderen Python. - -Anda tidak perlu belajar sintaksis, metode, *classs* baru dari *library* tertentu, dll. - -Cukup **Python** standar. - -Sebagai contoh untuk `int`: - -```Python -item_id: int -``` - -atau untuk model lebih rumit `Item`: - -```Python -item: Item -``` - -...dengan sekali deklarasi anda mendapatkan: - -* Dukungan editor, termasuk: - * Pelengkapan kode. - * Pengecekan tipe. -* Validasi data: - * Kesalahan otomatis dan jelas ketika data tidak sesuai. - * Validasi hingga untuk object JSON bercabang mendalam. -* Konversi input data: berasal dari jaringan ke data dan tipe Python. Membaca dari: - * JSON. - * Parameter path. - * Parameter query. - * Cookie. - * Header. - * Form. - * File. -* Konversi output data: konversi data Python ke tipe jaringan data (seperti JSON): - * Konversi tipe Python (`str`, `int`, `float`, `bool`, `list`, dll). - * Objek `datetime`. - * Objek `UUID`. - * Model database. - * ...dan banyak lagi. -* Dokumentasi interaktif otomatis, termasuk 2 alternatif tampilan pengguna: - * Swagger UI. - * ReDoc. - ---- - -Kembali ke kode contoh sebelumnya, **FastAPI** akan: - -* Validasi apakah terdapat `item_id` di *path* untuk permintaan `GET` dan `PUT` requests. -* Validasi apakah `item_id` berjenit `int` untuk permintaan `GET` dan `PUT`. - * Jika tidak, klien akan melihat pesan kesalahan jelas. -* Periksa jika ada parameter *query* opsional bernama `q` (seperti `http://127.0.0.1:8000/items/foo?q=somequery`) untuk permintaan `GET`. - * Karena parameter `q` dideklarasikan dengan `= None`, maka bersifat opsional. - * Tanpa `None` maka akan menjadi wajib ada (seperti struktur di kondisi dengan `PUT`). -* Untuk permintaan `PUT` `/items/{item_id}`, membaca struktur sebagai JSON: - * Memeriksa terdapat atribut wajib `name` harus berjenis `str`. - * Memeriksa terdapat atribut wajib`price` harus berjenis `float`. - * Memeriksa atribut opsional `is_offer`, harus berjenis `bool`, jika ada. - * Semua ini juga sama untuk objek json yang bersarang mendalam. -* Konversi dari dan ke JSON secara otomatis. -* Dokumentasi segalanya dengan OpenAPI, dengan menggunakan: - * Sistem dokumentasi interaktif. - * Sistem otomatis penghasil kode, untuk banyak bahasa. -* Menyediakan 2 tampilan dokumentasi web interaktif dengan langsung. - ---- - -Kita baru menyentuh permukaannya saja, tetapi anda sudah mulai paham gambaran besar cara kerjanya. - -Coba ubah baris: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...dari: - -```Python - ... "item_name": item.name ... -``` - -...menjadi: - -```Python - ... "item_price": item.price ... -``` - -...anda akan melihat kode editor secara otomatis melengkapi atributnya dan tahu tipe nya: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -Untuk contoh lengkap termasuk fitur lainnya, kunjungi Tutorial - Panduan Pengguna. - -**Peringatan spoiler**: tutorial - panduan pengguna termasuk: - -* Deklarasi **parameter** dari tempat berbeda seperti: **header**, **cookie**, **form field** and **file**. -* Bagaimana mengatur **batasan validasi** seperti `maximum_length`atau `regex`. -* Sistem **Dependency Injection** yang hebat dan mudah digunakan. -* Keamanan dan autentikasi, termasuk dukungan ke **OAuth2** dengan **JWT token** dan autentikasi **HTTP Basic**. -* Teknik lebih aju (tetapi mudah dipakai untuk deklarasi **model JSON bersarang ke dalam** (berkat Pydantic). -* Integrasi **GraphQL** dengan Strawberry dan library lainnya. -* Fitur lainnya (berkat Starlette) seperti: - * **WebSocket** - * Test yang sangat mudah berdasarkan HTTPX dan `pytest` - * **CORS** - * **Cookie Session** - * ...dan lainnya. - -## Performa - -Tolok ukur Independent TechEmpower mendapati aplikasi **FastAPI** berjalan menggunakan Uvicorn sebagai salah satu framework Python tercepat yang ada, hanya di bawah Starlette dan Uvicorn itu sendiri (digunakan di internal FastAPI). (*) - -Penjelasan lebih lanjut, lihat bagian Tolok ukur. - -## Dependensi - -FastAPI bergantung pada Pydantic dan Starlette. - -### Dependensi `standar` - -Ketika anda meng-*install* FastAPI dengan `pip install "fastapi[standard]"`, maka FastAPI akan menggunakan sekumpulan dependensi opsional `standar`: - -Digunakan oleh Pydantic: - -* email-validator - untuk validasi email. - -Digunakan oleh Starlette: - -* httpx - Dibutuhkan jika anda menggunakan `TestClient`. -* jinja2 - Dibutuhkan jika anda menggunakan konfigurasi template bawaan. -* python-multipart - Dibutuhkan jika anda menggunakan form dukungan "parsing", dengan `request.form()`. - -Digunakan oleh FastAPI / Starlette: - -* uvicorn - untuk server yang memuat dan melayani aplikasi anda. Termasuk `uvicorn[standard]`, yang memasukan sejumlah dependensi (misal `uvloop`) untuk needed melayani dengan performa tinggi. -* `fastapi-cli` - untuk menyediakan perintah `fastapi`. - -### Tanpda dependensi `standard` - -Jika anda tidak ingin menambahkan dependensi opsional `standard`, anda dapat menggunakan `pip install fastapi` daripada `pip install "fastapi[standard]"`. - -### Dependensi Opsional Tambahan - -Ada beberapa dependensi opsional yang bisa anda install. - -Dependensi opsional tambahan Pydantic: - -* pydantic-settings - untuk manajemen setting. -* pydantic-extra-types - untuk tipe tambahan yang digunakan dengan Pydantic. - -Dependensi tambahan opsional FastAPI: - -* orjson - Diperlukan jika anda akan menggunakan`ORJSONResponse`. -* ujson - Diperlukan jika anda akan menggunakan `UJSONResponse`. - -## Lisensi - -Project terlisensi dengan lisensi MIT. diff --git a/docs/id/docs/tutorial/first-steps.md b/docs/id/docs/tutorial/first-steps.md deleted file mode 100644 index 9b461507d..000000000 --- a/docs/id/docs/tutorial/first-steps.md +++ /dev/null @@ -1,332 +0,0 @@ -# Langkah Pertama - -File FastAPI yang paling sederhana bisa seperti berikut: - -{* ../../docs_src/first_steps/tutorial001.py *} - -Salin file tersebut ke `main.py`. - -Jalankan di server: - -
- -```console -$ fastapi dev main.py -INFO Using path main.py -INFO Resolved absolute path /home/user/code/awesomeapp/main.py -INFO Searching for package file structure from directories with __init__.py files -INFO Importing from /home/user/code/awesomeapp - - ╭─ Python module file ─╮ - │ │ - │ 🐍 main.py │ - │ │ - ╰──────────────────────╯ - -INFO Importing module main -INFO Found importable FastAPI app - - ╭─ Importable FastAPI app ─╮ - │ │ - │ from main import app │ - │ │ - ╰──────────────────────────╯ - -INFO Using import string main:app - - ╭────────── FastAPI CLI - Development mode ───────────╮ - │ │ - │ Serving at: http://127.0.0.1:8000 │ - │ │ - │ API docs: http://127.0.0.1:8000/docs │ - │ │ - │ Running in development mode, for production use: │ - │ │ - │ fastapi run │ - │ │ - ╰─────────────────────────────────────────────────────╯ - -INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [2265862] using WatchFiles -INFO: Started server process [2265873] -INFO: Waiting for application startup. -INFO: Application startup complete. -``` - -
- -Di output, terdapat sebaris pesan: - -```hl_lines="4" -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -Baris tersebut menunjukan URL dimana app aktif di komputer anda. - - -### Mencoba aplikasi - -Buka browser di http://127.0.0.1:8000. - -Anda akan melihat response JSON sebagai berikut: - -```JSON -{"message": "Hello World"} -``` - -### Dokumen API interaktif - -Sekarang kunjungi http://127.0.0.1:8000/docs. - -Anda akan melihat dokumentasi API interaktif otomatis (dibuat oleh Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Dokumen API alternatif - -Dan sekarang, kunjungi http://127.0.0.1:8000/redoc. - -Anda akan melihat dokumentasi alternatif otomatis (dibuat oleh ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -### OpenAPI - -**FastAPI** membuat sebuah "schema" dimana semua API anda menggunakan standar **OpenAPI** untuk mendefinisikan API. - -#### "Schema" - -"schema" adalah suatu definisi atau deskripsi dari sesuatu. Bukan kode yang mengimplementasi definisi tersebut. Ini hanyalah sebuah deskripsi abstrak. - -#### "schema" API - -Dalam hal ini, OpenAPI adalah spesifikasi yang menunjukan bagaimana untuk mendefinisikan sebuah skema di API anda. - -Definisi skema ini termasuk jalur API anda, parameter yang bisa diterima, dll. - -#### "schema" Data - -Istilah "schema" bisa juga merujuk ke struktur data, seperti konten JSON. - -Dalam kondisi ini, ini berarti attribut JSON dan tipe data yang dimiliki, dll. - -#### Schema OpenAPI and JSON - -"schema" OpenAPI mendefinisikan skema API dari API yang anda buat. Skema tersebut termasuk definisi (atau "schema") dari data yang dikirim atau diterima oleh API dari **JSON Schema**, skema data standar JSON. - -#### Lihat `openapi.json` - -Jika anda penasaran bagaimana skema OpenAPI polos seperti apa, FastAPI secara otomatis membuat JSON (schema) dengan deksripsi API anda. - -anda bisa melihatnya di: http://127.0.0.1:8000/openapi.json. - -Anda akan melihat JSON yang dimulai seperti: - -```JSON -{ - "openapi": "3.1.0", - "info": { - "title": "FastAPI", - "version": "0.1.0" - }, - "paths": { - "/items/": { - "get": { - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - - - -... -``` - -#### Kegunaan OpenAPI - -Skema OpenAPI adalah tulang punggung dua sistem dokumentasi API interaktif yang ada di FastAPI. - -Ada banyak alternatif sistem dokumentasi lainnya yang semuanya berdasarkan OpenAPI. Anda bisa menambahkannya ke aplikasi **FastAPI** anda. - -Anda juga bisa menggunakan OpenAPI untuk membuat kode secara otomatis, untuk klien yang menggunakan API anda. Sebagai contoh, frontend, aplikasi mobile atau IoT. - -## Ringkasan, secara bertahap - -### Langkah 1: impor `FastAPI` - -{* ../../docs_src/first_steps/tutorial001.py hl[1] *} - -`FastAPI` adalah class Python yang menyediakan semua fungsionalitas API anda. - -/// note | Detail Teknis - -`FastAPI` adalah class turunan langsung dari `Starlette`. - -Anda bisa menggunakan semua fungsionalitas Starlette dengan `FastAPI` juga. - -/// - -### Langkah 2: buat "instance" dari `FastAPI` - -{* ../../docs_src/first_steps/tutorial001.py hl[3] *} - -Di sini variabel `app` akan menjadi sebuah "instance" dari class `FastAPI`. - -Ini akan menjadi gerbang utama untuk membuat semua API anda. - -### Langkah 3: Buat *operasi path* - -#### Path - -"Path" atau jalur di sini merujuk ke bagian URL terakhir dimulai dari `/` pertama. - -Sehingga, URL seperti: - -``` -https://example.com/items/foo -``` - -...path-nya adalah: - -``` -/items/foo -``` - -/// info - -"path" juga biasa disebut "endpoint" atau "route". - -/// - -ketika membuat API, "path" adalah jalan utama untuk memisahkan "concern" dan "resources". - -#### Operasi - -"Operasi" di sini merujuk ke salah satu dari metode HTTP berikut. - -Salah satu dari: - -* `POST` -* `GET` -* `PUT` -* `DELETE` - -...dan operasi lainnya yang unik: - -* `OPTIONS` -* `HEAD` -* `PATCH` -* `TRACE` - -Dalam protokol HTTP, anda bisa berkomunikasi ke setiap path menggunakan satu (atau lebih) metode di atas. - ---- - -Ketika membuat API, anda umumnya menggunakan metode HTTP tertentu untuk proses tertentu. - -Umumnya menggunakan: - -* `POST`: untuk membuat data. -* `GET`: untuk membaca data. -* `PUT`: untuk memperbarui data. -* `DELETE`: untuk menghapus data. - -Sehingga, di OpanAPI, setiap metode HTTP ini disebut sebuah "operasi". - -Kita akan menyebut mereka juga "**operasi**". - -#### Mendefinisikan *dekorator operasi path* - -{* ../../docs_src/first_steps/tutorial001.py hl[6] *} - -`@app.get("/")` memberitahu **FastAPI** bahwa fungsi di bawahnya mengurusi request yang menuju ke: - -* path `/` -* menggunakan operasi get - -/// info | `@decorator` Info - -Sintaksis `@sesuatu` di Python disebut "dekorator". - -Dekorator ditempatkan di atas fungsi. Seperti sebuah topi cantik (Saya pikir istilah ini berasal dari situ). - -"dekorator" memanggil dan bekerja dengan fungsi yang ada di bawahnya - -Pada kondisi ini, dekorator ini memberi tahu **FastAPI** bahwa fungsi di bawah nya berhubungan dengan **path** `/` dengan **operasi** `get`. - -Sehingga disebut **dekorator operasi path**. - -/// - -Operasi lainnya yang bisa digunakan: - -* `@app.post()` -* `@app.put()` -* `@app.delete()` - -Dan operasi unik lainnya: - -* `@app.options()` -* `@app.head()` -* `@app.patch()` -* `@app.trace()` - -/// tip | Tips - -Jika anda bisa menggunakan operasi apa saja (metode HTTP). - -**FastAPI** tidak mengharuskan anda menggunakan operasi tertentu. - -Informasi di sini hanyalah sebagai panduan, bukan keharusan. - -Sebagai contoh, ketika menggunakan GraphQL, semua operasi umumnya hanya menggunakan `POST`. - -/// - -### Langkah 4: mendefinisikan **fungsi operasi path** - -Ini "**fungsi operasi path**" kita: - -* **path**: adalah `/`. -* **operasi**: adalah `get`. -* **fungsi**: adalah fungsi yang ada di bawah dekorator (di bawah `@app.get("/")`). - -{* ../../docs_src/first_steps/tutorial001.py hl[7] *} - -Ini adalah fungsi Python. - -Fungsi ini dipanggil **FastAPI** setiap kali menerima request ke URL "`/`" dengan operasi `GET`. - -Di kondisi ini, ini adalah sebuah fungsi `async`. - ---- - -Anda bisa mendefinisikan fungsi ini sebagai fungsi normal daripada `async def`: - -{* ../../docs_src/first_steps/tutorial003.py hl[7] *} - -/// note | Catatan - -Jika anda tidak tahu perbedaannya, kunjungi [Async: *"Panduan cepat"*](../async.md#in-a-hurry){.internal-link target=_blank}. - -/// - -### Langkah 5: hasilkan konten - -{* ../../docs_src/first_steps/tutorial001.py hl[8] *} - -Anda bisa menghasilkan `dict`, `list`, nilai singular seperti `str`, `int`, dll. - -Anda juga bisa menghasilkan model Pydantic (anda akan belajar mengenai ini nanti). - -Ada banyak objek dan model yang secara otomatis dikonversi ke JSON (termasuk ORM, dll). Anda bisa menggunakan yang anda suka, kemungkinan sudah didukung. - -## Ringkasan - -* Impor `FastAPI`. -* Buat sebuah instance `app`. -* Tulis **dekorator operasi path** menggunakan dekorator seperti `@app.get("/")`. -* Definisikan **fungsi operasi path**; sebagai contoh, `def root(): ...`. -* Jalankan server development dengan perintah `fastapi dev`. diff --git a/docs/id/docs/tutorial/index.md b/docs/id/docs/tutorial/index.md deleted file mode 100644 index c01ec9a89..000000000 --- a/docs/id/docs/tutorial/index.md +++ /dev/null @@ -1,83 +0,0 @@ -# Tutorial - Pedoman Pengguna - Pengenalan - -Tutorial ini menunjukan cara menggunakan ***FastAPI*** dengan semua fitur-fiturnya, tahap demi tahap. - -Setiap bagian dibangun secara bertahap dari bagian sebelumnya, tetapi terstruktur untuk memisahkan banyak topik, sehingga kamu bisa secara langsung menuju ke topik spesifik untuk menyelesaikan kebutuhan API tertentu. - -Ini juga dibangun untuk digunakan sebagai referensi yang akan datang. - -Sehingga kamu dapat kembali lagi dan mencari apa yang kamu butuhkan dengan tepat. - -## Jalankan kode - -Semua blok-blok kode dapat disalin dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji). - -Untuk menjalankan setiap contoh, salin kode ke file `main.py`, dan jalankan `uvicorn` dengan: - -
- -```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. -``` - -
- -**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. - ---- - -## Install FastAPI - -Langkah pertama adalah dengan meng-install FastAPI. - -Untuk tutorial, kamu mungkin hendak meng-installnya dengan semua pilihan fitur dan dependensinya: - -
- -```console -$ pip install "fastapi[all]" - ----> 100% -``` - -
- -...yang juga termasuk `uvicorn`, yang dapat kamu gunakan sebagai server yang menjalankan kodemu. - -/// note | Catatan - -Kamu juga dapat meng-installnya bagian demi bagian. - -Hal ini mungkin yang akan kamu lakukan ketika kamu hendak menyebarkan (men-deploy) aplikasimu ke tahap produksi: - -``` -pip install fastapi -``` - -Juga install `uvicorn` untuk menjalankan server" - -``` -pip install "uvicorn[standard]" -``` - -Dan demikian juga untuk pilihan dependensi yang hendak kamu gunakan. - -/// - -## Pedoman Pengguna Lanjutan - -Tersedia juga **Pedoman Pengguna Lanjutan** yang dapat kamu baca nanti setelah **Tutorial - Pedoman Pengguna** ini. - -**Pedoman Pengguna Lanjutan**, dibangun atas hal ini, menggunakan konsep yang sama, dan mengajarkan kepadamu beberapa fitur tambahan. - -Tetapi kamu harus membaca terlebih dahulu **Tutorial - Pedoman Pengguna** (apa yang sedang kamu baca sekarang). - -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**. diff --git a/docs/id/docs/tutorial/path-params.md b/docs/id/docs/tutorial/path-params.md deleted file mode 100644 index 7c24de4d3..000000000 --- a/docs/id/docs/tutorial/path-params.md +++ /dev/null @@ -1,258 +0,0 @@ -# Parameter Path - -"parameter" atau "variabel" path didefinisikan dengan sintaksis Python format string: - -{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} - -Nilai parameter path `item_id` akan dikirim ke fungsi sebagai argument `item_id`: - -Jika anda menjalankan contoh berikut dan kunjungi http://127.0.0.1:8000/items/foo, anda akan melihat respon: - -```JSON -{"item_id":"foo"} -``` - -## Parameter path dengan tipe data - -Tipe data parameter path bisa didefinisikan di dalam fungsi, menggunakan anotasi tipe data standar Python: - -{* ../../docs_src/path_params/tutorial002.py hl[7] *} - -Dalam hal ini `item_id` didefinisikan sebagai `int`. - -/// check | Periksa - -Penyunting kode anda bisa membantu periksa di dalam fungsi seperti pemeriksaan kesalahan, kelengkapan kode, dll. - -/// - -## Konversi data - -Jika contoh berikut dijalankan dan diakses browser melalui http://127.0.0.1:8000/items/3, anda akan melihat respon: - -```JSON -{"item_id":3} -``` - -/// check | Periksa - -Perhatikan nilai fungsi yang diterima (dan dihasilkan) adalah `3`, sebagai `int` di Python, dan bukan string `"3"`. - -Sehingga dengan deklarasi tipe data **FastAPI** memberikan request otomatis "parsing". - -/// - -## Validasi Data - -Tetapi jika di browser anda akses http://127.0.0.1:8000/items/foo, anda akan melihat pesan kesalahan HTTP: - -```JSON -{ - "detail": [ - { - "type": "int_parsing", - "loc": [ - "path", - "item_id" - ], - "msg": "Input should be a valid integer, unable to parse string as an integer", - "input": "foo", - "url": "https://errors.pydantic.dev/2.1/v/int_parsing" - } - ] -} -``` - -Karena parameter path `item_id` bernilai `"foo"` yang bukan tipe data `int`. - -Kesalahan yang sama akan muncul jika menggunakan `float` daripada `int`, seperti di: http://127.0.0.1:8000/items/4.2 - -/// check | Periksa - -Dengan deklarasi tipe data Python, **FastAPI** melakukan validasi data. - -Perhatikan kesalahan tersebut juga menjelaskan validasi apa yang tidak sesuai. - -Validasi ini sangat membantu ketika mengembangkan dan men-*debug* kode yang berhubungan dengan API anda. - -/// - -## Dokumentasi - -Ketika anda membuka browser di http://127.0.0.1:8000/docs, anda melihat dokumentasi API interaktif otomatis berikut: - - - -/// check | Periksa - -Dengan deklarasi tipe data Python yang sama, **FastAPI** membuat dokumentasi interaktif otomatis (terintegrasi Swagger UI). - -Perhatikan parameter path dideklarasikan sebagai integer. - -/// - -## Keuntungan basis-standar, dokumentasi alternatif - -Karena skema yang dibuat berasal dari standar OpenAPI, maka banyak alat lain yang kompatibel. - -Sehingga **FastAPI** menyediakan dokumentasi alternatif (menggunakan ReDoc), yang bisa diakses di http://127.0.0.1:8000/redoc: - - - -Cara yang sama untuk menggunakan tools kompatibel lainnya. Termasuk alat membuat kode otomatis untuk banyak bahasa. - -## Pydantic - -Semua validasi data dikerjakan di belakang layar oleh Pydantic, sehingga anda mendapatkan banyak kemudahan. Anda juga tahu proses ini akan ditangani dengan baik. - -Anda bisa mendeklarasikan tipe data dengan `str`, `float`, `bool` dan banyak tipe data kompleks lainnya. - -Beberapa tipe di atas akan dibahas pada bab berikutnya tutorial ini. - -## Urutan berpengaruh - -Ketika membuat *operasi path*, anda bisa menghadapi kondisi dimana *path* nya sudah tetap. - -Seperti `/users/me`, untuk mendapatkan data user yang sedang aktif. - -Kemudian anda bisa memiliki path `/users/{user_id}` untuk mendapatkan data user tertentu melalui user ID. - -karena *operasi path* dievaluasi melalui urutan, anda harus memastikan path untuk `/users/me` dideklarasikan sebelum `/user/{user_id}`: - -{* ../../docs_src/path_params/tutorial003.py hl[6,11] *} - -Sebaliknya, path `/users/{user_id}` juga akan sesuai dengan `/users/me`, "menganggap" menerima parameter `user_id` dengan nilai `"me"`. - -Serupa, anda juga tidak bisa mendefinisikan operasi path: - -{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *} - -Path pertama akan selalu digunakan karena path sesuai dengan yang pertama. - -## Nilai terdefinisi - -Jika ada *operasi path* yang menerima *parameter path*, tetapi anda ingin nilai valid *parameter path* sudah terdefinisi, anda bisa menggunakan standar Python `Enum`. - -### Membuat class `Enum` - -Import `Enum` dan buat *sub-class* warisan dari `str` dan `Enum`. - -Dengan warisan dari `str` dokumen API mengetahui nilai nya harus berjenis `string` supaya bisa digunakan dengan benar. - -Kemudian buat atribut *class* dengan nilai tetap *string* yang benar: - -{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *} - -/// info - -Enumerasi (atau enum) tersedia di Python sejak versi 3.4. - -/// - -/// tip | Tips - -"AlxexNet", "ResNet", dan "LeNet" adalah nama model *Machine Learning*. - -/// - -### Mendeklarasikan *parameter path* - -Kemudian buat *parameter path* dengan tipe anotasi menggunakan *class* enum dari (`ModelName`) - -{* ../../docs_src/path_params/tutorial005.py hl[16] *} - -### Periksa dokumentasi - -Karena nilai yang tersedia untuk *parameter path* telah terdefinisi, dokumen interatik bisa memunculkan: - - - -### Bekerja dengan *enumarasi* Python - -Nilai *parameter path* akan menjadi *anggota enumerasi*. - -#### Membandingkan *anggota enumerasi* - -Anda bisa membandingkan parameter *path* dengan *anggota enumerasi* di enum `ModelName` yang anda buat: - -{* ../../docs_src/path_params/tutorial005.py hl[17] *} - -#### Mendapatkan *nilai enumerasi* - -Anda bisa mendapatkan nilai (`str` dalam kasus ini) menggunakan `model_name.value`, atau secara umum `anggota_enum_anda.value`: - -{* ../../docs_src/path_params/tutorial005.py hl[20] *} - -/// tip | Tips - -Anda bisa mengakses nilai `"lenet"` dnegan `ModelName.lenet.value`. - -/// - -#### Menghasilkan *anggota enumerasi* - -Anda bisa menghasilkan *anggota enumerasi* dari *operasi path* bahkan di body JSON bersarang (contoh `dict`). - -They will be converted to their corresponding values (strings in this case) before returning them to the client: - -{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *} - -Klien akan mendapatkan respon JSON seperti berikut: - -```JSON -{ - "model_name": "alexnet", - "message": "Deep Learning FTW!" -} -``` - -## Parameter path berisi path - -Misalkan terdapat *operasi path* dengan path `/files/{file_path}`. - -Tetapi anda memerlukan `file_path` itu berisi *path*, seperti like `home/johndoe/myfile.txt`. - -Sehingga URL untuk file tersebut akan seperti: `/files/home/johndoe/myfile.txt`. - -### Dukungan OpenAPI - -OpenAPI tidak bisa mendeklarasikan *parameter path* berisi *path* di dalamnya, karena menyebabkan kondisi yang sulit di*test* dan didefinisikan. - -Tetapi, di **FastAPI** anda tetap bisa melakukannya dengan menggunakan *tools* internal dari Starlette. - -Dan dokumentasi tetap berfungsi walaupun tidak menambahkan keterangan bahwa parameter harus berisi *path*. - -### Konverter path - -Melalui Starlette anda bisa mendeklarasikan *parameter path* berisi *path* dengan URL seperti: - -``` -/files/{file_path:path} -``` - -Dikondisi ini nama parameter adalah `file_path` dan bagian terakhir `:path` menginformasikan parameter harus sesuai dengan setiap *path*. - -Sehingga anda bisa menggunakan: - -{* ../../docs_src/path_params/tutorial004.py hl[6] *} - -/// tip | Tips - -Anda mungkin perlu parameter berisi `/home/johndoe/myfile.txt` di awali garis belakang (`/`). - -Di kondisi ini, URL nya menjadi: `/files//home/johndoe/myfile.txt`, dengan dua garis belakang (`//`) di antara `files` dan `home`. - -/// - -## Ringkasan - -Di **FastAPI** dengan menggunakan deklarasi tipe Python standar, pendek, intuitif, anda mendapatkan: - -* Dukungan editor: pemeriksaan kesalahan, autocompletion, dll. -* "Parsing" data. -* Validasi data. -* Annotasi API dan dokumentasi otomatis. - -Semua itu anda hanya perlu mendeklarasikan sekali saja. - -Ini adalah salah satu keunggulan **FastAPI** dibandingkan dengan *framework* lainnya (selain dari performa Python *native*c) diff --git a/docs/id/docs/tutorial/static-files.md b/docs/id/docs/tutorial/static-files.md deleted file mode 100644 index b55f31394..000000000 --- a/docs/id/docs/tutorial/static-files.md +++ /dev/null @@ -1,40 +0,0 @@ -# Berkas Statis - -Anda dapat menyajikan berkas statis secara otomatis dari sebuah direktori menggunakan `StaticFiles`. - -## Penggunaan `StaticFiles` - -* Mengimpor `StaticFiles`. -* "Mount" representatif `StaticFiles()` di jalur spesifik. - -{* ../../docs_src/static_files/tutorial001.py hl[2,6] *} - -/// note | Detail Teknis - -Anda dapat pula menggunakan `from starlette.staticfiles import StaticFiles`. - -**FastAPI** menyediakan `starlette.staticfiles` sama seperti `fastapi.staticfiles` sebagai kemudahan pada Anda, yaitu para pengembang. Tetapi ini asli berasal langsung dari Starlette. - -/// - -### Apa itu "Mounting" - -"Mounting" dimaksud menambah aplikasi "independen" secara lengkap di jalur spesifik, kemudian menangani seluruh sub-jalur. - -Hal ini berbeda dari menggunakan `APIRouter` karena aplikasi yang dimount benar-benar independen. OpenAPI dan dokumentasi dari aplikasi utama Anda tak akan menyertakan apa pun dari aplikasi yang dimount, dst. - -Anda dapat mempelajari mengenai ini dalam [Panduan Pengguna Lanjutan](../advanced/index.md){.internal-link target=_blank}. - -## Detail - -Terhadap `"/static"` pertama mengacu pada sub-jalur yang akan menjadi tempat "sub-aplikasi" ini akan "dimount". Maka, jalur apa pun yang dimulai dengan `"/static"` akan ditangani oleh sub-jalur tersebut. - -Terhadap `directory="static"` mengacu pada nama direktori yang berisi berkas statis Anda. - -Terhadap `name="static"` ialah nama yang dapat digunakan secara internal oleh **FastAPI**. - -Seluruh parameter ini dapat berbeda dari sekadar "`static`", sesuaikan parameter dengan keperluan dan detail spesifik akan aplikasi Anda. - -## Info lanjutan - -Sebagai detail dan opsi tambahan lihat dokumentasi Starlette perihal Berkas Statis. diff --git a/docs/id/mkdocs.yml b/docs/id/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/id/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/it/docs/index.md b/docs/it/docs/index.md deleted file mode 100644 index dc8f5b846..000000000 --- a/docs/it/docs/index.md +++ /dev/null @@ -1,463 +0,0 @@ -

- FastAPI -

-

- FastAPI framework, alte prestazioni, facile da imparare, rapido da implementare, pronto per il rilascio in produzione -

- -

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**Documentazione**: https://fastapi.tiangolo.com - -**Codice Sorgente**: https://github.com/fastapi/fastapi - ---- - -FastAPI è un web framework moderno e veloce (a prestazioni elevate) che serve a creare API con Python 3.6+ basato sulle annotazioni di tipo di Python. - -Le sue caratteristiche principali sono: - -* **Velocità**: Prestazioni molto elevate, alla pari di **NodeJS** e **Go** (grazie a Starlette e Pydantic). [Uno dei framework Python piÚ veloci in circolazione](#performance). -* **Veloce da programmare**: Velocizza il lavoro consentendo il rilascio di nuove funzionalità tra il 200% e il 300% piÚ rapidamente. * -* **Meno bug**: Riduce di circa il 40% gli errori che commettono gli sviluppatori durante la scrittura del codice. * -* **Intuitivo**: Grande supporto per gli editor di testo con autocompletamento in ogni dove. In questo modo si puÃ˛ dedicare meno tempo al debugging. -* **Facile**: Progettato per essere facile da usare e imparare. Si riduce il tempo da dedicare alla lettura della documentazione. -* **Sintentico**: Minimizza la duplicazione di codice. Molteplici funzionalità, ognuna con la propria dichiarazione dei parametri. Meno errori. -* **Robusto**: Crea codice pronto per la produzione con documentazione automatica interattiva. -* **Basato sugli standard**: Basato su (e completamente compatibile con) gli open standard per le API: OpenAPI (precedentemente Swagger) e JSON Schema. - -* Stima basata sull'esito di test eseguiti su codice sorgente di applicazioni rilasciate in produzione da un team interno di sviluppatori. - -## Sponsor - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -Altri sponsor - -## Recensioni - -"_[...] 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._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" - -
Piero Molino, Yaroslav Dudin, e Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_I’m over the moon excited about **FastAPI**. It’s so fun!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_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._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_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 [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- - -## **Typer**, la FastAPI delle CLI - - - -Se stai sviluppando un'app CLI da usare nel terminale invece che una web API, ti consigliamo **Typer**. - -**Typer** è il fratello minore di FastAPI. Ed è stato ideato per essere la **FastAPI delle CLI**. âŒ¨ī¸ 🚀 - -## Requisiti - -Python 3.6+ - -FastAPI è basata su importanti librerie: - -* Starlette per le parti web. -* Pydantic per le parti dei dati. - -## Installazione - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -Per il rilascio in produzione, sarà necessario un server ASGI come Uvicorn oppure Hypercorn. - -
- -```console -$ pip install uvicorn[standard] - ----> 100% -``` - -
- -## Esempio - -### Crea un file - -* Crea un file `main.py` con: - -```Python -from fastapi import FastAPI -from typing import Optional - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: str = Optional[None]): - return {"item_id": item_id, "q": q} -``` - -
-Oppure usa async def... - -Se il tuo codice usa `async` / `await`, allora usa `async def`: - -```Python hl_lines="7 12" -from fastapi import FastAPI -from typing import Optional - -app = FastAPI() - - -@app.get("/") -async def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -async def read_item(item_id: int, q: Optional[str] = None): - return {"item_id": item_id, "q": q} -``` - -**Nota**: - -e vuoi approfondire, consulta la sezione _"In a hurry?"_ su `async` e `await` nella documentazione. - -
- -### Esegui il server - -Puoi far partire il server cosÃŦ: - -
- -```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. -``` - -
- -
-Informazioni sul comando uvicorn main:app --reload... - -Vediamo il comando `uvicorn main:app` in dettaglio: - -* `main`: il file `main.py` (il "modulo" Python). -* `app`: l'oggetto creato dentro `main.py` con la riga di codice `app = FastAPI()`. -* `--reload`: ricarica il server se vengono rilevati cambiamenti del codice. Usalo solo durante la fase di sviluppo. - -
- -### Testa l'API - -Apri il browser all'indirizzo http://127.0.0.1:8000/items/5?q=somequery. - -Vedrai la seguente risposta JSON: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -Hai appena creato un'API che: - -* Riceve richieste HTTP sui _paths_ `/` and `/items/{item_id}`. -* Entrambi i _paths_ accettano`GET` operations (conosciuti anche come HTTP _methods_). -* Il _path_ `/items/{item_id}` ha un _path parameter_ `item_id` che deve essere un `int`. -* Il _path_ `/items/{item_id}` ha una `str` _query parameter_ `q`. - -### Documentazione interattiva dell'API - -Adesso vai all'indirizzo http://127.0.0.1:8000/docs. - -Vedrai la documentazione interattiva dell'API (offerta da Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Documentazione interattiva alternativa - -Adesso accedi all'url http://127.0.0.1:8000/redoc. - -Vedrai la documentazione interattiva dell'API (offerta da ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## Esempio piÚ avanzato - -Adesso modifica il file `main.py` per ricevere un _body_ da una richiesta `PUT`. - -Dichiara il _body_ usando le annotazioni di tipo standard di Python, grazie a Pydantic. - -```Python hl_lines="2 7-10 23-25" -from fastapi import FastAPI -from pydantic import BaseModel -from typing import Optional - -app = FastAPI() - - -class Item(BaseModel): - name: str - price: float - is_offer: bool = Optional[None] - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: Optional[str] = None): - return {"item_id": item_id, "q": q} - - -@app.put("/items/{item_id}") -def update_item(item_id: int, item: Item): - return {"item_name": item.name, "item_id": item_id} -``` - -Il server dovrebbe ricaricarsi in automatico (perchÊ hai specificato `--reload` al comando `uvicorn` lanciato precedentemente). - -### Aggiornamento della documentazione interattiva - -Adesso vai su http://127.0.0.1:8000/docs. - -* La documentazione interattiva dell'API verrà automaticamente aggiornata, includendo il nuovo _body_: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Fai click sul pulsante "Try it out", che ti permette di inserire i parametri per interagire direttamente con l'API: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Successivamente, premi sul pulsante "Execute". L'interfaccia utente comunicherà con la tua API, invierà i parametri, riceverà i risultati della richiesta, e li mostrerà sullo schermo: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Aggiornamento della documentazione alternativa - -Ora vai su http://127.0.0.1:8000/redoc. - -* Anche la documentazione alternativa dell'API mostrerà il nuovo parametro della query e il _body_: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Riepilogo - -Ricapitolando, è sufficiente dichiarare **una sola volta** i tipi dei parametri, del body, ecc. come parametri di funzioni. - -Questo con le annotazioni per i tipi standard di Python. - -Non c'è bisogno di imparare una nuova sintassi, metodi o classi specifici a una libreria, ecc. - -È normalissimo **Python 3.6+**. - -Per esempio, per un `int`: - -```Python -item_id: int -``` - -o per un modello `Item` piÚ complesso: - -```Python -item: Item -``` - -...e con quella singola dichiarazione hai in cambio: - -* Supporto per gli editor di testo, incluso: - * Autocompletamento. - * Controllo sulle annotazioni di tipo. -* Validazione dei dati: - * Errori chiari e automatici quando i dati sono invalidi. - * Validazione anche per gli oggetti JSON piÚ complessi. -* Conversione dei dati di input: da risorse esterne a dati e tipi di Python. È possibile leggere da: - * JSON. - * Path parameters. - * Query parameters. - * Cookies. - * Headers. - * Form. - * File. -* Conversione dei dati di output: converte dati e tipi di Python a dati per la rete (come JSON): - * Converte i tipi di Python (`str`, `int`, `float`, `bool`, `list`, ecc). - * Oggetti `datetime`. - * Oggetti `UUID`. - * Modelli del database. - * ...e molto di piÚ. -* Generazione di una documentazione dell'API interattiva, con scelta dell'interfaccia grafica: - * Swagger UI. - * ReDoc. - ---- - -Tornando al precedente esempio, **FastAPI**: - -* Validerà che esiste un `item_id` nel percorso delle richieste `GET` e `PUT`. -* Validerà che `item_id` sia di tipo `int` per le richieste `GET` e `PUT`. - * Se non lo è, il client vedrà un errore chiaro e utile. -* Controllerà se ci sia un parametro opzionale chiamato `q` (per esempio `http://127.0.0.1:8000/items/foo?q=somequery`) per le richieste `GET`. - * Siccome il parametro `q` è dichiarato con `= None`, è opzionale. - * Senza il `None` sarebbe stato obbligatorio (come per il body della richiesta `PUT`). -* Per le richieste `PUT` su `/items/{item_id}`, leggerà il body come JSON, questo comprende: - * verifica che la richiesta abbia un attributo obbligatorio `name` e che sia di tipo `str`. - * verifica che la richiesta abbia un attributo obbligatorio `price` e che sia di tipo `float`. - * verifica che la richiesta abbia un attributo opzionale `is_offer` e che sia di tipo `bool`, se presente. - * Tutto questo funzionerebbe anche con oggetti JSON piÚ complessi. -* Convertirà *da* e *a* JSON automaticamente. -* Documenterà tutto con OpenAPI, che puÃ˛ essere usato per: - * Sistemi di documentazione interattivi. - * Sistemi di generazione di codice dal lato client, per molti linguaggi. -* Fornirà 2 interfacce di documentazione dell'API interattive. - ---- - -Questa è solo la punta dell'iceberg, ma dovresti avere già un'idea di come il tutto funzioni. - -Prova a cambiare questa riga di codice: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...da: - -```Python - ... "item_name": item.name ... -``` - -...a: - -```Python - ... "item_price": item.price ... -``` - -...e osserva come il tuo editor di testo autocompleterà gli attributi e sarà in grado di riconoscere i loro tipi: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -Per un esempio piÚ completo che mostra piÚ funzionalità del framework, consulta Tutorial - Guida Utente. - -**Spoiler alert**: il tutorial - Guida Utente include: - -* Dichiarazione di **parameters** da altri posti diversi come: **headers**, **cookies**, **form fields** e **files**. -* Come stabilire **vincoli di validazione** come `maximum_length` o `regex`. -* Un sistema di **Dependency Injection** facile da usare e molto potente. -e potente. -* Sicurezza e autenticazione, incluso il supporto per **OAuth2** con **token JWT** e autenticazione **HTTP Basic**. -* Tecniche piÚ avanzate (ma ugualmente semplici) per dichiarare **modelli JSON altamente nidificati** (grazie a Pydantic). -* E altre funzionalità (grazie a Starlette) come: - * **WebSockets** - * **GraphQL** - * test molto facili basati su `requests` e `pytest` - * **CORS** - * **Cookie Sessions** - * ...e altro ancora. - -## Prestazioni - -Benchmark indipendenti di TechEmpower mostrano che **FastAPI** basato su Uvicorn è uno dei framework Python piÚ veloci in circolazione, solamente dietro a Starlette e Uvicorn (usate internamente da FastAPI). (*) - -Per approfondire, consulta la sezione Benchmarks. - -## Dipendenze opzionali - -Usate da Pydantic: - -* email-validator - per la validazione di email. - -Usate da Starlette: - -* requests - Richiesto se vuoi usare il `TestClient`. -* aiofiles - Richiesto se vuoi usare `FileResponse` o `StaticFiles`. -* jinja2 - Richiesto se vuoi usare la configurazione template di default. -* python-multipart - Richiesto se vuoi supportare il "parsing" con `request.form()`. -* itsdangerous - Richiesto per usare `SessionMiddleware`. -* pyyaml - Richiesto per il supporto dello `SchemaGenerator` di Starlette (probabilmente non ti serve con FastAPI). -* graphene - Richiesto per il supporto di `GraphQLApp`. - -Usate da FastAPI / Starlette: - -* uvicorn - per il server che carica e serve la tua applicazione. -* orjson - ichiesto se vuoi usare `ORJSONResponse`. -* ujson - Richiesto se vuoi usare `UJSONResponse`. - -Puoi installarle tutte con `pip install fastapi[all]`. - -## Licenza - -Questo progetto è concesso in licenza in base ai termini della licenza MIT. diff --git a/docs/it/mkdocs.yml b/docs/it/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/it/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/ja/docs/async.md b/docs/ja/docs/async.md index d1da1f82d..90a2e2ee5 100644 --- a/docs/ja/docs/async.md +++ b/docs/ja/docs/async.md @@ -338,7 +338,7 @@ async def read_burgers(): äģĨ前ぎバãƒŧã‚¸ãƒ§ãƒŗãŽPythonでは、゚ãƒŦッドやGeventãŒåˆŠį”¨ã§ããžã—ãŸã€‚ã—ã‹ã—ã€ã‚ŗãƒŧãƒ‰ã¯į†č§Ŗã€ãƒ‡ãƒãƒƒã‚¯ã€ãã—ãĻã€č€ƒå¯ŸãŒã¯ã‚‹ã‹ãĢč¤‡é›‘ã§ã™ã€‚ -äģĨ前ぎバãƒŧã‚¸ãƒ§ãƒŗãŽNodeJS / ブナã‚Ļã‚ļJavaScriptã§ã¯ã€ã€Œã‚ŗãƒŧãƒĢバック」をäŊŋį”¨ã—ãĻã„ãžã—ãŸã€‚ã“ã‚Œã¯ã€ã‚ŗãƒŧãƒĢãƒãƒƒã‚¯åœ°į„ãĢつãĒがりぞす。 +äģĨ前ぎバãƒŧã‚¸ãƒ§ãƒŗãŽNodeJS / ブナã‚Ļã‚ļJavaScriptã§ã¯ã€ã€Œã‚ŗãƒŧãƒĢバック」をäŊŋį”¨ã—ãĻã„ãžã—ãŸã€‚ã“ã‚Œã¯ã€ã€Œã‚ŗãƒŧãƒĢãƒãƒƒã‚¯åœ°į„ã€ãĢつãĒがりぞす。 ## ã‚ŗãƒĢãƒŧãƒãƒŗ diff --git a/docs/ja/docs/help-fastapi.md b/docs/ja/docs/help-fastapi.md index d999fa127..8cf0c2163 100644 --- a/docs/ja/docs/help-fastapi.md +++ b/docs/ja/docs/help-fastapi.md @@ -31,18 +31,18 @@ GitHubでFastAPIを「Watch」できぞす (åŗä¸Šéƒ¨ãŽWatchボã‚ŋãƒŗã‚’ã‚¯ãƒĒ * **GitHub** でフりロãƒŧ。 * äģ–ぎã‚Ēãƒŧãƒ—ãƒŗã‚Ŋãƒŧ゚プロジェクトをįĸēčĒã§ããžã™ã€‚äŊ•かぎ劊けãĢãĒるもぎがčĻ‹ã¤ã‹ã‚‹ã‹ã‚‚ã—ã‚Œãžã›ã‚“ã€‚ * 新たãĒã‚Ēãƒŧãƒ—ãƒŗã‚Ŋãƒŧ゚プロジェクトをäŊœæˆã—たときãĢ通įŸĨされぞす。 -* **Twitter** でフりロãƒŧ。 +* **X (Twitter)** でフりロãƒŧ。 * FastAPIぎäŊŋį”¨į”¨é€”ã‚’æ•™ãˆãĻください (čžã„ãĻãŋたいです)。 * 新たãĒツãƒŧãƒĢぎį™ēčĄ¨ã‚„ãƒĒãƒĒãƒŧã‚šãŒčžã‘ãžã™ã€‚ * **Linkedin** でつãĒがる。 - * 新たãĒツãƒŧãƒĢぎį™ēčĄ¨ã‚„ãƒĒãƒĒãƒŧã‚šãŒčžã‘ãžã™ (ただしTwitterãŽæ–šãŒåˆŠį”¨é ģåēĻがéĢ˜ã„ã§ã™ãŒ 🤷‍♂)。 + * 新たãĒツãƒŧãƒĢぎį™ēčĄ¨ã‚„ãƒĒãƒĒãƒŧã‚šãŒčžã‘ãžã™ (ただしX (Twitter)ãŽæ–šãŒåˆŠį”¨é ģåēĻがéĢ˜ã„ã§ã™ãŒ 🤷‍♂)。 * **Dev.to** や **Medium** ã§č‘—äŊœį‰Šã‚’čĒ­ã‚€ (ぞたはフりロãƒŧ)。 * ã‚ĸイデã‚ĸやäŊœæˆãƒ„ãƒŧãƒĢãĢついãĻãŽč¨˜äē‹ãŒčĒ­ã‚ãžã™ã€‚ * 新čĻč¨˜äē‹ãŽåŸˇį­†ã‚’通įŸĨしãĻくれぞす。 ## **FastAPI** ãĢé–ĸするツイãƒŧト -**FastAPI** ãĢついãĻツイãƒŧトし、開į™ēč€…ã‚„äģ–ぎäēēãĢおこが気ãĢå…ĨãŖãŸãŽã‹æ•™ãˆãĻãã ã•ã„ã€‚đŸŽ‰ +**FastAPI** ãĢついãĻツイãƒŧトし、開į™ēč€…ã‚„äģ–ぎäēēãĢおこが気ãĢå…ĨãŖãŸãŽã‹æ•™ãˆãĻãã ã•ã„ã€‚đŸŽ‰ **FastAPI** がおぎようãĢäŊŋわれ、おこが気ãĢå…Ĩられ、おんãĒプロジェクト/äŧšį¤žã§äŊŋわれãĻいるかãĒおãĢついãĻįŸĨりたいです。 diff --git a/docs/ja/docs/index.md b/docs/ja/docs/index.md index 1ba85f8e0..c4ff6beeb 100644 --- a/docs/ja/docs/index.md +++ b/docs/ja/docs/index.md @@ -88,7 +88,7 @@ FastAPI は、Pythonぎ標æē–ã§ã‚ã‚‹åž‹ãƒ’ãƒŗãƒˆãĢåŸēãĨいãĻPython äģĨ降 "_į§ã¯**FastAPI**ãĢワクワクしãĻいぞす。 ã‚ãĄã‚ƒããĄã‚ƒæĨŊしいですīŧ_" -
Brian Okken - Python Bytes podcast host (ref)
+
Brian Okken - Python Bytes podcast host (ref)
--- @@ -102,7 +102,7 @@ FastAPI は、Pythonぎ標æē–ã§ã‚ã‚‹åž‹ãƒ’ãƒŗãƒˆãĢåŸēãĨいãĻPython äģĨ降 "_į§ãŸãĄãŽ**API**は**FastAPI**ãĢ切りæ›ŋえぞした。[...] ããŖã¨æ°—ãĢå…Ĩると思いぞす。 [...]_" -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
+
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
--- diff --git a/docs/ja/docs/tutorial/body.md b/docs/ja/docs/tutorial/body.md index 8376959d5..1298eec7e 100644 --- a/docs/ja/docs/tutorial/body.md +++ b/docs/ja/docs/tutorial/body.md @@ -22,7 +22,7 @@ GET ãƒĒã‚¯ã‚¨ã‚šãƒˆã§ãƒœãƒ‡ã‚Ŗã‚’é€äŋĄã™ã‚‹ã“とは、ä앿§˜ã§ã¯æœĒåŽšįžŠ ぞす初めãĢ、 `pydantic` から `BaseModel` ã‚’ã‚¤ãƒŗãƒãƒŧトするåŋ…čĻãŒã‚ã‚Šãžã™: -{* ../../docs_src/body/tutorial001.py hl[2] *} +{* ../../docs_src/body/tutorial001.py hl[4] *} ## デãƒŧã‚ŋãƒĸデãƒĢぎäŊœæˆ @@ -30,7 +30,7 @@ GET ãƒĒã‚¯ã‚¨ã‚šãƒˆã§ãƒœãƒ‡ã‚Ŗã‚’é€äŋĄã™ã‚‹ã“とは、ä앿§˜ã§ã¯æœĒåŽšįžŠ すずãĻãŽåąžæ€§ãĢpython標æē–ぎ型をäŊŋį”¨ã—ãžã™: -{* ../../docs_src/body/tutorial001.py hl[5:9] *} +{* ../../docs_src/body/tutorial001.py hl[7:11] *} クエãƒĒãƒ‘ãƒŠãƒĄãƒŧã‚ŋãŽåŽŖč¨€ã¨åŒæ§˜ãĢ、ãƒĸデãƒĢåąžæ€§ãŒãƒ‡ãƒ•ã‚ŠãƒĢト値をもつとき、åŋ…é ˆãĒåąžæ€§ã§ã¯ãĒくãĒりぞす。それäģĨ外はåŋ…é ˆãĢãĒりぞす。ã‚Ēãƒ—ã‚ˇãƒ§ãƒŠãƒĢãĒåąžæ€§ãĢしたい場合は `None` をäŊŋį”¨ã—ãĻください。 @@ -58,7 +58,7 @@ GET ãƒĒã‚¯ã‚¨ã‚šãƒˆã§ãƒœãƒ‡ã‚Ŗã‚’é€äŋĄã™ã‚‹ã“とは、ä앿§˜ã§ã¯æœĒåŽšįžŠ *パ゚ã‚ĒペãƒŦãƒŧã‚ˇãƒ§ãƒŗ* ãĢ加えるためãĢã€ãƒ‘ã‚šãƒ‘ãƒŠãƒĄãƒŧã‚ŋやクエãƒĒãƒ‘ãƒŠãƒĄãƒŧã‚ŋと同じ様ãĢåŽŖč¨€ã—ãžã™: -{* ../../docs_src/body/tutorial001.py hl[16] *} +{* ../../docs_src/body/tutorial001.py hl[18] *} ...そしãĻ、äŊœæˆã—たãƒĸデãƒĢ `Item` ã§åž‹ã‚’åŽŖč¨€ã—ãžã™ã€‚ @@ -125,7 +125,7 @@ GET ãƒĒã‚¯ã‚¨ã‚šãƒˆã§ãƒœãƒ‡ã‚Ŗã‚’é€äŋĄã™ã‚‹ã“とは、ä앿§˜ã§ã¯æœĒåŽšįžŠ é–ĸ数内部で、ãƒĸデãƒĢぎ全ãĻãŽåąžæ€§ãĢį›´æŽĨã‚ĸクã‚ģ゚できぞす: -{* ../../docs_src/body/tutorial002.py hl[19] *} +{* ../../docs_src/body/tutorial002.py hl[21] *} ## ãƒĒã‚¯ã‚¨ã‚šãƒˆãƒœãƒ‡ã‚Ŗ + ãƒ‘ã‚šãƒ‘ãƒŠãƒĄãƒŧã‚ŋ @@ -133,7 +133,7 @@ GET ãƒĒã‚¯ã‚¨ã‚šãƒˆã§ãƒœãƒ‡ã‚Ŗã‚’é€äŋĄã™ã‚‹ã“とは、ä앿§˜ã§ã¯æœĒåŽšįžŠ **FastAPI** ã¯ãƒ‘ã‚šãƒ‘ãƒŠãƒĄãƒŧã‚ŋであるé–ĸæ•°ãƒ‘ãƒŠãƒĄãƒŧã‚ŋは**パ゚から受け取り**、PydanticãƒĸデãƒĢãĢã‚ˆãŖãĻåŽŖč¨€ã•ã‚ŒãŸé–ĸæ•°ãƒ‘ãƒŠãƒĄãƒŧã‚ŋは**ãƒĒã‚¯ã‚¨ã‚šãƒˆãƒœãƒ‡ã‚Ŗã‹ã‚‰å—ã‘å–ã‚‹**ということをčĒč­˜ã—ãžã™ã€‚ -{* ../../docs_src/body/tutorial003.py hl[15:16] *} +{* ../../docs_src/body/tutorial003.py hl[17:18] *} ## ãƒĒã‚¯ã‚¨ã‚šãƒˆãƒœãƒ‡ã‚Ŗ + ãƒ‘ã‚šãƒ‘ãƒŠãƒĄãƒŧã‚ŋ + クエãƒĒãƒ‘ãƒŠãƒĄãƒŧã‚ŋ @@ -141,7 +141,7 @@ GET ãƒĒã‚¯ã‚¨ã‚šãƒˆã§ãƒœãƒ‡ã‚Ŗã‚’é€äŋĄã™ã‚‹ã“とは、ä앿§˜ã§ã¯æœĒåŽšįžŠ **FastAPI** はそれぞれをčĒč­˜ã—ã€éŠåˆ‡ãĒ場所からデãƒŧã‚ŋを取垗しぞす。 -{* ../../docs_src/body/tutorial004.py hl[16] *} +{* ../../docs_src/body/tutorial004.py hl[18] *} é–ĸæ•°ãƒ‘ãƒŠãƒĄãƒŧã‚ŋはäģĨ下ぎ様ãĢčĒč­˜ã•ã‚Œãžã™: diff --git a/docs/ja/docs/tutorial/security/index.md b/docs/ja/docs/tutorial/security/index.md index 37b8bb958..14f2c8f44 100644 --- a/docs/ja/docs/tutorial/security/index.md +++ b/docs/ja/docs/tutorial/security/index.md @@ -22,7 +22,7 @@ OAuth2は、čĒč¨ŧとčĒå¯ã‚’å‡Ļį†ã™ã‚‹ãŸã‚ãŽã„ãã¤ã‹ãŽæ–šæŗ•ã‚’åŽš これãĢは「ã‚ĩãƒŧドパãƒŧãƒ†ã‚Ŗã€ã‚’äŊŋį”¨ã—ãĻčĒč¨ŧã™ã‚‹æ–šæŗ•ãŒåĢぞれãĻいぞす。 -これが、「Facebook、Google、Twitter、GitHubをäŊŋãŖãĻãƒ­ã‚°ã‚¤ãƒŗã€ã‚’äŊŋį”¨ã—ãŸã™ãšãĻãŽã‚ˇã‚šãƒ†ãƒ ãŽčƒŒåžŒã§äŊŋわれãĻいるäģ•įĩ„ãŋです。 +これが、「Facebook、Google、X (Twitter)、GitHubをäŊŋãŖãĻãƒ­ã‚°ã‚¤ãƒŗã€ã‚’äŊŋį”¨ã—ãŸã™ãšãĻãŽã‚ˇã‚šãƒ†ãƒ ãŽčƒŒåžŒã§äŊŋわれãĻいるäģ•įĩ„ãŋです。 ### OAuth 1 @@ -79,7 +79,7 @@ OpenAPIでは、äģĨ下ぎã‚ģキãƒĨãƒĒãƒ†ã‚Ŗã‚šã‚­ãƒŧãƒ ã‚’åŽšįžŠã—ãĻいぞす: * HTTP BasicčĒč¨ŧ * HTTP ダイジェ゚トčĒč¨ŧãĒお * `oauth2`: OAuth2ぎã‚ģキãƒĨãƒĒãƒ†ã‚Ŗå‡Ļį†æ–šæŗ•īŧˆã€Œãƒ•ロãƒŧ」とå‘ŧばれぞすīŧ‰ãŽã™ãšãĻ。 - * これらぎフロãƒŧぎいくつかは、OAuth 2.0čĒč¨ŧプロバイダīŧˆGoogle、Facebook、Twitter、GitHubãĒおīŧ‰ã‚’æ§‹į¯‰ã™ã‚‹ãŽãĢ遊しãĻいぞす。 + * これらぎフロãƒŧぎいくつかは、OAuth 2.0čĒč¨ŧプロバイダīŧˆGoogle、Facebook、X (Twitter)、GitHubãĒおīŧ‰ã‚’æ§‹į¯‰ã™ã‚‹ãŽãĢ遊しãĻいぞす。 * `implicit` * `clientCredentials` * `authorizationCode` @@ -91,7 +91,7 @@ OpenAPIでは、äģĨ下ぎã‚ģキãƒĨãƒĒãƒ†ã‚Ŗã‚šã‚­ãƒŧãƒ ã‚’åŽšįžŠã—ãĻいぞす: /// tip | 豆įŸĨ識 -Google、Facebook、Twitter、GitHubãĒお、äģ–ぎčĒč¨ŧ/čĒå¯ãƒ—ãƒ­ãƒã‚¤ãƒ€ã‚’įĩąåˆã™ã‚‹ã“とも可čƒŊで、比čŧƒįš„į°Ąå˜ã§ã™ã€‚ +Google、Facebook、X (Twitter)、GitHubãĒお、äģ–ぎčĒč¨ŧ/čĒå¯ãƒ—ãƒ­ãƒã‚¤ãƒ€ã‚’įĩąåˆã™ã‚‹ã“とも可čƒŊで、比čŧƒįš„į°Ąå˜ã§ã™ã€‚ æœ€ã‚‚č¤‡é›‘ãĒå•éĄŒã¯ã€ãã‚Œã‚‰ãŽã‚ˆã†ãĒčĒč¨ŧ/čĒå¯ãƒ—ãƒ­ãƒã‚¤ãƒ€ã‚’æ§‹į¯‰ã™ã‚‹ã“ã¨ã§ã™ãŒã€**FastAPI**は、あãĒたぎためãĢ重いäģ•äē‹ã‚’こãĒしãĒãŒã‚‰ã€ãã‚Œã‚’į°Ąå˜ãĢčĄŒã†ãŸã‚ãŽãƒ„ãƒŧãƒĢを提䞛しぞす。 diff --git a/docs/ja/docs/tutorial/security/oauth2-jwt.md b/docs/ja/docs/tutorial/security/oauth2-jwt.md index 4859819cc..599fc7b06 100644 --- a/docs/ja/docs/tutorial/security/oauth2-jwt.md +++ b/docs/ja/docs/tutorial/security/oauth2-jwt.md @@ -272,4 +272,4 @@ OAuth2ãĢã¯ã€ã€Œã‚šã‚ŗãƒŧプ」というæĻ‚åŋĩがありぞす。 ぞた、OAuth2ぎようãĒ厉全で標æē–įš„ãĒãƒ—ãƒ­ãƒˆã‚ŗãƒĢを比čŧƒįš„į°Ąå˜ãĒæ–šæŗ•ã§äŊŋį”¨ã§ãã‚‹ã ã‘ã§ã¯ãĒãã€åŽŸčŖ…ã™ã‚‹ã“ã¨ã‚‚ã§ããžã™ã€‚ -OAuth2ãŽã€Œã‚šã‚ŗãƒŧプ」をäŊŋãŖãĻ、同じåŸēæē–ã§ã‚ˆã‚Šį´°ã‹ã„æ¨Šé™ã‚ˇã‚šãƒ†ãƒ ã‚’åŽŸįžã™ã‚‹æ–šæŗ•ãĢついãĻは、**é̘åēĻãĒãƒĻãƒŧã‚ļãƒŧã‚Ŧイド**ã§čŠŗã—ãčĒŦ明しãĻã„ãžã™ã€‚ã‚šã‚ŗãƒŧプäģ˜ããŽOAuth2は、Facebook、Google、GitHub、Microsoft、TwitterãĒお、多くぎ大手čĒč¨ŧプロバイダが、ã‚ĩãƒŧドパãƒŧãƒ†ã‚ŖãŽã‚ĸプãƒĒã‚ąãƒŧã‚ˇãƒ§ãƒŗã¨č‡Ēį¤žãŽAPIとぎやり取りをãƒĻãƒŧã‚ļãƒŧãĢäģŖã‚ãŖãĻčĒå¯ã™ã‚‹ãŸã‚ãĢäŊŋį”¨ã—ãĻいるäģ•įĩ„ãŋです。 +OAuth2ãŽã€Œã‚šã‚ŗãƒŧプ」をäŊŋãŖãĻ、同じåŸēæē–ã§ã‚ˆã‚Šį´°ã‹ã„æ¨Šé™ã‚ˇã‚šãƒ†ãƒ ã‚’åŽŸįžã™ã‚‹æ–šæŗ•ãĢついãĻは、**é̘åēĻãĒãƒĻãƒŧã‚ļãƒŧã‚Ŧイド**ã§čŠŗã—ãčĒŦ明しãĻã„ãžã™ã€‚ã‚šã‚ŗãƒŧプäģ˜ããŽOAuth2は、Facebook、Google、GitHub、Microsoft、X (Twitter)ãĒお、多くぎ大手čĒč¨ŧプロバイダが、ã‚ĩãƒŧドパãƒŧãƒ†ã‚ŖãŽã‚ĸプãƒĒã‚ąãƒŧã‚ˇãƒ§ãƒŗã¨č‡Ēį¤žãŽAPIとぎやり取りをãƒĻãƒŧã‚ļãƒŧãĢäģŖã‚ãŖãĻčĒå¯ã™ã‚‹ãŸã‚ãĢäŊŋį”¨ã—ãĻいるäģ•įĩ„ãŋです。 diff --git a/docs/ko/docs/async.md b/docs/ko/docs/async.md index fa0d20488..ec503d540 100644 --- a/docs/ko/docs/async.md +++ b/docs/ko/docs/async.md @@ -349,7 +349,7 @@ FastAPIëĨŧ ė‚ŦėšŠí•˜ė§€ ė•Šë”ëŧ도, ë†’ė€ í˜¸í™˜ė„ą 및 GeventëĨŧ ė‚ŦėšŠí•  눘 ėžˆė„ ę˛ƒėž…ë‹ˆë‹¤. í•˜ė§€ë§Œ ėŊ”드ëĨŧ ė´í•´í•˜ęŗ , ë””ë˛„ęš…í•˜ęŗ , ė´ė— 대해 ėƒę°í•˜ëŠ”ę˛Œ 훨ė”Ŧ ëŗĩėžĄí•Šë‹ˆë‹¤. -ė˜ˆė „ ë˛„ė „ė˜ NodeJS / 브ëŧėš°ė € ėžë°”ėŠ¤íŦëĻŊ트ëŧ늴, "ėŊœë°ą í•¨ėˆ˜"ëĨŧ ė‚ŦėšŠí–ˆė„ ę˛ƒėž…ë‹ˆë‹¤. ꡸ëĻŦęŗ  ė´ëĄœ ė¸í•´ ėŊœë°ą ė§€ė˜Ĩ뗐 ëš ė§€ę˛Œ 될 눘 ėžˆėŠĩ니다. +ė˜ˆė „ ë˛„ė „ė˜ NodeJS / 브ëŧėš°ė € ėžë°”ėŠ¤íŦëĻŊ트ëŧ늴, "ėŊœë°ą í•¨ėˆ˜"ëĨŧ ė‚ŦėšŠí–ˆė„ ę˛ƒėž…ë‹ˆë‹¤. ꡸ëĻŦęŗ  ė´ëĄœ ė¸í•´ "ėŊœë°ą ė§€ė˜Ĩ"뗐 ëš ė§€ę˛Œ 될 눘 ėžˆėŠĩ니다. ## ėŊ”ëŖ¨í‹´ diff --git a/docs/ko/docs/deployment/cloud.md b/docs/ko/docs/deployment/cloud.md index 2d6938e20..dbc814bbd 100644 --- a/docs/ko/docs/deployment/cloud.md +++ b/docs/ko/docs/deployment/cloud.md @@ -10,7 +10,4 @@ ė´ëŠ” FastAPI뙀 **ėģ¤ëŽ¤ë‹ˆí‹°** (ė—ŦëŸŦëļ„)뗐 대한 ė§„ė •í•œ í—Œė‹ ė„ ëŗ´ė—Ŧė¤ë‹ˆë‹¤. ęˇ¸ë“¤ė€ ė—ŦëŸŦëļ„ė—ę˛Œ **ėĸ‹ė€ ė„œëš„ėŠ¤**ëĨŧ 렜ęŗĩ할 ëŋ ë§Œė´ ė•„ë‹ˆëŧ ė—ŦëŸŦëļ„ė´ **훌ëĨ­í•˜ęŗ  건강한 í”„ë ˆėž„ė›ŒíŦė¸** FastAPI ëĨŧ ė‚ŦėšŠí•˜ę¸¸ ė›í•˜ę¸° 때ëŦ¸ėž…니다. 🙇 -ė•„ëž˜ė™€ ę°™ė€ ė„œëš„ėŠ¤ëĨŧ ė‚ŦėšŠí•´ëŗ´ęŗ  각 ė„œëš„ėŠ¤ė˜ ę°€ė´ë“œëĨŧ 따ëĨŧ ėˆ˜ë„ ėžˆėŠĩ니다: - -* Platform.sh -* Porter +ė•„ëž˜ė™€ ę°™ė€ ė„œëš„ėŠ¤ëĨŧ ė‚ŦėšŠí•´ëŗ´ęŗ  각 ė„œëš„ėŠ¤ė˜ ę°€ė´ë“œëĨŧ 따ëĨŧ ėˆ˜ë„ ėžˆėŠĩ니다. diff --git a/docs/ko/docs/help-fastapi.md b/docs/ko/docs/help-fastapi.md index 06435d4bb..b65ef959c 100644 --- a/docs/ko/docs/help-fastapi.md +++ b/docs/ko/docs/help-fastapi.md @@ -22,7 +22,7 @@ FastAPI, 다ëĨ¸ ė‚ŦėšŠėž, ę°œë°œėžëĨŧ ė‘ė›í•˜ęŗ  ė‹ļėœŧė‹ ę°€ėš”? ## íŠ¸ėœ„í„°ė—ė„œ FastAPI íŒ”ëĄœėš°í•˜ę¸° -**Twitter**ė˜ @fastapiëĨŧ íŒ”ëĄœėš°í•˜ė—Ŧ **FastAPI** 뗐 대한 ėĩœė‹  ë‰´ėŠ¤ëĨŧ ė–ģė„ 눘 ėžˆėŠĩ니다. đŸĻ +**X (Twitter)**ė˜ @fastapiëĨŧ íŒ”ëĄœėš°í•˜ė—Ŧ **FastAPI** 뗐 대한 ėĩœė‹  ë‰´ėŠ¤ëĨŧ ė–ģė„ 눘 ėžˆėŠĩ니다. đŸĻ ## Star **FastAPI** in GitHub @@ -47,19 +47,19 @@ GitHubė—ė„œ FastAPIëĨŧ "watch"할 눘 ėžˆėŠĩ니다 (똤ëĨ¸ėĒŊ ėƒë‹¨ watch 버 * **GitHub**ė—ė„œ íŒ”ëĄœėš°í•˜ę¸°.. * ë‹šė‹ ė—ę˛Œ ë„ė›€ė´ 될 ė €ė˜ 다ëĨ¸ ė˜¤í”ˆė†ŒėŠ¤ í”„ëĄœė íŠ¸ëĨŧ í™•ė¸í•˜ė‹­ė‹œė˜¤. * ėƒˆëĄœėš´ ė˜¤í”ˆė†ŒėŠ¤ í”„ëĄœė íŠ¸ëĨŧ ë§Œë“¤ė—ˆė„ 때 í™•ė¸í•˜ë ¤ëŠ´ íŒ”ëĄœėš° í•˜ė‹­ė‹œė˜¤. -* **Twitter** 또는 Mastodonė—ė„œ íŒ”ëĄœėš°í•˜ę¸°. +* **X (Twitter)** 또는 Mastodonė—ė„œ íŒ”ëĄœėš°í•˜ę¸°. * FastAPIė˜ ė‚ŦėšŠ ėšŠë„ëĨŧ ė•Œë ¤ėŖŧė„¸ėš” (ęˇ¸ę˛ƒė„ ë“ŖëŠ” ę˛ƒė„ ėĸ‹ė•„핊니다). * 발표나 ėƒˆëĄœėš´ 툴 ėļœė‹œ ė†Œė‹ė„ ë°›ė•„ëŗ´ė‹­ė‹œė˜¤. - * **Twitter**ė˜ @fastapiëĨŧ íŒ”ëĄœėš° (ëŗ„ë„ ęŗ„ė •ė—ė„œ) 할 눘 ėžˆėŠĩ니다. + * **X (Twitter)**ė˜ @fastapiëĨŧ íŒ”ëĄœėš° (ëŗ„ë„ ęŗ„ė •ė—ė„œ) 할 눘 ėžˆėŠĩ니다. * **LinkedIn**ė—ė„œ íŒ”ëĄœėš°í•˜ę¸°.. - * ėƒˆëĄœėš´ íˆ´ė˜ 발표나 ėļœė‹œ ė†Œė‹ė„ ë°›ė•„ëŗ´ė‹­ė‹œė˜¤. (단, TwitterëĨŧ 더 ėžėŖŧ ė‚ŦėšŠí•Šë‹ˆë‹¤ 🤷‍♂). + * ėƒˆëĄœėš´ íˆ´ė˜ 발표나 ėļœė‹œ ė†Œė‹ė„ ë°›ė•„ëŗ´ė‹­ė‹œė˜¤. (단, X (Twitter)ëĨŧ 더 ėžėŖŧ ė‚ŦėšŠí•Šë‹ˆë‹¤ 🤷‍♂). * **Dev.to** 또는 **Medium**ė—ė„œ ė œę°€ ėž‘ė„ąí•œ ë‚´ėšŠė„ ėŊė–´ ëŗ´ė‹­ė‹œė˜¤ (또는 íŒ”ëĄœėš°). * 다ëĨ¸ 기ė‚Ŧ나 ė•„ė´ë””ė–´ë“¤ė„ ėŊęŗ , ė œę°€ ë§Œë“¤ė–´ė™”ë˜ íˆ´ė— ëŒ€í•´ė„œë„ ėŊėœŧė‹­ė‹œė˜¤. * ėƒˆëĄœėš´ 기ė‚ŦëĨŧ ėŊ기 ėœ„í•´ íŒ”ëĄœėš° í•˜ė‹­ė‹œė˜¤. ## **FastAPI**뗐 대한 íŠ¸ėœ— -**FastAPI**뗐 대해 íŠ¸ėœ— í•˜ęŗ  FastAPI가 ë§ˆėŒė— 드는 ė´ėœ ëĨŧ ė•Œë ¤ėŖŧė„¸ėš”. 🎉 +**FastAPI**뗐 대해 íŠ¸ėœ— í•˜ęŗ  FastAPI가 ë§ˆėŒė— 드는 ė´ėœ ëĨŧ ė•Œë ¤ėŖŧė„¸ėš”. 🎉 **FastAPI**가 ė–´ë–ģ枌 ė‚ŦėšŠë˜ęŗ  ėžˆëŠ”ė§€, ė–´ë–¤ ė ė´ ë§ˆėŒė— ë“¤ė—ˆëŠ”ė§€, ė–´ë–¤ í”„ëĄœė íŠ¸/회ė‚Ŧė—ė„œ ė‚ŦėšŠí•˜ęŗ  ėžˆëŠ”ė§€ ë“ąė— 대해 ë“Ŗęŗ  ė‹ļėŠĩ니다. diff --git a/docs/ko/docs/index.md b/docs/ko/docs/index.md index 0df2000fa..fc0502052 100644 --- a/docs/ko/docs/index.md +++ b/docs/ko/docs/index.md @@ -88,7 +88,7 @@ FastAPI는 í˜„ëŒ€ė ė´ęŗ , ëš ëĨ´ëа(ęŗ ė„ąëŠĨ), íŒŒė´ėŦ í‘œė¤€ íƒ€ėž… 힌트 "_**FastAPI**가 너ëŦ´ ėĸ‹ė•„ė„œ ęĩŦëĻ„ ėœ„ëĨŧ ęąˇëŠ”ë“¯ 합니다. ė •ë§ ėϐ极ėŠĩ니다!_" -
Brian Okken - Python Bytes 팟ėēėŠ¤íŠ¸ í˜¸ėŠ¤íŠ¸ (ref)
+
Brian Okken - Python Bytes 팟ėēėŠ¤íŠ¸ í˜¸ėŠ¤íŠ¸ (ref)
--- @@ -102,7 +102,7 @@ FastAPI는 í˜„ëŒ€ė ė´ęŗ , ëš ëĨ´ëа(ęŗ ė„ąëŠĨ), íŒŒė´ėŦ í‘œė¤€ íƒ€ėž… 힌트 "_뚰ëĻŦ **API**ëĨŧ **FastAPI**로 바ęŋ¨ėŠĩ니다 [...] ė•„ë§ˆ ė—ŦëŸŦëļ„도 ėĸ‹ė•„í•˜ė‹¤ ę˛ƒėž…ë‹ˆë‹¤ [...]_" -
Ines Montani - Matthew Honnibal - Explosion AI 네ëĻŊėž - spaCy ė œėž‘ėž (ref) - (ref)
+
Ines Montani - Matthew Honnibal - Explosion AI 네ëĻŊėž - spaCy ė œėž‘ėž (ref) - (ref)
--- diff --git a/docs/ko/docs/tutorial/security/oauth2-jwt.md b/docs/ko/docs/tutorial/security/oauth2-jwt.md index d8bac8346..8d27856e8 100644 --- a/docs/ko/docs/tutorial/security/oauth2-jwt.md +++ b/docs/ko/docs/tutorial/security/oauth2-jwt.md @@ -270,4 +270,4 @@ OAuth2는 "늤ėŊ”프(scopes)" ëŧ는 ę°œë…ė„ ę°–ęŗ  ėžˆėŠĩ니다. ꡸ëĻŦęŗ  OAuth2뙀 ę°™ė€ í‘œė¤€ 프로토ėŊœė„ 비ęĩė  간단한 방법ėœŧ로 ęĩŦí˜„í•˜ęŗ  ė‚ŦėšŠí•  눘 ėžˆėŠĩ니다. -더 넏ëļ„화된 ęļŒí•œ 랴溄ëĨŧ ėœ„í•´ OAuth2ė˜ "늤ėŊ”프"ëĨŧ ė‚ŦėšŠí•˜ëŠ” ë°Šë˛•ė€ **ė‹Ŧ화 ė‚ŦėšŠėž ė•ˆë‚´ė„œ**ė—ė„œ 더 ėžė„¸ížˆ ë°°ėš¸ 눘 ėžˆėŠĩ니다. OAuth2ė˜ 늤ėŊ”프는 렜3ėž ė• í”ŒëĻŦėŧ€ė´ė…˜ė´ ė‚ŦėšŠėžëĨŧ ëŒ€ė‹ í•´ ęˇ¸ë“¤ė˜ API뙀 ėƒí˜¸ėž‘ėšŠí•˜ë„ëĄ ęļŒí•œė„ ëļ€ė—Ŧ하기 ėœ„í•´, Facebook, Google, GitHub, Microsoft, Twitter ë“ąė˜ ë§Žė€ 대형 ė¸ėĻ 렜ęŗĩė—…ė˛´ë“¤ė´ ė‚ŦėšŠí•˜ëŠ” 메ėģ¤ë‹ˆėĻ˜ėž…ë‹ˆë‹¤. +더 넏ëļ„화된 ęļŒí•œ 랴溄ëĨŧ ėœ„í•´ OAuth2ė˜ "늤ėŊ”프"ëĨŧ ė‚ŦėšŠí•˜ëŠ” ë°Šë˛•ė€ **ė‹Ŧ화 ė‚ŦėšŠėž ė•ˆë‚´ė„œ**ė—ė„œ 더 ėžė„¸ížˆ ë°°ėš¸ 눘 ėžˆėŠĩ니다. OAuth2ė˜ 늤ėŊ”프는 렜3ėž ė• í”ŒëĻŦėŧ€ė´ė…˜ė´ ė‚ŦėšŠėžëĨŧ ëŒ€ė‹ í•´ ęˇ¸ë“¤ė˜ API뙀 ėƒí˜¸ėž‘ėšŠí•˜ë„ëĄ ęļŒí•œė„ ëļ€ė—Ŧ하기 ėœ„í•´, Facebook, Google, GitHub, Microsoft, X (Twitter) ë“ąė˜ ë§Žė€ 대형 ė¸ėĻ 렜ęŗĩė—…ė˛´ë“¤ė´ ė‚ŦėšŠí•˜ëŠ” 메ėģ¤ë‹ˆėĻ˜ėž…ë‹ˆë‹¤. diff --git a/docs/nl/docs/environment-variables.md b/docs/nl/docs/environment-variables.md deleted file mode 100644 index f6b3d285b..000000000 --- a/docs/nl/docs/environment-variables.md +++ /dev/null @@ -1,298 +0,0 @@ -# Omgevingsvariabelen - -/// tip - -Als je al weet wat "omgevingsvariabelen" zijn en hoe je ze kunt gebruiken, kun je deze stap gerust overslaan. - -/// - -Een omgevingsvariabele (ook bekend als "**env var**") is een variabele die **buiten** de Python-code leeft, in het **besturingssysteem** en die door je Python-code (of door andere programma's) kan worden gelezen. - -Omgevingsvariabelen kunnen nuttig zijn voor het bijhouden van applicatie **instellingen**, als onderdeel van de **installatie** van Python, enz. - -## Omgevingsvariabelen maken en gebruiken - -Je kunt omgevingsvariabelen **maken** en gebruiken in de **shell (terminal)**, zonder dat je Python nodig hebt: - -//// tab | Linux, macOS, Windows Bash - -
- -```console -// Je zou een omgevingsvariabele MY_NAME kunnen maken met -$ export MY_NAME="Wade Wilson" - -// Dan zou je deze met andere programma's kunnen gebruiken, zoals -$ echo "Hello $MY_NAME" - -Hello Wade Wilson -``` - -
- -//// - -//// tab | Windows PowerShell - -
- -```console -// Maak een omgevingsvariabel MY_NAME -$ $Env:MY_NAME = "Wade Wilson" - -// Gebruik het met andere programma's, zoals -$ echo "Hello $Env:MY_NAME" - -Hello Wade Wilson -``` - -
- -//// - -## Omgevingsvariabelen uitlezen in Python - -Je kunt omgevingsvariabelen **buiten** Python aanmaken, in de terminal (of met een andere methode) en ze vervolgens **in Python uitlezen**. - -Je kunt bijvoorbeeld een bestand `main.py` hebben met: - -```Python hl_lines="3" -import os - -name = os.getenv("MY_NAME", "World") -print(f"Hello {name} from Python") -``` - -/// tip - -Het tweede argument van `os.getenv()` is de standaardwaarde die wordt geretourneerd. - -Als je dit niet meegeeft, is de standaardwaarde `None`. In dit geval gebruiken we standaard `"World"`. - -/// - -Dan zou je dat Python-programma kunnen aanroepen: - -//// tab | Linux, macOS, Windows Bash - -
- -```console -// Hier stellen we de omgevingsvariabelen nog niet in -$ python main.py - -// Omdat we de omgevingsvariabelen niet hebben ingesteld, krijgen we de standaardwaarde - -Hello World from Python - -// Maar als we eerst een omgevingsvariabele aanmaken -$ export MY_NAME="Wade Wilson" - -// en het programma dan opnieuw aanroepen -$ python main.py - -// kan het de omgevingsvariabele nu wel uitlezen - -Hello Wade Wilson from Python -``` - -
- -//// - -//// tab | Windows PowerShell - -
- -```console -// Hier stellen we de omgevingsvariabelen nog niet in -$ python main.py - -// Omdat we de omgevingsvariabelen niet hebben ingesteld, krijgen we de standaardwaarde - -Hello World from Python - -// Maar als we eerst een omgevingsvariabele aanmaken -$ $Env:MY_NAME = "Wade Wilson" - -// en het programma dan opnieuw aanroepen -$ python main.py - -// kan het de omgevingsvariabele nu wel uitlezen - -Hello Wade Wilson from Python -``` - -
- -//// - -Omdat omgevingsvariabelen buiten de code kunnen worden ingesteld, maar wel door de code kunnen worden gelezen en niet hoeven te worden opgeslagen (gecommit naar `git`) met de rest van de bestanden, worden ze vaak gebruikt voor configuraties of **instellingen**. - -Je kunt ook een omgevingsvariabele maken die alleen voor een **specifieke programma-aanroep** beschikbaar is, die alleen voor dat programma beschikbaar is en alleen voor de duur van dat programma. - -Om dat te doen, maak je het vlak voor het programma zelf aan, op dezelfde regel: - -
- -```console -// Maak een omgevingsvariabele MY_NAME in de regel voor deze programma-aanroep -$ MY_NAME="Wade Wilson" python main.py - -// Nu kan het de omgevingsvariabele lezen - -Hello Wade Wilson from Python - -// De omgevingsvariabelen bestaan daarna niet meer -$ python main.py - -Hello World from Python -``` - -
- -/// tip - -Je kunt er meer over lezen op The Twelve-Factor App: Config. - -/// - -## Types en Validatie - -Deze omgevingsvariabelen kunnen alleen **tekstuele gegevens** verwerken, omdat ze extern zijn aan Python, compatibel moeten zijn met andere programma's en de rest van het systeem (zelfs met verschillende besturingssystemen, zoals Linux, Windows en macOS). - -Dat betekent dat **elke waarde** die in Python uit een omgevingsvariabele wordt gelezen **een `str` zal zijn** en dat elke conversie naar een ander type of elke validatie in de code moet worden uitgevoerd. - -Meer informatie over het gebruik van omgevingsvariabelen voor het verwerken van **applicatie instellingen** vind je in de [Geavanceerde gebruikershandleiding - Instellingen en Omgevingsvariabelen](./advanced/settings.md){.internal-link target=_blank}. - -## `PATH` Omgevingsvariabele - -Er is een **speciale** omgevingsvariabele met de naam **`PATH`**, die door de besturingssystemen (Linux, macOS, Windows) wordt gebruikt om programma's te vinden die uitgevoerd kunnen worden. - -De waarde van de variabele `PATH` is een lange string die bestaat uit mappen die gescheiden worden door een dubbele punt `:` op Linux en macOS en door een puntkomma `;` op Windows. - -De omgevingsvariabele `PATH` zou er bijvoorbeeld zo uit kunnen zien: - -//// tab | Linux, macOS - -```plaintext -/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin -``` - -Dit betekent dat het systeem naar programma's zoekt in de mappen: - -* `/usr/local/bin` -* `/usr/bin` -* `/bin` -* `/usr/sbin` -* `/sbin` - -//// - -//// tab | Windows - -```plaintext -C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 -``` - -Dit betekent dat het systeem naar programma's zoekt in de mappen: - -* `C:\Program Files\Python312\Scripts` -* `C:\Program Files\Python312` -* `C:\Windows\System32` - -//// - -Wanneer je een **opdracht** in de terminal typt, **zoekt** het besturingssysteem naar het programma in **elk van de mappen** die vermeld staan in de omgevingsvariabele `PATH`. - -Wanneer je bijvoorbeeld `python` in de terminal typt, zoekt het besturingssysteem naar een programma met de naam `python` in de **eerste map** in die lijst. - -Zodra het gevonden wordt, zal het dat programma **gebruiken**. Anders blijft het in de **andere mappen** zoeken. - -### Python installeren en `PATH` bijwerken - -Wanneer je Python installeert, word je mogelijk gevraagd of je de omgevingsvariabele `PATH` wilt bijwerken. - -//// tab | Linux, macOS - -Stel dat je Python installeert en het komt terecht in de map `/opt/custompython/bin`. - -Als je kiest om de `PATH` omgevingsvariabele bij te werken, zal het installatieprogramma `/opt/custompython/bin` toevoegen aan de `PATH` omgevingsvariabele. - -Dit zou er zo uit kunnen zien: - -```plaintext -/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin -``` - -Op deze manier zal het systeem, wanneer je `python` in de terminal typt, het Python-programma in `/opt/custompython/bin` (de laatste map) vinden en dat gebruiken. - -//// - -//// tab | Windows - -Stel dat je Python installeert en het komt terecht in de map `C:\opt\custompython\bin`. - -Als je kiest om de `PATH` omgevingsvariabele bij te werken, zal het installatieprogramma `C:\opt\custompython\bin` toevoegen aan de `PATH` omgevingsvariabele. - -```plaintext -C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin -``` - -Op deze manier zal het systeem, wanneer je `python` in de terminal typt, het Python-programma in `C:\opt\custompython\bin` (de laatste map) vinden en dat gebruiken. - -//// - -Dus als je typt: - -
- -```console -$ python -``` - -
- -//// tab | Linux, macOS - -Zal het systeem het `python`-programma in `/opt/custompython/bin` **vinden** en uitvoeren. - -Het zou ongeveer hetzelfde zijn als het typen van: - -
- -```console -$ /opt/custompython/bin/python -``` - -
- -//// - -//// tab | Windows - -Zal het systeem het `python`-programma in `C:\opt\custompython\bin\python` **vinden** en uitvoeren. - -Het zou ongeveer hetzelfde zijn als het typen van: - -
- -```console -$ C:\opt\custompython\bin\python -``` - -
- -//// - -Deze informatie is handig wanneer je meer wilt weten over [virtuele omgevingen](virtual-environments.md){.internal-link target=_blank}. - -## Conclusion - -Hiermee heb je basiskennis van wat **omgevingsvariabelen** zijn en hoe je ze in Python kunt gebruiken. - -Je kunt er ook meer over lezen op de Wikipedia over omgevingsvariabelen. - -In veel gevallen is het niet direct duidelijk hoe omgevingsvariabelen nuttig zijn en hoe je ze moet toepassen. Maar ze blijven in veel verschillende scenario's opduiken als je aan het ontwikkelen bent, dus het is goed om er meer over te weten. - -Je hebt deze informatie bijvoorbeeld nodig in de volgende sectie, over [Virtuele Omgevingen](virtual-environments.md). diff --git a/docs/nl/docs/features.md b/docs/nl/docs/features.md deleted file mode 100644 index 848b155ec..000000000 --- a/docs/nl/docs/features.md +++ /dev/null @@ -1,201 +0,0 @@ -# Functionaliteit - -## FastAPI functionaliteit - -**FastAPI** biedt je het volgende: - -### Gebaseerd op open standaarden - -* OpenAPI voor het maken van API's, inclusief declaraties van padbewerkingen, parameters, request bodies, beveiliging, enz. -* Automatische datamodel documentatie met JSON Schema (aangezien OpenAPI zelf is gebaseerd op JSON Schema). -* Ontworpen op basis van deze standaarden, na zorgvuldig onderzoek. In plaats van achteraf deze laag er bovenop te bouwen. -* Dit maakt het ook mogelijk om automatisch **clientcode te genereren** in verschillende programmeertalen. - -### Automatische documentatie - -Interactieve API-documentatie en verkenning van webgebruikersinterfaces. Aangezien dit framework is gebaseerd op OpenAPI, zijn er meerdere documentatie opties mogelijk, waarvan er standaard 2 zijn inbegrepen. - -* Swagger UI, met interactieve interface, maakt het mogelijk je API rechtstreeks vanuit de browser aan te roepen en te testen. - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Alternatieve API-documentatie met ReDoc. - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Gewoon Moderne Python - -Het is allemaal gebaseerd op standaard **Python type** declaraties (dankzij Pydantic). Je hoeft dus geen nieuwe syntax te leren. Het is gewoon standaard moderne Python. - -Als je een opfriscursus van 2 minuten nodig hebt over het gebruik van Python types (zelfs als je FastAPI niet gebruikt), bekijk dan deze korte tutorial: [Python Types](python-types.md){.internal-link target=_blank}. - -Je schrijft gewoon standaard Python met types: - -```Python -from datetime import date - -from pydantic import BaseModel - -# Declareer een variabele als een str -# en krijg editorondersteuning in de functie -def main(user_id: str): - return user_id - - -# Een Pydantic model -class User(BaseModel): - id: int - name: str - joined: date -``` - -Vervolgens kan je het op deze manier gebruiken: - -```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` betekent: - -Geef de sleutels (keys) en waarden (values) van de `second_user_data` dict direct door als sleutel-waarden argumenten, gelijk aan: `User(id=4, name=“Mary”, joined=“2018-11-30”)` - -/// - -### Editor-ondersteuning - -Het gehele framework is ontworpen om eenvoudig en intuïtief te zijn in gebruik. Alle beslissingen zijn getest op meerdere code-editors nog voordat het daadwerkelijke ontwikkelen begon, om zo de beste ontwikkelervaring te garanderen. - -Uit enquÃĒtes onder Python ontwikkelaars blijkt maar al te duidelijk dat "(automatische) code aanvulling" een van de meest gebruikte functionaliteiten is. - -Het hele **FastAPI** framework is daarop gebaseerd. Automatische code aanvulling werkt overal. - -Je hoeft zelden terug te vallen op de documentatie. - -Zo kan je editor je helpen: - -* in Visual Studio Code: - -![editor ondersteuning](https://fastapi.tiangolo.com/img/vscode-completion.png) - -* in PyCharm: - -![editor ondersteuning](https://fastapi.tiangolo.com/img/pycharm-completion.png) - -Je krijgt autocomletion die je voorheen misschien zelfs voor onmogelijk had gehouden. Zoals bijvoorbeeld de `price` key in een JSON body (die genest had kunnen zijn) die afkomstig is van een request. - -Je hoeft niet langer de verkeerde keys in te typen, op en neer te gaan tussen de documentatie, of heen en weer te scrollen om te checken of je `username` of toch `user_name` had gebruikt. - -### Kort - -Dit framework heeft voor alles verstandige **standaardinstellingen**, met overal optionele configuraties. Alle parameters kunnen worden verfijnd zodat het past bij wat je nodig hebt, om zo de API te kunnen definiÃĢren die jij nodig hebt. - -Maar standaard werkt alles **“gewoon”**. - -### Validatie - -* Validatie voor de meeste (of misschien wel alle?) Python **datatypes**, inclusief: - * JSON objecten (`dict`). - * JSON array (`list`) die itemtypes definiÃĢren. - * String (`str`) velden, die min en max lengtes hebben. - * Getallen (`int`, `float`) met min en max waarden, enz. - -* Validatie voor meer exotische typen, zoals: - * URL. - * E-mail. - * UUID. - * ...en anderen. - -Alle validatie wordt uitgevoerd door het beproefde en robuuste **Pydantic**. - -### Beveiliging en authenticatie - -Beveiliging en authenticatie is geïntegreerd. Zonder compromissen te doen naar databases of datamodellen. - -Alle beveiligingsschema's gedefinieerd in OpenAPI, inclusief: - -* HTTP Basic. -* **OAuth2** (ook met **JWT tokens**). Bekijk de tutorial over [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. -* API keys in: - * Headers. - * Query parameters. - * Cookies, enz. - -Plus alle beveiligingsfuncties van Starlette (inclusief **sessiecookies**). - -Gebouwd als een herbruikbare tool met componenten die makkelijk te integreren zijn in en met je systemen, datastores, relationele en NoSQL databases, enz. - -### Dependency Injection - -FastAPI bevat een uiterst eenvoudig, maar uiterst krachtig Dependency Injection systeem. - -* Zelfs dependencies kunnen dependencies hebben, waardoor een hiÃĢrarchie of **“graph” van dependencies** ontstaat. -* Allemaal **automatisch afgehandeld** door het framework. -* Alle dependencies kunnen data nodig hebben van request, de vereiste **padoperaties veranderen** en automatische documentatie verstrekken. -* **Automatische validatie** zelfs voor *padoperatie* parameters gedefinieerd in dependencies. -* Ondersteuning voor complexe gebruikersauthenticatiesystemen, **databaseverbindingen**, enz. -* **Geen compromisen** met databases, gebruikersinterfaces, enz. Maar eenvoudige integratie met ze allemaal. - -### Ongelimiteerde "plug-ins" - -Of anders gezegd, je hebt ze niet nodig, importeer en gebruik de code die je nodig hebt. - -Elke integratie is ontworpen om eenvoudig te gebruiken (met afhankelijkheden), zodat je een “plug-in" kunt maken in 2 regels code, met dezelfde structuur en syntax die wordt gebruikt voor je *padbewerkingen*. - -### Getest - -* 100% van de code is getest. -* 100% type geannoteerde codebase. -* Wordt gebruikt in productietoepassingen. - -## Starlette functies - -**FastAPI** is volledig verenigbaar met (en gebaseerd op) Starlette. - -`FastAPI` is eigenlijk een subklasse van `Starlette`. Dus als je Starlette al kent of gebruikt, zal de meeste functionaliteit op dezelfde manier werken. - -Met **FastAPI** krijg je alle functies van **Starlette** (FastAPI is gewoon Starlette op steroïden): - -* Zeer indrukwekkende prestaties. Het is een van de snelste Python frameworks, vergelijkbaar met **NodeJS** en **Go**. -* **WebSocket** ondersteuning. -* Taken in de achtergrond tijdens het proces. -* Opstart- en afsluit events. -* Test client gebouwd op HTTPX. -* **CORS**, GZip, Statische bestanden, Streaming reacties. -* **Sessie en Cookie** ondersteuning. -* 100% van de code is getest. -* 100% type geannoteerde codebase. - -## Pydantic functionaliteit - -**FastAPI** is volledig verenigbaar met (en gebaseerd op) Pydantic. Dus alle extra Pydantic code die je nog hebt werkt ook. - -Inclusief externe pakketten die ook gebaseerd zijn op Pydantic, zoals ORMs, ODMs voor databases. - -Dit betekent ook dat je in veel gevallen het object dat je van een request krijgt **direct naar je database** kunt sturen, omdat alles automatisch wordt gevalideerd. - -Hetzelfde geldt ook andersom, in veel gevallen kun je dus het object dat je krijgt van de database **direct doorgeven aan de client**. - -Met **FastAPI** krijg je alle functionaliteit van **Pydantic** (omdat FastAPI is gebaseerd op Pydantic voor alle dataverwerking): - -* **Geen brainfucks**: - * Je hoeft geen nieuwe microtaal voor schemadefinities te leren. - * Als je bekend bent Python types, weet je hoe je Pydantic moet gebruiken. -* Werkt goed samen met je **IDE/linter/hersenen**: - * Doordat pydantic's datastructuren enkel instanties zijn van klassen, die je definieert, werkt automatische aanvulling, linting, mypy en je intuïtie allemaal goed met je gevalideerde data. -* Valideer **complexe structuren**: - * Gebruik van hiÃĢrarchische Pydantic modellen, Python `typing`'s `List` en `Dict`, enz. - * Met validators kunnen complexe dataschema's duidelijk en eenvoudig worden gedefinieerd, gecontroleerd en gedocumenteerd als JSON Schema. - * Je kunt diep **geneste JSON** objecten laten valideren en annoteren. -* **Uitbreidbaar**: - * Met Pydantic kunnen op maat gemaakte datatypen worden gedefinieerd of je kunt validatie uitbreiden met methoden op een model dat is ingericht met de decorator validator. -* 100% van de code is getest. diff --git a/docs/nl/docs/index.md b/docs/nl/docs/index.md deleted file mode 100644 index 32b20e31e..000000000 --- a/docs/nl/docs/index.md +++ /dev/null @@ -1,494 +0,0 @@ -# FastAPI - - - -

- FastAPI -

-

- FastAPI framework, zeer goede prestaties, eenvoudig te leren, snel te programmeren, klaar voor productie -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**Documentatie**: https://fastapi.tiangolo.com - -**Broncode**: https://github.com/tiangolo/fastapi - ---- - -FastAPI is een modern, snel (zeer goede prestaties), web framework voor het bouwen van API's in Python, gebruikmakend van standaard Python type-hints. - -De belangrijkste kenmerken zijn: - -* **Snel**: Zeer goede prestaties, vergelijkbaar met **NodeJS** en **Go** (dankzij Starlette en Pydantic). [Een van de snelste beschikbare Python frameworks](#prestaties). -* **Snel te programmeren**: Verhoog de snelheid om functionaliteit te ontwikkelen met ongeveer 200% tot 300%. * -* **Minder bugs**: Verminder ongeveer 40% van de door mensen (ontwikkelaars) veroorzaakte fouten. * -* **Intuïtief**: Buitengewoon goede ondersteuning voor editors. Overal automische code aanvulling. Minder tijd kwijt aan debuggen. -* **Eenvoudig**: Ontworpen om gemakkelijk te gebruiken en te leren. Minder tijd nodig om documentatie te lezen. -* **Kort**: Minimaliseer codeduplicatie. Elke parameterdeclaratie ondersteunt meerdere functionaliteiten. Minder bugs. -* **Robust**: Code gereed voor productie. Met automatische interactieve documentatie. -* **Standards-based**: Gebaseerd op (en volledig verenigbaar met) open standaarden voor API's: OpenAPI (voorheen bekend als Swagger) en JSON Schema. - -* schatting op basis van testen met een intern ontwikkelteam en bouwen van productieapplicaties. - -## Sponsors - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -Overige sponsoren - -## Meningen - -"_[...] Ik gebruik **FastAPI** heel vaak tegenwoordig. [...] Ik ben van plan om het te gebruiken voor alle **ML-services van mijn team bij Microsoft**. Sommige van deze worden geïntegreerd in het kernproduct van **Windows** en sommige **Office**-producten._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_We hebben de **FastAPI** library gebruikt om een **REST** server te maken die bevraagd kan worden om **voorspellingen** te maken. [voor Ludwig]_" - -
Piero Molino, Yaroslav Dudin en Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** is verheugd om een open-source release aan te kondigen van ons **crisismanagement**-orkestratieframework: **Dispatch**! [gebouwd met **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_Ik ben super enthousiast over **FastAPI**. Het is zo leuk!_" - -
Brian Okken - Python Bytes podcast presentator (ref)
- ---- - -"_Wat je hebt gebouwd ziet er echt super solide en gepolijst uit. In veel opzichten is het wat ik wilde dat **Hug** kon zijn - het is echt inspirerend om iemand dit te zien bouwen._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"Wie geïnteresseerd is in een **modern framework** voor het bouwen van REST API's, bekijkt best eens **FastAPI** [...] Het is snel, gebruiksvriendelijk en gemakkelijk te leren [...]_" - -"_We zijn overgestapt naar **FastAPI** voor onze **API's** [...] Het gaat jou vast ook bevallen [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI oprichters - spaCy ontwikkelaars (ref) - (ref)
- ---- - -"_Wie een Python API wil bouwen voor productie, kan ik ten stelligste **FastAPI** aanraden. Het is **prachtig ontworpen**, **eenvoudig te gebruiken** en **gemakkelijk schaalbaar**, het is een **cruciale component** geworden in onze strategie om API's centraal te zetten, en het vereenvoudigt automatisering en diensten zoals onze Virtual TAC Engineer._" - -
Deon Pillsbury - Cisco (ref)
- ---- - -## **Typer**, de FastAPI van CLIs - - - -Als je een CLI-app bouwt die in de terminal moet worden gebruikt in plaats van een web-API, gebruik dan **Typer**. - -**Typer** is het kleine broertje van FastAPI. En het is bedoeld als de **FastAPI van CLI's**. ī¸ - -## Vereisten - -FastAPI staat op de schouders van reuzen: - -* Starlette voor de webonderdelen. -* Pydantic voor de datadelen. - -## Installatie - -
- -```console -$ pip install "fastapi[standard]" - ----> 100% -``` - -
- -**Opmerking**: Zet `"fastapi[standard]"` tussen aanhalingstekens om ervoor te zorgen dat het werkt in alle terminals. - -## Voorbeeld - -### CreÃĢer het - -* Maak het bestand `main.py` aan met daarin: - -```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} -``` - -
-Of maak gebruik van async def... - -Als je code gebruik maakt van `async` / `await`, gebruik dan `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} -``` - -**Opmerking**: - -Als je het niet weet, kijk dan in het gedeelte _"Heb je haast?"_ over `async` en `await` in de documentatie. - -
- -### Voer het uit - -Run de server met: - -
- -```console -$ fastapi dev main.py - - ╭────────── FastAPI CLI - Development mode ───────────╮ - │ │ - │ Serving at: http://127.0.0.1:8000 │ - │ │ - │ API docs: http://127.0.0.1:8000/docs │ - │ │ - │ Running in development mode, for production use: │ - │ │ - │ fastapi run │ - │ │ - ╰─────────────────────────────────────────────────────╯ - -INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [2248755] using WatchFiles -INFO: Started server process [2248757] -INFO: Waiting for application startup. -INFO: Application startup complete. -``` - -
- -
-Over het commando fastapi dev main.py... - -Het commando `fastapi dev` leest het `main.py` bestand, detecteert de **FastAPI** app, en start een server met Uvicorn. - -Standaard zal dit commando `fastapi dev` starten met "auto-reload" geactiveerd voor ontwikkeling op het lokale systeem. - -Je kan hier meer over lezen in de FastAPI CLI documentatie. - -
- -### Controleer het - -Open je browser op http://127.0.0.1:8000/items/5?q=somequery. - -Je zult een JSON response zien: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -Je hebt een API gemaakt die: - -* HTTP verzoeken kan ontvangen op de _paden_ `/` en `/items/{item_id}`. -* Beide _paden_ hebben `GET` operaties (ook bekend als HTTP _methoden_). -* Het _pad_ `/items/{item_id}` heeft een _pad parameter_ `item_id` dat een `int` moet zijn. -* Het _pad_ `/items/{item_id}` heeft een optionele `str` _query parameter_ `q`. - -### Interactieve API documentatie - -Ga naar http://127.0.0.1:8000/docs. - -Je ziet de automatische interactieve API documentatie (verstrekt door Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternatieve API documentatie - -Ga vervolgens naar http://127.0.0.1:8000/redoc. - -Je ziet de automatische interactieve API documentatie (verstrekt door ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## Voorbeeld upgrade - -Pas nu het bestand `main.py` aan om de body van een `PUT` request te ontvangen. - -Dankzij Pydantic kunnen we de body declareren met standaard Python types. - -```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} -``` - -De `fastapi dev` server zou automatisch moeten herladen. - -### Interactieve API documentatie upgrade - -Ga nu naar http://127.0.0.1:8000/docs. - -* De interactieve API-documentatie wordt automatisch bijgewerkt, inclusief de nieuwe body: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Klik op de knop "Try it out", hiermee kan je de parameters invullen en direct met de API interacteren: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Klik vervolgens op de knop "Execute", de gebruikersinterface zal communiceren met jouw API, de parameters verzenden, de resultaten ophalen en deze op het scherm tonen: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Alternatieve API documentatie upgrade - -Ga vervolgens naar http://127.0.0.1:8000/redoc. - -* De alternatieve documentatie zal ook de nieuwe queryparameter en body weergeven: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Samenvatting - -Samengevat declareer je **eenmalig** de types van parameters, body, etc. als functieparameters. - -Dat doe je met standaard moderne Python types. - -Je hoeft geen nieuwe syntax te leren, de methods of klassen van een specifieke bibliotheek, etc. - -Gewoon standaard **Python**. - -Bijvoorbeeld, voor een `int`: - -```Python -item_id: int -``` - -of voor een complexer `Item` model: - -```Python -item: Item -``` - -...en met die ene verklaring krijg je: - -* Editor ondersteuning, inclusief: - * Code aanvulling. - * Type validatie. -* Validatie van data: - * Automatische en duidelijke foutboodschappen wanneer de data ongeldig is. - * Validatie zelfs voor diep geneste JSON objecten. -* Conversie van invoergegevens: afkomstig van het netwerk naar Python-data en -types. Zoals: - * JSON. - * Pad parameters. - * Query parameters. - * Cookies. - * Headers. - * Formulieren. - * Bestanden. -* Conversie van uitvoergegevens: converstie van Python-data en -types naar netwerkgegevens (zoals JSON): - * Converteer Python types (`str`, `int`, `float`, `bool`, `list`, etc). - * `datetime` objecten. - * `UUID` objecten. - * Database modellen. - * ...en nog veel meer. -* Automatische interactieve API-documentatie, inclusief 2 alternatieve gebruikersinterfaces: - * Swagger UI. - * ReDoc. - ---- - -Terugkomend op het vorige code voorbeeld, **FastAPI** zal: - -* Valideren dat er een `item_id` bestaat in het pad voor `GET` en `PUT` verzoeken. -* Valideren dat het `item_id` van het type `int` is voor `GET` en `PUT` verzoeken. - * Wanneer dat niet het geval is, krijgt de cliÃĢnt een nuttige, duidelijke foutmelding. -* Controleren of er een optionele query parameter is met de naam `q` (zoals in `http://127.0.0.1:8000/items/foo?q=somequery`) voor `GET` verzoeken. - * Aangezien de `q` parameter werd gedeclareerd met `= None`, is deze optioneel. - * Zonder de `None` declaratie zou deze verplicht zijn (net als bij de body in het geval met `PUT`). -* Voor `PUT` verzoeken naar `/items/{item_id}`, lees de body als JSON: - * Controleer of het een verplicht attribuut `naam` heeft en dat dat een `str` is. - * Controleer of het een verplicht attribuut `price` heeft en dat dat een`float` is. - * Controleer of het een optioneel attribuut `is_offer` heeft, dat een `bool` is wanneer het aanwezig is. - * Dit alles werkt ook voor diep geneste JSON objecten. -* Converteer automatisch van en naar JSON. -* Documenteer alles met OpenAPI, dat gebruikt kan worden door: - * Interactieve documentatiesystemen. - * Automatische client code generatie systemen, voor vele talen. -* Biedt 2 interactieve documentatie-webinterfaces aan. - ---- - -Dit was nog maar een snel overzicht, maar je zou nu toch al een idee moeten hebben over hoe het allemaal werkt. - -Probeer deze regel te veranderen: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...van: - -```Python - ... "item_name": item.name ... -``` - -...naar: - -```Python - ... "item_price": item.price ... -``` - -...en zie hoe je editor de attributen automatisch invult en hun types herkent: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -Voor een vollediger voorbeeld met meer mogelijkheden, zie de Tutorial - Gebruikershandleiding. - -**Spoiler alert**: de tutorial - gebruikershandleiding bevat: - -* Declaratie van **parameters** op andere plaatsen zoals: **headers**, **cookies**, **formuliervelden** en **bestanden**. -* Hoe stel je **validatie restricties** in zoals `maximum_length` of een `regex`. -* Een zeer krachtig en eenvoudig te gebruiken **Dependency Injection** systeem. -* Beveiliging en authenticatie, inclusief ondersteuning voor **OAuth2** met **JWT-tokens** en **HTTP Basic** auth. -* Meer geavanceerde (maar even eenvoudige) technieken voor het declareren van **diep geneste JSON modellen** (dankzij Pydantic). -* **GraphQL** integratie met Strawberry en andere packages. -* Veel extra functies (dankzij Starlette) zoals: - * **WebSockets** - * uiterst gemakkelijke tests gebaseerd op HTTPX en `pytest` - * **CORS** - * **Cookie Sessions** - * ...en meer. - -## Prestaties - -Onafhankelijke TechEmpower benchmarks tonen **FastAPI** applicaties draaiend onder Uvicorn aan als een van de snelste Python frameworks beschikbaar, alleen onder Starlette en Uvicorn zelf (intern gebruikt door FastAPI). (*) - -Zie de sectie Benchmarks om hier meer over te lezen. - -## Afhankelijkheden - -FastAPI maakt gebruik van Pydantic en Starlette. - -### `standard` Afhankelijkheden - -Wanneer je FastAPI installeert met `pip install "fastapi[standard]"`, worden de volgende `standard` optionele afhankelijkheden geïnstalleerd: - -Gebruikt door Pydantic: - -* email_validator - voor email validatie. - -Gebruikt door Starlette: - -* httpx - Vereist indien je de `TestClient` wil gebruiken. -* jinja2 - Vereist als je de standaard templateconfiguratie wil gebruiken. -* python-multipart - Vereist indien je "parsen" van formulieren wil ondersteunen met `requests.form()`. - -Gebruikt door FastAPI / Starlette: - -* uvicorn - voor de server die jouw applicatie laadt en bedient. -* `fastapi-cli` - om het `fastapi` commando te voorzien. - -### Zonder `standard` Afhankelijkheden - -Indien je de optionele `standard` afhankelijkheden niet wenst te installeren, kan je installeren met `pip install fastapi` in plaats van `pip install "fastapi[standard]"`. - -### Bijkomende Optionele Afhankelijkheden - -Er zijn nog een aantal bijkomende afhankelijkheden die je eventueel kan installeren. - -Bijkomende optionele afhankelijkheden voor Pydantic: - -* pydantic-settings - voor het beheren van settings. -* pydantic-extra-types - voor extra data types die gebruikt kunnen worden met Pydantic. - -Bijkomende optionele afhankelijkheden voor FastAPI: - -* orjson - Vereist indien je `ORJSONResponse` wil gebruiken. -* ujson - Vereist indien je `UJSONResponse` wil gebruiken. - -## Licentie - -Dit project is gelicenseerd onder de voorwaarden van de MIT licentie. diff --git a/docs/nl/docs/python-types.md b/docs/nl/docs/python-types.md deleted file mode 100644 index fb8b1e5fd..000000000 --- a/docs/nl/docs/python-types.md +++ /dev/null @@ -1,587 +0,0 @@ -# Introductie tot Python Types - -Python biedt ondersteuning voor optionele "type hints" (ook wel "type annotaties" genoemd). - -Deze **"type hints"** of annotaties zijn een speciale syntax waarmee het type van een variabele kan worden gedeclareerd. - -Door types voor je variabelen te declareren, kunnen editors en hulpmiddelen je beter ondersteunen. - -Dit is slechts een **korte tutorial/opfrisser** over Python type hints. Het behandelt enkel het minimum dat nodig is om ze te gebruiken met **FastAPI**... en dat is relatief weinig. - -**FastAPI** is helemaal gebaseerd op deze type hints, ze geven veel voordelen. - -Maar zelfs als je **FastAPI** nooit gebruikt, heb je er baat bij om er iets over te leren. - -/// note - -Als je een Python expert bent en alles al weet over type hints, sla dan dit hoofdstuk over. - -/// - -## Motivatie - -Laten we beginnen met een eenvoudig voorbeeld: - -{* ../../docs_src/python_types/tutorial001.py *} - - -Het aanroepen van dit programma leidt tot het volgende resultaat: - -``` -John Doe -``` - -De functie voert het volgende uit: - -* Neem een `first_name` en een `last_name` -* Converteer de eerste letter van elk naar een hoofdletter met `title()`. -`` -* Voeg samen met een spatie in het midden. - -{* ../../docs_src/python_types/tutorial001.py hl[2] *} - - -### Bewerk het - -Dit is een heel eenvoudig programma. - -Maar stel je nu voor dat je het vanaf nul zou moeten maken. - -Op een gegeven moment zou je aan de definitie van de functie zijn begonnen, je had de parameters klaar... - -Maar dan moet je “die methode die de eerste letter naar hoofdletters converteert” aanroepen. - -Was het `upper`? Was het `uppercase`? `first_uppercase`? `capitalize`? - -Dan roep je de hulp in van je oude programmeursvriend, (automatische) code aanvulling in je editor. - -Je typt de eerste parameter van de functie, `first_name`, dan een punt (`.`) en drukt dan op `Ctrl+Spatie` om de aanvulling te activeren. - -Maar helaas krijg je niets bruikbaars: - - - -### Types toevoegen - -Laten we een enkele regel uit de vorige versie aanpassen. - -We zullen precies dit fragment, de parameters van de functie, wijzigen van: - -```Python - first_name, last_name -``` - -naar: - -```Python - first_name: str, last_name: str -``` - -Dat is alles. - -Dat zijn de "type hints": - -{* ../../docs_src/python_types/tutorial002.py hl[1] *} - - -Dit is niet hetzelfde als het declareren van standaardwaarden zoals bij: - -```Python - first_name="john", last_name="doe" -``` - -Het is iets anders. - -We gebruiken dubbele punten (`:`), geen gelijkheidstekens (`=`). - -Het toevoegen van type hints verandert normaal gesproken niet wat er gebeurt in je programma t.o.v. wat er zonder type hints zou gebeuren. - -Maar stel je voor dat je weer bezig bent met het maken van een functie, maar deze keer met type hints. - -Op hetzelfde moment probeer je de automatische aanvulling te activeren met `Ctrl+Spatie` en je ziet: - - - -Nu kun je de opties bekijken en er doorheen scrollen totdat je de optie vindt die “een belletje doet rinkelen”: - - - -### Meer motivatie - -Bekijk deze functie, deze heeft al type hints: - -{* ../../docs_src/python_types/tutorial003.py hl[1] *} - - -Omdat de editor de types van de variabelen kent, krijgt u niet alleen aanvulling, maar ook controles op fouten: - - - -Nu weet je hoe je het moet oplossen, converteer `age` naar een string met `str(age)`: - -{* ../../docs_src/python_types/tutorial004.py hl[2] *} - - -## Types declareren - -Je hebt net de belangrijkste plek om type hints te declareren gezien. Namelijk als functieparameters. - -Dit is ook de belangrijkste plek waar je ze gebruikt met **FastAPI**. - -### Eenvoudige types - -Je kunt alle standaard Python types declareren, niet alleen `str`. - -Je kunt bijvoorbeeld het volgende gebruiken: - -* `int` -* `float` -* `bool` -* `bytes` - -{* ../../docs_src/python_types/tutorial005.py hl[1] *} - - -### Generieke types met typeparameters - -Er zijn enkele datastructuren die andere waarden kunnen bevatten, zoals `dict`, `list`, `set` en `tuple` en waar ook de interne waarden hun eigen type kunnen hebben. - -Deze types die interne types hebben worden “**generieke**” types genoemd. Het is mogelijk om ze te declareren, zelfs met hun interne types. - -Om deze types en de interne types te declareren, kun je de standaard Python module `typing` gebruiken. Deze module is speciaal gemaakt om deze type hints te ondersteunen. - -#### Nieuwere versies van Python - -De syntax met `typing` is **verenigbaar** met alle versies, van Python 3.6 tot aan de nieuwste, inclusief Python 3.9, Python 3.10, enz. - -Naarmate Python zich ontwikkelt, worden **nieuwere versies**, met verbeterde ondersteuning voor deze type annotaties, beschikbaar. In veel gevallen hoef je niet eens de `typing` module te importeren en te gebruiken om de type annotaties te declareren. - -Als je een recentere versie van Python kunt kiezen voor je project, kun je profiteren van die extra eenvoud. - -In alle documentatie staan voorbeelden die compatibel zijn met elke versie van Python (als er een verschil is). - -Bijvoorbeeld “**Python 3.6+**” betekent dat het compatibel is met Python 3.6 of hoger (inclusief 3.7, 3.8, 3.9, 3.10, etc). En “**Python 3.9+**” betekent dat het compatibel is met Python 3.9 of hoger (inclusief 3.10, etc). - -Als je de **laatste versies van Python** kunt gebruiken, gebruik dan de voorbeelden voor de laatste versie, die hebben de **beste en eenvoudigste syntax**, bijvoorbeeld “**Python 3.10+**”. - -#### List - -Laten we bijvoorbeeld een variabele definiÃĢren als een `list` van `str`. - -//// tab | Python 3.9+ - -Declareer de variabele met dezelfde dubbele punt (`:`) syntax. - -Als type, vul `list` in. - -Doordat de list een type is dat enkele interne types bevat, zet je ze tussen vierkante haakjes: - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -Van `typing`, importeer `List` (met een hoofdletter `L`): - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -Declareer de variabele met dezelfde dubbele punt (`:`) syntax. - -Zet als type de `List` die je hebt geïmporteerd uit `typing`. - -Doordat de list een type is dat enkele interne types bevat, zet je ze tussen vierkante haakjes: - -```Python hl_lines="4" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -//// - -/// info - -De interne types tussen vierkante haakjes worden “typeparameters” genoemd. - -In dit geval is `str` de typeparameter die wordt doorgegeven aan `List` (of `list` in Python 3.9 en hoger). - -/// - -Dat betekent: “de variabele `items` is een `list`, en elk van de items in deze list is een `str`”. - -/// tip - -Als je Python 3.9 of hoger gebruikt, hoef je `List` niet te importeren uit `typing`, je kunt in plaats daarvan hetzelfde reguliere `list` type gebruiken. - -/// - -Door dat te doen, kan je editor ondersteuning bieden, zelfs tijdens het verwerken van items uit de list: - - - -Zonder types is dat bijna onmogelijk om te bereiken. - -Merk op dat de variabele `item` een van de elementen is in de lijst `items`. - -Toch weet de editor dat het een `str` is, en biedt daar vervolgens ondersteuning voor aan. - -#### Tuple en Set - -Je kunt hetzelfde doen om `tuple`s en `set`s te declareren: - -//// tab | Python 3.9+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial007_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial007.py!} -``` - -//// - -Dit betekent: - -* De variabele `items_t` is een `tuple` met 3 items, een `int`, nog een `int`, en een `str`. -* De variabele `items_s` is een `set`, en elk van de items is van het type `bytes`. - -#### Dict - -Om een `dict` te definiÃĢren, geef je 2 typeparameters door, gescheiden door komma's. - -De eerste typeparameter is voor de sleutels (keys) van de `dict`. - -De tweede typeparameter is voor de waarden (values) van het `dict`: - -//// tab | Python 3.9+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial008_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008.py!} -``` - -//// - -Dit betekent: - -* De variabele `prices` is een `dict`: - * De sleutels van dit `dict` zijn van het type `str` (bijvoorbeeld de naam van elk item). - * De waarden van dit `dict` zijn van het type `float` (bijvoorbeeld de prijs van elk item). - -#### Union - -Je kunt een variable declareren die van **verschillende types** kan zijn, bijvoorbeeld een `int` of een `str`. - -In Python 3.6 en hoger (inclusief Python 3.10) kun je het `Union`-type van `typing` gebruiken en de mogelijke types die je wilt accepteren, tussen de vierkante haakjes zetten. - -In Python 3.10 is er ook een **nieuwe syntax** waarin je de mogelijke types kunt scheiden door een verticale balk (`|`). - -//// tab | Python 3.10+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial008b_py310.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} -``` - -//// - -In beide gevallen betekent dit dat `item` een `int` of een `str` kan zijn. - -#### Mogelijk `None` - -Je kunt declareren dat een waarde een type kan hebben, zoals `str`, maar dat het ook `None` kan zijn. - -In Python 3.6 en hoger (inclusief Python 3.10) kun je het declareren door `Optional` te importeren en te gebruiken vanuit de `typing`-module. - -```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009.py!} -``` - -Door `Optional[str]` te gebruiken in plaats van alleen `str`, kan de editor je helpen fouten te detecteren waarbij je ervan uit zou kunnen gaan dat een waarde altijd een `str` is, terwijl het in werkelijkheid ook `None` zou kunnen zijn. - -`Optional[EenType]` is eigenlijk een snelkoppeling voor `Union[EenType, None]`, ze zijn equivalent. - -Dit betekent ook dat je in Python 3.10 `EenType | None` kunt gebruiken: - -//// tab | Python 3.10+ - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial009_py310.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} -``` - -//// - -//// tab | Python 3.8+ alternative - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} -``` - -//// - -#### Gebruik van `Union` of `Optional` - -Als je een Python versie lager dan 3.10 gebruikt, is dit een tip vanuit mijn **subjectieve** standpunt: - -* 🚨 Vermijd het gebruik van `Optional[EenType]`. -* Gebruik in plaats daarvan **`Union[EenType, None]`** ✨. - -Beide zijn gelijkwaardig en onderliggend zijn ze hetzelfde, maar ik zou `Union` aanraden in plaats van `Optional` omdat het woord “**optional**” lijkt te impliceren dat de waarde optioneel is, en het eigenlijk betekent “het kan `None` zijn”, zelfs als het niet optioneel is en nog steeds vereist is. - -Ik denk dat `Union[SomeType, None]` explicieter is over wat het betekent. - -Het gaat alleen om de woorden en naamgeving. Maar die naamgeving kan invloed hebben op hoe jij en je teamgenoten over de code denken. - -Laten we als voorbeeld deze functie nemen: - -{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} - - -De parameter `name` is gedefinieerd als `Optional[str]`, maar is **niet optioneel**, je kunt de functie niet aanroepen zonder de parameter: - -```Python -say_hi() # Oh, nee, dit geeft een foutmelding! 😱 -``` - -De `name` parameter is **nog steeds vereist** (niet *optioneel*) omdat het geen standaardwaarde heeft. Toch accepteert `name` `None` als waarde: - -```Python -say_hi(name=None) # Dit werkt, None is geldig 🎉 -``` - -Het goede nieuws is dat als je eenmaal Python 3.10 gebruikt, je je daar geen zorgen meer over hoeft te maken, omdat je dan gewoon `|` kunt gebruiken om unions van types te definiÃĢren: - -{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *} - - -Dan hoef je je geen zorgen te maken over namen als `Optional` en `Union`. 😎 - -#### Generieke typen - -De types die typeparameters in vierkante haakjes gebruiken, worden **Generieke types** of **Generics** genoemd, bijvoorbeeld: - -//// tab | Python 3.10+ - -Je kunt dezelfde ingebouwde types gebruiken als generics (met vierkante haakjes en types erin): - -* `list` -* `tuple` -* `set` -* `dict` - -Hetzelfde als bij Python 3.8, uit de `typing`-module: - -* `Union` -* `Optional` (hetzelfde als bij Python 3.8) -* ...en anderen. - -In Python 3.10 kun je , als alternatief voor de generieke `Union` en `Optional`, de verticale lijn (`|`) gebruiken om unions van typen te voorzien, dat is veel beter en eenvoudiger. - -//// - -//// tab | Python 3.9+ - -Je kunt dezelfde ingebouwde types gebruiken als generieke types (met vierkante haakjes en types erin): - -* `list` -* `tuple` -* `set` -* `dict` - -En hetzelfde als met Python 3.8, vanuit de `typing`-module: - -* `Union` -* `Optional` -* ...en anderen. - -//// - -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ...en anderen. - -//// - -### Klassen als types - -Je kunt een klasse ook declareren als het type van een variabele. - -Stel dat je een klasse `Person` hebt, met een naam: - -{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} - - -Vervolgens kun je een variabele van het type `Persoon` declareren: - -{* ../../docs_src/python_types/tutorial010.py hl[6] *} - - -Dan krijg je ook nog eens volledige editorondersteuning: - - - -Merk op dat dit betekent dat "`one_person` een **instantie** is van de klasse `Person`". - -Dit betekent niet dat `one_person` de **klasse** is met de naam `Person`. - -## Pydantic modellen - -Pydantic is een Python-pakket voor het uitvoeren van datavalidatie. - -Je declareert de "vorm" van de data als klassen met attributen. - -Elk attribuut heeft een type. - -Vervolgens maak je een instantie van die klasse met een aantal waarden en het valideert de waarden, converteert ze naar het juiste type (als dat het geval is) en geeft je een object met alle data terug. - -Daarnaast krijg je volledige editorondersteuning met dat resulterende object. - -Een voorbeeld uit de officiÃĢle Pydantic-documentatie: - -//// tab | Python 3.10+ - -```Python -{!> ../../docs_src/python_types/tutorial011_py310.py!} -``` - -//// - -//// tab | Python 3.9+ - -```Python -{!> ../../docs_src/python_types/tutorial011_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -```Python -{!> ../../docs_src/python_types/tutorial011.py!} -``` - -//// - -/// info - -Om meer te leren over Pydantic, bekijk de documentatie. - -/// - -**FastAPI** is volledig gebaseerd op Pydantic. - -Je zult veel meer van dit alles in de praktijk zien in de [Tutorial - Gebruikershandleiding](tutorial/index.md){.internal-link target=_blank}. - -/// tip - -Pydantic heeft een speciaal gedrag wanneer je `Optional` of `Union[EenType, None]` gebruikt zonder een standaardwaarde, je kunt er meer over lezen in de Pydantic-documentatie over Verplichte optionele velden. - -/// - -## Type Hints met Metadata Annotaties - -Python heeft ook een functie waarmee je **extra metadata** in deze type hints kunt toevoegen met behulp van `Annotated`. - -//// tab | Python 3.9+ - -In Python 3.9 is `Annotated` onderdeel van de standaardpakket, dus je kunt het importeren vanuit `typing`. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -In versies lager dan Python 3.9 importeer je `Annotated` vanuit `typing_extensions`. - -Het wordt al geïnstalleerd met **FastAPI**. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013.py!} -``` - -//// - -Python zelf doet niets met deze `Annotated` en voor editors en andere hulpmiddelen is het type nog steeds een `str`. - -Maar je kunt deze ruimte in `Annotated` gebruiken om **FastAPI** te voorzien van extra metadata over hoe je wilt dat je applicatie zich gedraagt. - -Het belangrijkste om te onthouden is dat **de eerste *typeparameter*** die je doorgeeft aan `Annotated` het **werkelijke type** is. De rest is gewoon metadata voor andere hulpmiddelen. - -Voor nu hoef je alleen te weten dat `Annotated` bestaat en dat het standaard Python is. 😎 - -Later zul je zien hoe **krachtig** het kan zijn. - -/// tip - -Het feit dat dit **standaard Python** is, betekent dat je nog steeds de **best mogelijke ontwikkelaarservaring** krijgt in je editor, met de hulpmiddelen die je gebruikt om je code te analyseren en te refactoren, enz. ✨ - -Daarnaast betekent het ook dat je code zeer verenigbaar zal zijn met veel andere Python-hulpmiddelen en -pakketten. 🚀 - -/// - -## Type hints in **FastAPI** - -**FastAPI** maakt gebruik van type hints om verschillende dingen te doen. - -Met **FastAPI** declareer je parameters met type hints en krijg je: - -* **Editor ondersteuning**. -* **Type checks**. - -...en **FastAPI** gebruikt dezelfde declaraties om: - -* **Vereisten te definïeren **: van request pad parameters, query parameters, headers, bodies, dependencies, enz. -* **Data te converteren**: van de request naar het vereiste type. -* **Data te valideren**: afkomstig van elke request: - * **Automatische foutmeldingen** te genereren die naar de client worden geretourneerd wanneer de data ongeldig is. -* De API met OpenAPI te **documenteren**: - * die vervolgens wordt gebruikt door de automatische interactieve documentatie gebruikersinterfaces. - -Dit klinkt misschien allemaal abstract. Maak je geen zorgen. Je ziet dit allemaal in actie in de [Tutorial - Gebruikershandleiding](tutorial/index.md){.internal-link target=_blank}. - -Het belangrijkste is dat door standaard Python types te gebruiken, op ÊÊn plek (in plaats van meer klassen, decorators, enz. toe te voegen), **FastAPI** een groot deel van het werk voor je doet. - -/// info - -Als je de hele tutorial al hebt doorgenomen en terug bent gekomen om meer te weten te komen over types, is een goede bron het "cheat sheet" van `mypy`. - -/// diff --git a/docs/nl/mkdocs.yml b/docs/nl/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/nl/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/pl/docs/features.md b/docs/pl/docs/features.md deleted file mode 100644 index 80d3bdece..000000000 --- a/docs/pl/docs/features.md +++ /dev/null @@ -1,201 +0,0 @@ -# Cechy - -## Cechy FastAPI - -**FastAPI** zapewnia Ci następujące korzyści: - -### Oparcie o standardy open - -* OpenAPI do tworzenia API, w tym deklaracji ścieÅŧek operacji, parametrÃŗw, ciał zapytań, bezpieczeństwa, itp. -* Automatyczna dokumentacja modelu danych za pomocą JSON Schema (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. - -* Swagger UI, z interaktywnym interfejsem - odpytuj i testuj swoje API bezpośrednio z przeglądarki. - -![Swagger UI interakcja](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Alternatywna dokumentacja API z ReDoc. - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Nowoczesny Python - -Wszystko opiera się na standardowych deklaracjach typu **Python 3.8** (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 Python developer survey jasno wskazuje, Åŧe najczęściej uÅŧywaną funkcjonalnością jest autouzupełnianie w edytorze. - -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: - -* Visual Studio Code: - -![wsparcie edytora](https://fastapi.tiangolo.com/img/vscode-completion.png) - -* PyCharm: - -![wsparcie edytora](https://fastapi.tiangolo.com/img/pycharm-completion.png) - -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 **ciasteczka sesyjne**). - -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 Wstrzykiwania ZaleÅŧności. - -* 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ę **operacji na ścieÅŧce**. -* **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% pokrycia kodu testami. -* 100% adnotacji typÃŗw. -* UÅŧywany w aplikacjach produkcyjnych. - -## Cechy Starlette - -**FastAPI** jest w pełni kompatybilny z (oraz bazuje na) Starlette. 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 jeden z najszybszych dostępnych frameworkÃŗw Pythona, na rÃŗwni z **NodeJS** i **Go**. -* Wsparcie dla **WebSocket**. -* Zadania w tle. -* 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) Pydantic. 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 ORM, ODM 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 **IDE/linterem/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. -* 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. diff --git a/docs/pl/docs/help-fastapi.md b/docs/pl/docs/help-fastapi.md deleted file mode 100644 index 3ea328dc2..000000000 --- a/docs/pl/docs/help-fastapi.md +++ /dev/null @@ -1,269 +0,0 @@ -# PomÃŗÅŧ FastAPI - Uzyskaj pomoc - -Czy podoba Ci się **FastAPI**? - -Czy chciałbyś pomÃŗc FastAPI, jego uÅŧytkownikom i autorowi? - -MoÅŧe napotkałeś na trudności z **FastAPI** i potrzebujesz pomocy? - -Istnieje kilka bardzo łatwych sposobÃŗw, aby pomÃŗc (czasami wystarczy jedno lub dwa kliknięcia). - -Istnieje rÃŗwnieÅŧ kilka sposobÃŗw uzyskania pomocy. - -## Zapisz się do newslettera - -MoÅŧesz zapisać się do rzadkiego [newslettera o **FastAPI i jego przyjaciołach**](newsletter.md){.internal-link target=_blank}, aby być na bieÅŧąco z: - -* Aktualnościami o FastAPI i przyjaciołach 🚀 -* Przewodnikami 📝 -* Funkcjami ✨ -* Przełomowymi zmianami 🚨 -* Poradami i sztuczkami ✅ - -## ŚledÅē FastAPI na Twitterze - -ŚledÅē @fastapi na **Twitterze** aby być na bieÅŧąco z najnowszymi wiadomościami o **FastAPI**. đŸĻ - -## Dodaj gwiazdkę **FastAPI** na GitHubie - -MoÅŧesz "dodać gwiazdkę" FastAPI na GitHubie (klikając przycisk gwiazdki w prawym gÃŗrnym rogu): https://github.com/fastapi/fastapi. â­ī¸ - -Dodając gwiazdkę, inni uÅŧytkownicy będą mogli łatwiej znaleÅēć projekt i zobaczyć, Åŧe był juÅŧ przydatny dla innych. - -## Obserwuj repozytorium GitHub w poszukiwaniu nowych wydań - -MoÅŧesz "obserwować" FastAPI na GitHubie (klikając przycisk "obserwuj" w prawym gÃŗrnym rogu): https://github.com/fastapi/fastapi. 👀 - -Wybierz opcję "Tylko wydania". - -Dzięki temu będziesz otrzymywać powiadomienia (na swÃŗj adres e-mail) za kaÅŧdym razem, gdy pojawi się nowe wydanie (nowa wersja) **FastAPI** z poprawkami błędÃŗw i nowymi funkcjami. - -## Skontaktuj się z autorem - -MoÅŧesz skontaktować się ze mną (SebastiÃĄn Ramírez / `tiangolo`), autorem. - -MoÅŧesz: - -* Śledzić mnie na **GitHubie**. - * Zobacz inne projekty open source, ktÃŗre stworzyłem, a mogą być dla Ciebie pomocne. - * ŚledÅē mnie, aby dostać powiadomienie, gdy utworzę nowy projekt open source. -* Śledzić mnie na **Twitterze** lub na Mastodonie. - * Napisz mi, w jaki sposÃŗb korzystasz z FastAPI (uwielbiam o tym czytać). - * Dowiedz się, gdy ogłoszę coś nowego lub wypuszczę nowe narzędzia. - * MoÅŧesz takÅŧe śledzić @fastapi na Twitterze (to oddzielne konto). -* NawiąÅŧ ze mną kontakt na **Linkedinie**. - * Dowiedz się, gdy ogłoszę coś nowego lub wypuszczę nowe narzędzia (chociaÅŧ częściej korzystam z Twittera 🤷‍♂). -* Czytaj moje posty (lub śledÅē mnie) na **Dev.to** lub na **Medium**. - * Czytaj o innych pomysłach, artykułach i dowiedz się o narzędziach, ktÃŗre stworzyłem. - * ŚledÅē mnie, by wiedzieć gdy opublikuję coś nowego. - -## Napisz tweeta o **FastAPI** - -Napisz tweeta o **FastAPI** i powiedz czemu Ci się podoba. 🎉 - -Uwielbiam czytać w jaki sposÃŗb **FastAPI** jest uÅŧywane, co Ci się w nim podobało, w jakim projekcie/firmie go uÅŧywasz itp. - -## Głosuj na FastAPI - -* Głosuj na **FastAPI** w Slant. -* Głosuj na **FastAPI** w AlternativeTo. -* Powiedz, Åŧe uÅŧywasz **FastAPI** na StackShare. - -## Pomagaj innym, odpowiadając na ich pytania na GitHubie - -MoÅŧesz sprÃŗbować pomÃŗc innym, odpowiadając w: - -* Dyskusjach na GitHubie -* Problemach na GitHubie - -W wielu przypadkach moÅŧesz juÅŧ znać odpowiedÅē na te pytania. 🤓 - -Jeśli pomoÅŧesz wielu ludziom, moÅŧesz zostać oficjalnym [Ekspertem FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. 🎉 - -Pamiętaj tylko o najwaÅŧniejszym: bądÅē Åŧyczliwy. Ludzie przychodzą sfrustrowani i w wielu przypadkach nie zadają pytań w najlepszy sposÃŗb, ale mimo to postaraj się być dla nich jak najbardziej Åŧyczliwy. 🤗 - -Chciałbym, by społeczność **FastAPI** była Åŧyczliwa i przyjazna. Nie akceptuj prześladowania ani braku szacunku wobec innych. Dbajmy o siebie nawzajem. - ---- - -Oto, jak pomÃŗc innym z pytaniami (w dyskusjach lub problemach): - -### Zrozum pytanie - -* Upewnij się, czy rozumiesz **cel** i przypadek uÅŧycia osoby pytającej. - -* Następnie sprawdÅē, czy pytanie (większość to pytania) jest **jasne**. - -* W wielu przypadkach zadane pytanie dotyczy rozwiązania wymyślonego przez uÅŧytkownika, ale moÅŧe istnieć **lepsze** rozwiązanie. Jeśli dokładnie zrozumiesz problem i przypadek uÅŧycia, być moÅŧe będziesz mÃŗgł zaproponować lepsze **alternatywne rozwiązanie**. - -* Jeśli nie rozumiesz pytania, poproś o więcej **szczegÃŗÅ‚Ãŗw**. - -### OdtwÃŗrz problem - -W większości przypadkÃŗw problem wynika z **autorskiego kodu** osoby pytającej. - -Często pytający umieszczają tylko fragment kodu, niewystarczający do **odtworzenia problemu**. - -* MoÅŧesz poprosić ich o dostarczenie minimalnego, odtwarzalnego przykładu, ktÃŗry moÅŧesz **skopiować i wkleić** i uruchomić lokalnie, aby zobaczyć ten sam błąd lub zachowanie, ktÃŗre widzą, lub lepiej zrozumieć ich przypadki uÅŧycia. - -* Jeśli jesteś wyjątkowo pomocny, moÅŧesz sprÃŗbować **stworzyć taki przykład** samodzielnie, opierając się tylko na opisie problemu. Miej na uwadze, Åŧe moÅŧe to zająć duÅŧo czasu i lepiej moÅŧe być najpierw poprosić ich o wyjaśnienie problemu. - -### Proponuj rozwiązania - -* Po zrozumieniu pytania moÅŧesz podać im moÅŧliwą **odpowiedÅē**. - -* W wielu przypadkach lepiej zrozumieć ich **podstawowy problem lub przypadek uÅŧycia**, poniewaÅŧ moÅŧe istnieć lepszy sposÃŗb rozwiązania niÅŧ to, co prÃŗbują zrobić. - -### Poproś o zamknięcie - -Jeśli odpowiedzą, jest duÅŧa szansa, Åŧe rozwiązałeś ich problem, gratulacje, **jesteś bohaterem**! đŸĻ¸ - -* Jeśli Twoja odpowiedÅē rozwiązała problem, moÅŧesz poprosić o: - - * W Dyskusjach na GitHubie: oznaczenie komentarza jako **odpowiedÅē**. - * W Problemach na GitHubie: **zamknięcie** problemu. - -## Obserwuj repozytorium na GitHubie - -MoÅŧesz "obserwować" FastAPI na GitHubie (klikając przycisk "obserwuj" w prawym gÃŗrnym rogu): https://github.com/fastapi/fastapi. 👀 - -Jeśli wybierzesz "Obserwuj" zamiast "Tylko wydania", otrzymasz powiadomienia, gdy ktoś utworzy nowy problem lub pytanie. MoÅŧesz rÃŗwnieÅŧ określić, Åŧe chcesz być powiadamiany tylko o nowych problemach, dyskusjach, PR-ach itp. - -Następnie moÅŧesz sprÃŗbować pomÃŗc rozwiązać te problemy. - -## Zadawaj pytania - -MoÅŧesz utworzyć nowe pytanie w repozytorium na GitHubie, na przykład aby: - -* Zadać **pytanie** lub zapytać o **problem**. -* Zaproponować nową **funkcję**. - -**Uwaga**: jeśli to zrobisz, poproszę Cię rÃŗwnieÅŧ o pomoc innym. 😉 - -## Przeglądaj Pull Requesty - -MoÅŧesz pomÃŗc mi w przeglądaniu pull requestÃŗw autorstwa innych osÃŗb. - -Jak wcześniej wspomniałem, postaraj się być jak najbardziej Åŧyczliwy. 🤗 - ---- - -Oto, co warto mieć na uwadze podczas oceny pull requestu: - -### Zrozum problem - -* Najpierw upewnij się, Åŧe **rozumiesz problem**, ktÃŗry prÃŗbuje rozwiązać pull request. MoÅŧe być osadzony w większym kontekście w GitHubowej dyskusji lub problemie. - -* Jest teÅŧ duÅŧa szansa, Åŧe pull request nie jest konieczny, poniewaÅŧ problem moÅŧna rozwiązać w **inny sposÃŗb**. Wtedy moÅŧesz to zasugerować lub o to zapytać. - -### Nie martw się stylem - -* Nie przejmuj się zbytnio rzeczami takimi jak style wiadomości commitÃŗw, przy wcielaniu pull requesta łączę commity i modyfikuję opis sumarycznego commita ręcznie. - -* Nie przejmuj się rÃŗwnieÅŧ stylem kodu, automatyczne narzędzia w repozytorium sprawdzają to samodzielnie. - -A jeśli istnieje jakaś konkretna potrzeba dotycząca stylu lub spÃŗjności, sam poproszę o zmiany lub dodam commity z takimi zmianami. - -### SprawdÅē kod - -* Przeczytaj kod, zastanÃŗw się czy ma sens, **uruchom go lokalnie** i potwierdÅē czy faktycznie rozwiązuje problem. - -* Następnie dodaj **komentarz** z informacją o tym, Åŧe sprawdziłeś kod, dzięki temu będę miał pewność, Åŧe faktycznie go sprawdziłeś. - -/// info - -Niestety, nie mogę ślepo ufać PR-om, nawet jeśli mają kilka zatwierdzeń. - -Kilka razy zdarzyło się, Åŧe PR-y miały 3, 5 lub więcej zatwierdzeń (prawdopodobnie dlatego, Åŧe opis obiecuje rozwiązanie waÅŧnego problemu), ale gdy sam sprawdziłem danego PR-a, okazał się być zbugowany lub nie rozwiązywał problemu, ktÃŗry rzekomo miał rozwiązywać. 😅 - -Dlatego tak waÅŧne jest, abyś faktycznie przeczytał i uruchomił kod oraz napisał w komentarzu, Åŧe to zrobiłeś. 🤓 - -/// - -* Jeśli PR moÅŧna uprościć w jakiś sposÃŗb, moÅŧesz o to poprosić, ale nie ma potrzeby być zbyt wybrednym, moÅŧe być wiele subiektywnych punktÃŗw widzenia (a ja teÅŧ będę miał swÃŗj 🙈), więc lepiej Åŧebyś skupił się na kluczowych rzeczach. - -### Testy - -* PomÃŗÅŧ mi sprawdzić, czy PR ma **testy**. - -* SprawdÅē, czy testy **nie przechodzą** przed PR. 🚨 - -* Następnie sprawdÅē, czy testy **przechodzą** po PR. ✅ - -* Wiele PR-Ãŗw nie ma testÃŗw, moÅŧesz **przypomnieć** im o dodaniu testÃŗw, a nawet **zaproponować** samemu jakieś testy. To jedna z rzeczy, ktÃŗre pochłaniają najwięcej czasu i moÅŧesz w tym bardzo pomÃŗc. - -* Następnie skomentuj rÃŗwnieÅŧ to, czego sprÃŗbowałeś, wtedy będę wiedział, Åŧe to sprawdziłeś. 🤓 - -## UtwÃŗrz Pull Request - -MoÅŧesz [wnieść wkład](contributing.md){.internal-link target=_blank} do kodu ÅērÃŗdłowego za pomocą Pull Requestu, na przykład: - -* Naprawić literÃŗwkę, ktÃŗrą znalazłeś w dokumentacji. -* Podzielić się artykułem, filmem lub podcastem, ktÃŗry stworzyłeś lub znalazłeś na temat FastAPI, edytując ten plik. - * Upewnij się, Åŧe dodajesz swÃŗj link na początku odpowiedniej sekcji. -* PomÃŗc w [tłumaczeniu dokumentacji](contributing.md#translations){.internal-link target=_blank} na TwÃŗj język. - * MoÅŧesz rÃŗwnieÅŧ pomÃŗc w weryfikacji tłumaczeń stworzonych przez innych. -* Zaproponować nowe sekcje dokumentacji. -* Naprawić istniejący problem/błąd. - * Upewnij się, Åŧe dodajesz testy. -* Dodać nową funkcję. - * Upewnij się, Åŧe dodajesz testy. - * Upewnij się, Åŧe dodajesz dokumentację, jeśli jest to istotne. - -## PomÃŗÅŧ w utrzymaniu FastAPI - -PomÃŗÅŧ mi utrzymać **FastAPI**! 🤓 - -Jest wiele pracy do zrobienia, a w większości przypadkÃŗw **TY** moÅŧesz to zrobić. - -GÅ‚Ãŗwne zadania, ktÃŗre moÅŧesz wykonać teraz to: - -* [PomÃŗc innym z pytaniami na GitHubie](#pomagaj-innym-odpowiadajac-na-ich-pytania-na-githubie){.internal-link target=_blank} (zobacz sekcję powyÅŧej). -* [Oceniać Pull Requesty](#przegladaj-pull-requesty){.internal-link target=_blank} (zobacz sekcję powyÅŧej). - -Te dwie czynności **zajmują najwięcej czasu**. To gÅ‚Ãŗwna praca związana z utrzymaniem FastAPI. - -Jeśli moÅŧesz mi w tym pomÃŗc, **pomoÅŧesz mi utrzymać FastAPI** i zapewnisz Åŧe będzie **rozwijać się szybciej i lepiej**. 🚀 - -## Dołącz do czatu - -Dołącz do đŸ‘Ĩ serwera czatu na Discordzie đŸ‘Ĩ i spędzaj czas z innymi w społeczności FastAPI. - -/// tip | WskazÃŗwka - -Jeśli masz pytania, zadaj je w Dyskusjach na GitHubie, jest duÅŧo większa szansa, Åŧe otrzymasz pomoc od [EkspertÃŗw FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. - -UÅŧywaj czatu tylko do innych ogÃŗlnych rozmÃŗw. - -/// - -### Nie zadawaj pytań na czacie - -Miej na uwadze, Åŧe poniewaÅŧ czaty pozwalają na bardziej "swobodną rozmowę", łatwo jest zadawać pytania, ktÃŗre są zbyt ogÃŗlne i trudniejsze do odpowiedzi, więc moÅŧesz nie otrzymać odpowiedzi. - -Na GitHubie szablon poprowadzi Cię do napisania odpowiedniego pytania, dzięki czemu łatwiej uzyskasz dobrą odpowiedÅē, a nawet rozwiąÅŧesz problem samodzielnie, zanim zapytasz. Ponadto na GitHubie mogę się upewnić, Åŧe zawsze odpowiadam na wszystko, nawet jeśli zajmuje to trochę czasu. Osobiście nie mogę tego zrobić z systemami czatu. 😅 - -RozmÃŗw w systemach czatu nie moÅŧna tak łatwo przeszukiwać, jak na GitHubie, więc pytania i odpowiedzi mogą zaginąć w rozmowie. A tylko te na GitHubie liczą się do zostania [Ekspertem FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, więc najprawdopodobniej otrzymasz więcej uwagi na GitHubie. - -Z drugiej strony w systemach czatu są tysiące uÅŧytkownikÃŗw, więc jest duÅŧa szansa, Åŧe znajdziesz tam kogoś do rozmowy, prawie w kaÅŧdej chwili. 😄 - -## Wspieraj autora - -MoÅŧesz rÃŗwnieÅŧ finansowo wesprzeć autora (mnie) poprzez sponsoring na GitHubie. - -Tam moÅŧesz postawić mi kawę â˜•ī¸ aby podziękować. 😄 - -MoÅŧesz takÅŧe zostać srebrnym lub złotym sponsorem FastAPI. 🏅🎉 - -## Wspieraj narzędzia, ktÃŗre napędzają FastAPI - -Jak widziałeś w dokumentacji, FastAPI stoi na ramionach gigantÃŗw, Starlette i Pydantic. - -MoÅŧesz rÃŗwnieÅŧ wesprzeć: - -* Samuel Colvin (Pydantic) -* Encode (Starlette, Uvicorn) - ---- - -Dziękuję! 🚀 diff --git a/docs/pl/docs/index.md b/docs/pl/docs/index.md deleted file mode 100644 index 0e13d2631..000000000 --- a/docs/pl/docs/index.md +++ /dev/null @@ -1,467 +0,0 @@ -# FastAPI - - - -

- FastAPI -

-

- FastAPI to szybki, prosty w nauce i gotowy do uÅŧycia w produkcji framework -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**Dokumentacja**: https://fastapi.tiangolo.com - -**Kod ÅŧrÃŗdłowy**: https://github.com/fastapi/fastapi - ---- - -FastAPI to nowoczesny, wydajny framework webowy do budowania API z uÅŧyciem Pythona bazujący na standardowym typowaniu Pythona. - -Kluczowe cechy: - -* **Wydajność**: FastAPI jest bardzo wydajny, na rÃŗwni z **NodeJS** oraz **Go** (dzięki Starlette i Pydantic). [Jeden z najszybszych dostępnych frameworkÃŗw Pythonowych](#wydajnosc). -* **Szybkość kodowania**: Przyśpiesza szybkość pisania nowych funkcjonalności o około 200% do 300%. * -* **Mniejsza ilość błędÃŗw**: Zmniejsza ilość ludzkich (dewelopera) błędy o około 40%. * -* **Intuicyjność**: Wspaniałe wsparcie dla edytorÃŗw kodu. Dostępne wszędzie automatyczne uzupełnianie kodu. KrÃŗtszy czas debugowania. -* **Łatwość**: Zaprojektowany by być prosty i łatwy do nauczenia. Mniej czasu spędzonego na czytanie dokumentacji. -* **Kompaktowość**: Minimalizacja powtarzającego się kodu. Wiele funkcjonalności dla kaÅŧdej deklaracji parametru. Mniej błędÃŗw. -* **Solidność**: Kod gotowy dla środowiska produkcyjnego. Wraz z automatyczną interaktywną dokumentacją. -* **Bazujący na standardach**: Oparty na (i w pełni kompatybilny z) otwartych standardach API: OpenAPI (wcześniej znane jako Swagger) oraz JSON Schema. - -* oszacowania bazowane na testach wykonanych przez wewnętrzny zespÃŗÅ‚ deweloperÃŗw, budujących aplikacie uÅŧywane na środowisku produkcyjnym. - -## Sponsorzy - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -Inni sponsorzy - -## Opinie - -"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" - -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_I’m over the moon excited about **FastAPI**. It’s so fun!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_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._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_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 [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- - -## **Typer**, FastAPI aplikacji konsolowych - - - -JeÅŧeli tworzysz aplikacje CLI, ktÃŗra ma być uÅŧywana w terminalu zamiast API, sprawdÅē **Typer**. - -**Typer** to młodsze rodzeństwo FastAPI. Jego celem jest pozostanie **FastAPI aplikacji konsolowych** . âŒ¨ī¸ 🚀 - -## Wymagania - -FastAPI oparty jest na: - -* Starlette dla części webowej. -* Pydantic dla części obsługujących dane. - -## Instalacja - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -Na serwerze produkcyjnym będziesz takÅŧe potrzebował serwera ASGI, np. Uvicorn lub Hypercorn. - -
- -```console -$ pip install "uvicorn[standard]" - ----> 100% -``` - -
- -## Przykład - -### StwÃŗrz - -* UtwÃŗrz plik o nazwie `main.py` z: - -```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} -``` - -
-Albo uÅŧyj async def... - -JeÅŧeli twÃŗj kod korzysta z `async` / `await`, uÅŧyj `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} -``` - -**Przypis**: - -JeÅŧeli nie znasz, sprawdÅē sekcję _"In a hurry?"_ o `async` i `await` w dokumentacji. - -
- -### Uruchom - -Uruchom serwer uÅŧywając: - -
- -```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. -``` - -
- -
-O komendzie uvicorn main:app --reload... -Komenda `uvicorn main:app` odnosi się do: - -* `main`: plik `main.py` ("moduł" w Pythonie). -* `app`: obiekt stworzony w `main.py` w lini `app = FastAPI()`. -* `--reload`: spraw by serwer resetował się po kaÅŧdej zmianie w kodzie. UÅŧywaj tego tylko w środowisku deweloperskim. - -
- -### WyprÃŗbuj - -OtwÃŗrz link http://127.0.0.1:8000/items/5?q=somequery w przeglądarce. - -Zobaczysz następującą odpowiedÅē JSON: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -Właśnie stworzyłeś API ktÃŗre: - -* Otrzymuje Åŧądania HTTP w _ścieÅŧce_ `/` i `/items/{item_id}`. -* Obie _ścieÅŧki_ uÅŧywają operacji `GET` (znane takÅŧe jako _metody_ HTTP). -* _ŚcieÅŧka_ `/items/{item_id}` ma _parametr ścieÅŧki_ `item_id` ktÃŗry powinien być obiektem typu `int`. -* _ŚcieÅŧka_ `/items/{item_id}` ma opcjonalny _parametr zapytania_ typu `str` o nazwie `q`. - -### Interaktywna dokumentacja API - -OtwÃŗrz teraz stronę http://127.0.0.1:8000/docs. - -Zobaczysz automatyczną interaktywną dokumentację API (dostarczoną z pomocą Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternatywna dokumentacja API - -OtwÃŗrz teraz http://127.0.0.1:8000/redoc. - -Zobaczysz alternatywną, lecz wciąÅŧ automatyczną dokumentację (wygenerowaną z pomocą ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## Aktualizacja przykładu - -Zmodyfikuj teraz plik `main.py`, aby otrzmywał treść (body) Åŧądania `PUT`. - -Zadeklaruj treść Åŧądania, uÅŧywając standardowych typÃŗw w Pythonie dzięki Pydantic. - -```Python hl_lines="4 9-12 25-27" -from typing import 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} -``` - -Serwer powinien przeładować się automatycznie (poniewaÅŧ dodałeś `--reload` do komendy `uvicorn` powyÅŧej). - -### Zaktualizowana interaktywna dokumentacja API - -WejdÅē teraz na http://127.0.0.1:8000/docs. - -* Interaktywna dokumentacja API zaktualizuje sie automatycznie, takÅŧe z nową treścią Åŧądania (body): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Kliknij przycisk "Try it out" (wyprÃŗbuj), pozwoli Ci to wypełnić parametry i bezpośrednio uÅŧyć API: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Kliknij potem przycisk "Execute" (wykonaj), interfejs uÅŧytkownika połączy się z API, wyśle parametry, otrzyma odpowiedÅē i wyświetli ją na ekranie: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### Zaktualizowana alternatywna dokumentacja API - -OtwÃŗrz teraz http://127.0.0.1:8000/redoc. - -* Alternatywna dokumentacja rÃŗwnieÅŧ pokaÅŧe zaktualizowane parametry i treść Åŧądania (body): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### Podsumowanie - -Podsumowując, musiałeś zadeklarować typy parametrÃŗw, treści Åŧądania (body) itp. tylko **raz**, i są one dostępne jako parametry funkcji. - -Robisz to tak samo jak ze standardowymi typami w Pythonie. - -Nie musisz sie uczyć Åŧadnej nowej składni, metod lub klas ze specyficznych bibliotek itp. - -Po prostu standardowy **Python**. - -Na przykład, dla danych typu `int`: - -```Python -item_id: int -``` - -albo dla bardziej złoÅŧonego obiektu `Item`: - -```Python -item: Item -``` - -...i z pojedyńczą deklaracją otrzymujesz: - -* Wsparcie edytorÃŗw kodu, wliczając: - * Auto-uzupełnianie. - * Sprawdzanie typÃŗw. -* Walidacja danych: - * Automatyczne i przejrzyste błędy gdy dane są niepoprawne. - * Walidacja nawet dla głęboko zagnieÅŧdÅŧonych obiektÃŗw JSON. -* Konwersja danych wejściowych: przychodzących z sieci na Pythonowe typy. Pozwala na przetwarzanie danych: - * JSON. - * ParametrÃŗw ścieÅŧki. - * ParametrÃŗw zapytania. - * Dane cookies. - * Dane nagÅ‚ÃŗwkÃŗw (headers). - * Formularze. - * Pliki. -* Konwersja danych wyjściowych: wychodzących z Pythona do sieci (jako JSON): - * Przetwarzanie Pythonowych typÃŗw (`str`, `int`, `float`, `bool`, `list`, itp). - * Obiekty `datetime`. - * Obiekty `UUID`. - * Modele baz danych. - * ...i wiele więcej. -* Automatyczne interaktywne dokumentacje API, wliczając 2 alternatywne interfejsy uÅŧytkownika: - * Swagger UI. - * ReDoc. - ---- - -Wracając do poprzedniego przykładu, **FastAPI** : - -* Potwierdzi, Åŧe w ścieÅŧce jest `item_id` dla Åŧądań `GET` i `PUT`. -* Potwierdzi, Åŧe `item_id` jest typu `int` dla Åŧądań `GET` i `PUT`. - * JeÅŧeli nie jest, odbiorca zobaczy przydatną, przejrzystą wiadomość z błędem. -* Sprawdzi czy w ścieÅŧce jest opcjonalny parametr zapytania `q` (np. `http://127.0.0.1:8000/items/foo?q=somequery`) dla Åŧądania `GET`. - * Jako Åŧe parametr `q` jest zadeklarowany jako `= None`, jest on opcjonalny. - * Gdyby tego `None` nie było, parametr ten byłby wymagany (tak jak treść Åŧądania w Åŧądaniu `PUT`). -* Dla Åŧądania `PUT` z ścieÅŧką `/items/{item_id}`, odczyta treść Åŧądania jako JSON: - * Sprawdzi czy posiada wymagany atrybut `name`, ktÃŗry powinien być typu `str`. - * Sprawdzi czy posiada wymagany atrybut `price`, ktÃŗry musi być typu `float`. - * Sprawdzi czy posiada opcjonalny atrybut `is_offer`, ktÃŗry (jeÅŧeli obecny) powinien być typu `bool`. - * To wszystko będzie rÃŗwnieÅŧ działać dla głęboko zagnieÅŧdÅŧonych obiektÃŗw JSON. -* Automatycznie konwertuje z i do JSON. -* Dokumentuje wszystko w OpenAPI, ktÃŗre moÅŧe być uÅŧywane przez: - * Interaktywne systemy dokumentacji. - * Systemy automatycznego generowania kodu klienckiego, dla wielu językÃŗw. -* Dostarczy bezpośrednio 2 interaktywne dokumentacje webowe. - ---- - -To dopiero początek, ale juÅŧ masz mniej-więcej pojęcie jak to wszystko działa. - -SprÃŗbuj zmienić linijkę: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...z: - -```Python - ... "item_name": item.name ... -``` - -...na: - -```Python - ... "item_price": item.price ... -``` - -...i zobacz jak edytor kodu automatycznie uzupełni atrybuty i będzie znał ich typy: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -Dla bardziej kompletnych przykładÃŗw posiadających więcej funkcjonalności, zobacz Tutorial - User Guide. - -**Uwaga Spoiler**: tutorial - user guide zawiera: - -* Deklaracje **parametrÃŗw** z innych miejsc takich jak: **nagÅ‚Ãŗwki**, **pliki cookies**, **formularze** i **pliki**. -* Jak ustawić **ograniczenia walidacyjne** takie jak `maksymalna długość` lub `regex`. -* PotęÅŧny i łatwy w uÅŧyciu system **Dependency Injection**. -* Zabezpieczenia i autentykacja, wliczając wsparcie dla **OAuth2** z **tokenami JWT** oraz autoryzacją **HTTP Basic**. -* Bardziej zaawansowane (ale rÃŗwnie proste) techniki deklarowania **głęboko zagnieÅŧdÅŧonych modeli JSON** (dzięki Pydantic). -* Wiele dodatkowych funkcji (dzięki Starlette) takie jak: - * **WebSockety** - * **GraphQL** - * bardzo proste testy bazujące na HTTPX oraz `pytest` - * **CORS** - * **Sesje cookie** - * ...i więcej. - -## Wydajność - -NiezaleÅŧne benchmarki TechEmpower pokazują, Åŧe **FastAPI** (uruchomiony na serwerze Uvicorn) jest jednym z najszybszych dostępnych Pythonowych frameworkÃŗw, zaraz po Starlette i Uvicorn (uÅŧywanymi wewnątrznie przez FastAPI). (*) - -Aby dowiedzieć się o tym więcej, zobacz sekcję Benchmarks. - -## Opcjonalne zaleÅŧności - -UÅŧywane przez Pydantic: - -* email-validator - dla walidacji adresÃŗw email. - -UÅŧywane przez Starlette: - -* httpx - Wymagane jeÅŧeli chcesz korzystać z `TestClient`. -* aiofiles - Wymagane jeÅŧeli chcesz korzystać z `FileResponse` albo `StaticFiles`. -* jinja2 - Wymagane jeÅŧeli chcesz uÅŧywać domyślnej konfiguracji szablonÃŗw. -* python-multipart - Wymagane jeÅŧelich chcesz wsparcie "parsowania" formularzy, uÅŧywając `request.form()`. -* itsdangerous - Wymagany dla wsparcia `SessionMiddleware`. -* pyyaml - Wymagane dla wsparcia `SchemaGenerator` z Starlette (z FastAPI prawdopodobnie tego nie potrzebujesz). -* graphene - Wymagane dla wsparcia `GraphQLApp`. - -UÅŧywane przez FastAPI / Starlette: - -* uvicorn - jako serwer, ktÃŗry ładuje i obsługuje Twoją aplikację. -* orjson - Wymagane jeÅŧeli chcesz uÅŧywać `ORJSONResponse`. -* ujson - Wymagane jeÅŧeli chcesz korzystać z `UJSONResponse`. - -MoÅŧesz zainstalować wszystkie te aplikacje przy pomocy `pip install fastapi[all]`. - -## Licencja - -Ten projekt jest na licencji MIT. diff --git a/docs/pl/docs/tutorial/first-steps.md b/docs/pl/docs/tutorial/first-steps.md deleted file mode 100644 index 8fa4c75ad..000000000 --- a/docs/pl/docs/tutorial/first-steps.md +++ /dev/null @@ -1,335 +0,0 @@ -# Pierwsze kroki - -Najprostszy plik FastAPI moÅŧe wyglądać tak: - -{* ../../docs_src/first_steps/tutorial001.py *} - -Skopiuj to do pliku `main.py`. - -Uruchom serwer: - -
- -```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. -``` - -
- -/// note - -Polecenie `uvicorn main:app` odnosi się do: - -* `main`: plik `main.py` ("moduł" Python). -* `app`: obiekt utworzony w pliku `main.py` w lini `app = FastAPI()`. -* `--reload`: sprawia, Åŧe serwer uruchamia się ponownie po zmianie kodu. UÅŧywany tylko w trakcie tworzenia oprogramowania. - -/// - -Na wyjściu znajduje się linia z czymś w rodzaju: - -```hl_lines="4" -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -Ta linia pokazuje adres URL, pod ktÃŗrym Twoja aplikacja jest obsługiwana, na Twoim lokalnym komputerze. - -### SprawdÅē to - -OtwÃŗrz w swojej przeglądarce http://127.0.0.1:8000. - -Zobaczysz odpowiedÅē w formacie JSON: - -```JSON -{"message": "Hello World"} -``` - -### Interaktywna dokumentacja API - -PrzejdÅē teraz do http://127.0.0.1:8000/docs. - -Zobaczysz automatyczną i interaktywną dokumentację API (dostarczoną przez Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### Alternatywna dokumentacja API - -Teraz przejdÅē do http://127.0.0.1:8000/redoc. - -Zobaczysz alternatywną automatycznie wygenerowaną dokumentację API (dostarczoną przez ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -### OpenAPI - -**FastAPI** generuje "schemat" z całym Twoim API przy uÅŧyciu standardu **OpenAPI** słuÅŧącego do definiowania API. - -#### Schema - -"Schema" jest definicją lub opisem czegoś. Nie jest to kod, ktÃŗry go implementuje, ale po prostu abstrakcyjny opis. - -#### API "Schema" - -W typ przypadku, OpenAPI to specyfikacja, ktÃŗra dyktuje sposÃŗb definiowania schematu interfejsu API. - -Definicja schematu zawiera ścieÅŧki API, moÅŧliwe parametry, ktÃŗre są przyjmowane przez endpointy, itp. - -#### "Schemat" danych - -Termin "schemat" moÅŧe rÃŗwnieÅŧ odnosić się do wyglądu niektÃŗrych danych, takich jak zawartość JSON. - -W takim przypadku będzie to oznaczać atrybuty JSON, ich typy danych itp. - -#### OpenAPI i JSON Schema - -OpenAPI definiuje API Schema dla Twojego API, ktÃŗry zawiera definicje (lub "schematy") danych wysyłanych i odbieranych przez TwÃŗj interfejs API przy uÅŧyciu **JSON Schema**, standardu dla schematÃŗw danych w formacie JSON. - -#### SprawdÅē `openapi.json` - -Jeśli jesteś ciekawy, jak wygląda surowy schemat OpenAPI, FastAPI automatycznie generuje JSON Schema z opisami wszystkich Twoich API. - -MoÅŧesz to zobaczyć bezpośrednio pod adresem: http://127.0.0.1:8000/openapi.json. - -Zobaczysz JSON zaczynający się od czegoś takiego: - -```JSON -{ - "openapi": "3.0.2", - "info": { - "title": "FastAPI", - "version": "0.1.0" - }, - "paths": { - "/items/": { - "get": { - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - - - -... -``` - -#### Do czego słuÅŧy OpenAPI - -Schemat OpenAPI jest tym, co zasila dwa dołączone interaktywne systemy dokumentacji. - -Istnieją dziesiątki alternatyw, wszystkie oparte na OpenAPI. MoÅŧesz łatwo dodać dowolną z nich do swojej aplikacji zbudowanej za pomocą **FastAPI**. - -MoÅŧesz go rÃŗwnieÅŧ uÅŧyć do automatycznego generowania kodu dla klientÃŗw, ktÃŗrzy komunikują się z Twoim API. Na przykład aplikacje frontendowe, mobilne lub IoT. - -## Przypomnijmy, krok po kroku - -### Krok 1: zaimportuj `FastAPI` - -{* ../../docs_src/first_steps/tutorial001.py hl[1] *} - -`FastAPI` jest klasą, ktÃŗra zapewnia wszystkie funkcjonalności Twojego API. - -/// note | SzczegÃŗÅ‚y techniczne - -`FastAPI` jest klasą, ktÃŗra dziedziczy bezpośrednio z `Starlette`. - -Oznacza to, Åŧe moÅŧesz korzystać ze wszystkich funkcjonalności Starlette rÃŗwnieÅŧ w `FastAPI`. - -/// - -### Krok 2: utwÃŗrz instancję `FastAPI` - -{*../../docs_src/first_steps/tutorial001.py hl[3] *} - -Zmienna `app` będzie tutaj "instancją" klasy `FastAPI`. - -Będzie to gÅ‚Ãŗwny punkt interakcji przy tworzeniu całego interfejsu API. - -Ta zmienna `app` jest tą samą zmienną, do ktÃŗrej odnosi się `uvicorn` w poleceniu: - -
- -```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -Jeśli stworzysz swoją aplikację, np.: - -{* ../../docs_src/first_steps/tutorial002.py hl[3] *} - -I umieścisz to w pliku `main.py`, to będziesz mÃŗgł tak wywołać `uvicorn`: - -
- -```console -$ uvicorn main:my_awesome_api --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -### Krok 3: wykonaj *operację na ścieÅŧce* - -#### ŚcieÅŧka - -"ŚcieÅŧka" tutaj odnosi się do ostatniej części adresu URL, zaczynając od pierwszego `/`. - -Więc, w adresie URL takim jak: - -``` -https://example.com/items/foo -``` - -...ścieÅŧką będzie: - -``` -/items/foo -``` - -/// info - -"ŚcieÅŧka" jest zazwyczaj nazywana "path", "endpoint" lub "route'. - -/// - -Podczas budowania API, "ścieÅŧka" jest gÅ‚Ãŗwnym sposobem na oddzielenie "odpowiedzialności" i „zasobÃŗw”. - -#### Operacje - -"Operacje" tutaj odnoszą się do jednej z "metod" HTTP. - -Jedna z: - -* `POST` -* `GET` -* `PUT` -* `DELETE` - -...i te bardziej egzotyczne: - -* `OPTIONS` -* `HEAD` -* `PATCH` -* `TRACE` - -W protokole HTTP moÅŧna komunikować się z kaÅŧdą ścieÅŧką za pomocą jednej (lub więcej) "metod". - ---- - -Podczas tworzenia API zwykle uÅŧywasz tych metod HTTP do wykonania określonej akcji. - -Zazwyczaj uÅŧywasz: - -* `POST`: do tworzenia danych. -* `GET`: do odczytywania danych. -* `PUT`: do aktualizacji danych. -* `DELETE`: do usuwania danych. - -Tak więc w OpenAPI kaÅŧda z metod HTTP nazywana jest "operacją". - -Będziemy je rÃŗwnieÅŧ nazywali "**operacjami**". - -#### Zdefiniuj *dekorator operacji na ścieÅŧce* - -{* ../../docs_src/first_steps/tutorial001.py hl[6] *} - -`@app.get("/")` mÃŗwi **FastAPI** Åŧe funkcja poniÅŧej odpowiada za obsługę Åŧądań, ktÃŗre trafiają do: - -* ścieÅŧki `/` -* uÅŧywając operacji get - -/// info | `@decorator` Info - -Składnia `@something` jest w Pythonie nazywana "dekoratorem". - -Umieszczasz to na szczycie funkcji. Jak ładną ozdobną czapkę (chyba stąd wzięła się nazwa). - -"Dekorator" przyjmuje funkcję znajdującą się poniÅŧej jego i coś z nią robi. - -W naszym przypadku dekorator mÃŗwi **FastAPI**, Åŧe poniÅŧsza funkcja odpowiada **ścieÅŧce** `/` z **operacją** `get`. - -Jest to "**dekorator operacji na ścieÅŧce**". - -/// - -MoÅŧesz rÃŗwnieÅŧ uÅŧyć innej operacji: - -* `@app.post()` -* `@app.put()` -* `@app.delete()` - -Oraz tych bardziej egzotycznych: - -* `@app.options()` -* `@app.head()` -* `@app.patch()` -* `@app.trace()` - -/// tip - -MoÅŧesz dowolnie uÅŧywać kaÅŧdej operacji (metody HTTP). - -**FastAPI** nie narzuca Åŧadnego konkretnego znaczenia. - -Informacje tutaj są przedstawione jako wskazÃŗwka, a nie wymÃŗg. - -Na przykład, uÅŧywając GraphQL, normalnie wykonujesz wszystkie akcje uÅŧywając tylko operacji `POST`. - -/// - -### Krok 4: zdefiniuj **funkcję obsługującą ścieÅŧkę** - -To jest nasza "**funkcja obsługująca ścieÅŧkę**": - -* **ścieÅŧka**: to `/`. -* **operacja**: to `get`. -* **funkcja**: to funkcja poniÅŧej "dekoratora" (poniÅŧej `@app.get("/")`). - -{* ../../docs_src/first_steps/tutorial001.py hl[7] *} - -Jest to funkcja Python. - -Zostanie ona wywołana przez **FastAPI** za kaÅŧdym razem, gdy otrzyma Åŧądanie do adresu URL "`/`" przy uÅŧyciu operacji `GET`. - -W tym przypadku jest to funkcja "asynchroniczna". - ---- - -MoÅŧesz rÃŗwnieÅŧ zdefiniować to jako normalną funkcję zamiast `async def`: - -{* ../../docs_src/first_steps/tutorial003.py hl[7] *} - -/// note - -Jeśli nie znasz rÃŗÅŧnicy, sprawdÅē [Async: *"In a hurry?"*](../async.md#in-a-hurry){.internal-link target=_blank}. - -/// - -### Krok 5: zwrÃŗÄ‡ zawartość - -{* ../../docs_src/first_steps/tutorial001.py hl[8] *} - -MoÅŧesz zwrÃŗcić `dict`, `list`, pojedynczą wartość jako `str`, `int`, itp. - -MoÅŧesz rÃŗwnieÅŧ zwrÃŗcić modele Pydantic (więcej o tym pÃŗÅēniej). - -Istnieje wiele innych obiektÃŗw i modeli, ktÃŗre zostaną automatycznie skonwertowane do formatu JSON (w tym ORM itp.). SprÃŗbuj uÅŧyć swoich ulubionych, jest bardzo prawdopodobne, Åŧe są juÅŧ obsługiwane. - -## Podsumowanie - -* Zaimportuj `FastAPI`. -* StwÃŗrz instancję `app`. -* Dodaj **dekorator operacji na ścieÅŧce** (taki jak `@app.get("/")`). -* Napisz **funkcję obsługującą ścieÅŧkę** (taką jak `def root(): ...` powyÅŧej). -* Uruchom serwer deweloperski (`uvicorn main:app --reload`). diff --git a/docs/pl/docs/tutorial/index.md b/docs/pl/docs/tutorial/index.md deleted file mode 100644 index 66f7c6d62..000000000 --- a/docs/pl/docs/tutorial/index.md +++ /dev/null @@ -1,83 +0,0 @@ -# Samouczek - -Ten samouczek pokaÅŧe Ci, krok po kroku, jak uÅŧywać większości funkcji **FastAPI**. - -KaÅŧda część korzysta z poprzednich, ale jest jednocześnie osobnym tematem. MoÅŧesz przejść bezpośrednio do kaÅŧdego rozdziału, jeśli szukasz rozwiązania konkretnego problemu. - -Samouczek jest tak zbudowany, Åŧeby słuÅŧył jako punkt odniesienia w przyszłości. - -MoÅŧesz wracać i sprawdzać dokładnie to czego potrzebujesz. - -## Wykonywanie kodu - -Wszystkie fragmenty kodu mogą być skopiowane bezpośrednio i uÅŧyte (są poprawnymi i przetestowanymi plikami). - -Åģeby wykonać kaÅŧdy przykład skopiuj kod to pliku `main.py` i uruchom `uvicorn` za pomocą: - -
- -```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. -``` - -
- -**BARDZO zalecamy** pisanie bądÅē kopiowanie kodu, edycję, a następnie wykonywanie go lokalnie. - -UÅŧycie w Twoim edytorze jest tym, co pokazuje prawdziwe korzyści z FastAPI, pozwala zobaczyć jak mało kodu musisz napisać, wszystkie funkcje, takie jak kontrola typÃŗw, automatyczne uzupełnianie, itd. - ---- - -## Instalacja FastAPI - -Jako pierwszy krok zainstaluj FastAPI. - -Na potrzeby samouczka moÅŧesz zainstalować rÃŗwnieÅŧ wszystkie opcjonalne biblioteki: - -
- -```console -$ pip install "fastapi[all]" - ----> 100% -``` - -
- -...wliczając w to `uvicorn`, ktÃŗry będzie słuÅŧył jako serwer wykonujacy TwÃŗj kod. - -/// note - -MoÅŧesz rÃŗwnieÅŧ wykonać instalację "krok po kroku". - -Prawdopodobnie zechcesz to zrobić, kiedy będziesz wdraÅŧać swoją aplikację w środowisku produkcyjnym: - -``` -pip install fastapi -``` - -Zainstaluj teÅŧ `uvicorn`, ktÃŗry będzie słuÅŧył jako serwer: - -``` -pip install "uvicorn[standard]" -``` - -Tak samo moÅŧesz zainstalować wszystkie dodatkowe biblioteki, ktÃŗrych chcesz uÅŧyć. - -/// - -## Zaawansowany poradnik - -Jest teÅŧ **Zaawansowany poradnik**, ktÃŗry moÅŧesz przeczytać po lekturze tego **Samouczka**. - -**Zaawansowany poradnik** opiera się na tym samouczku, uÅŧywa tych samych pojęć, Åŧeby pokazać Ci kilka dodatkowych funkcji. - -Najpierw jednak powinieneś przeczytać **Samouczek** (czytasz go teraz). - -Ten rozdział jest zaprojektowany tak, Åŧe moÅŧesz stworzyć kompletną aplikację uÅŧywając tylko informacji tutaj zawartych, a następnie rozszerzać ją na rÃŗÅŧne sposoby, w zaleÅŧności od potrzeb, uÅŧywając kilku dodatkowych pomysÅ‚Ãŗw z **Zaawansowanego poradnika**. diff --git a/docs/pl/mkdocs.yml b/docs/pl/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/pl/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/pt/docs/advanced/security/oauth2-scopes.md b/docs/pt/docs/advanced/security/oauth2-scopes.md index 1d53f42d8..07b345945 100644 --- a/docs/pt/docs/advanced/security/oauth2-scopes.md +++ b/docs/pt/docs/advanced/security/oauth2-scopes.md @@ -4,9 +4,9 @@ VocÃĒ pode utilizar escopos do OAuth2 diretamente com o **FastAPI**, eles sÃŖo i Isso permitiria que vocÃĒ tivesse um sistema de permissionamento mais refinado, seguindo o padrÃŖo do OAuth2 integrado na sua aplicaÃ§ÃŖo OpenAPI (e as documentaçÃĩes da API). -OAuth2 com escopos Ê o mecanismo utilizado por muitos provedores de autenticaÃ§ÃŖo, como o Facebook, Google, GitHub, Microsoft, Twitter, etc. Eles utilizam isso para prover permissÃĩes específicas para os usuÃĄrios e aplicaçÃĩes. +OAuth2 com escopos Ê o mecanismo utilizado por muitos provedores de autenticaÃ§ÃŖo, como o Facebook, Google, GitHub, Microsoft, X (Twitter), etc. Eles utilizam isso para prover permissÃĩes específicas para os usuÃĄrios e aplicaçÃĩes. -Toda vez que vocÃĒ "se autentica com" Facebook, Google, GitHub, Microsoft, Twitter, aquela aplicaÃ§ÃŖo estÃĄ utilizando o OAuth2 com escopos. +Toda vez que vocÃĒ "se autentica com" Facebook, Google, GitHub, Microsoft, X (Twitter), aquela aplicaÃ§ÃŖo estÃĄ utilizando o OAuth2 com escopos. Nesta seÃ§ÃŖo, vocÃĒ verÃĄ como gerenciar a autenticaÃ§ÃŖo e autorizaÃ§ÃŖo com os mesmos escopos do OAuth2 em sua aplicaÃ§ÃŖo **FastAPI**. diff --git a/docs/pt/docs/async.md b/docs/pt/docs/async.md index 0d6bdbf0e..c70924ea5 100644 --- a/docs/pt/docs/async.md +++ b/docs/pt/docs/async.md @@ -40,7 +40,7 @@ def results(): --- -Se sua aplicaÃ§ÃŖo (de alguma forma) nÃŖo tem que se comunicar com nada mais e tem que esperar que o respondam, use `async def`. +Se sua aplicaÃ§ÃŖo (de alguma forma) nÃŖo tem que se comunicar com nada mais e esperar que o respondam, use `async def`. --- @@ -52,7 +52,7 @@ Se vocÃĒ simplesmente nÃŖo sabe, use apenas `def`. De qualquer forma, em ambos os casos acima, FastAPI irÃĄ trabalhar assincronamente e ser extremamente rÃĄpido. -Seguindo os passos acima, ele serÃĄ capaz de fazer algumas otimizaçÃĩes de performance. +Mas, seguindo os passos acima, ele serÃĄ capaz de fazer algumas otimizaçÃĩes de performance. ## Detalhes TÊcnicos @@ -66,36 +66,36 @@ Vamos ver aquela frase por partes na seÃ§ÃŖo abaixo: ## CÃŗdigo assíncrono -CÃŗdigo assíncrono apenas significa que a linguagem đŸ’Ŧ tem um jeito de dizer para o computador / programa 🤖 que em certo ponto, ele 🤖 terÃĄ que esperar por *algo* para finalizar em outro lugar. Vamos dizer que esse *algo* seja chamado "arquivo lento" 📝. +CÃŗdigo assíncrono apenas significa que a linguagem đŸ’Ŧ tem um jeito de dizer para o computador / programa 🤖 que em certo ponto do cÃŗdigo, ele 🤖 terÃĄ que esperar *algo* finalizar em outro lugar. Vamos dizer que esse *algo* seja chamado "arquivo lento" 📝. -EntÃŖo, durante esse tempo, o computador pode ir e fazer outro trabalho, enquanto o "arquivo lento" 📝 termine. +EntÃŖo, durante esse tempo, o computador pode ir e fazer outro trabalho, enquanto o "arquivo lento" 📝 termina. -EntÃŖo o computador / programa 🤖 irÃĄ voltar toda hora que tiver uma chance porquÃĒ ele ainda estÃĄ esperando o "arquivo lento", ou ele 🤖 nunca irÃĄ terminar todo o trabalho que tem atÊ esse ponto. E ele 🤖 irÃĄ ver se alguma das tarefas que estava esperando jÃĄ terminaram, fazendo o que quer que tinham que fazer. +EntÃŖo o computador / programa 🤖 irÃĄ voltar sempre que tiver uma chance, seja porque ele estÃĄ esperando novamente, ou quando ele 🤖 terminar todo o trabalho que tem atÊ esse ponto. E ele 🤖 irÃĄ ver se alguma das tarefas que estava esperando jÃĄ terminaram de fazer o que quer que tinham que fazer. -Depois, ele 🤖 pega a primeira tarefa para finalizar (vamos dizer, nosso "arquivo lento" 📝) e continua o que ele tem que fazer com isso. +Depois, ele 🤖 pega a primeira tarefa para finalizar (vamos dizer, nosso "arquivo lento" 📝) e continua o que tem que fazer com ela. -Esse "esperar por algo" normalmente se refere a operaçÃĩes I/O que sÃŖo relativamente "lentas" (comparadas a velocidade do processador e da memÃŗria RAM), como esperar por: +Esse "esperar por algo" normalmente se refere a operaçÃĩes I/O que sÃŖo relativamente "lentas" (comparadas à velocidade do processador e da memÃŗria RAM), como esperar por: * dados do cliente para serem enviados atravÊs da rede -* dados enviados pelo seu programa para serem recebidos pelo clente atravÊs da rede -* conteÃēdo de um arquivo no disco pra ser lido pelo sistema e entregar ao seu programa +* dados enviados pelo seu programa serem recebidos pelo clente atravÊs da rede +* conteÃēdo de um arquivo no disco ser lido pelo sistema e entregue ao seu programa * conteÃēdo que seu programa deu ao sistema para ser escrito no disco -* uma operaÃ§ÃŖo remota API -* uma operaÃ§ÃŖo no banco de dados para finalizar -* uma solicitaÃ§ÃŖo no banco de dados esperando o retorno do resultado +* uma operaÃ§ÃŖo em uma API remota +* uma operaÃ§ÃŖo no banco de dados finalizar +* uma solicitaÃ§ÃŖo no banco de dados retornar o resultado * etc. -Enquanto o tempo de execuÃ§ÃŖo Ê consumido mais pela espera das operaçÃĩes I/O, essas operaçÃĩes sÃŖo chamadas de operaçÃĩes "limitadas por I/O". +Quanto o tempo de execuÃ§ÃŖo Ê consumido majoritariamente pela espera de operaçÃĩes I/O, essas operaçÃĩes sÃŖo chamadas operaçÃĩes "limitadas por I/O". -Isso Ê chamado de "assíncrono" porquÃĒ o computador / programa nÃŖo tem que ser "sincronizado" com a tarefa lenta, esperando pelo exato momento que a tarefa finalize, enquanto nÃŖo faz nada, para ser capaz de pegar o resultado da tarefa e dar continuidade ao trabalho. +Isso Ê chamado de "assíncrono" porque o computador / programa nÃŖo tem que ser "sincronizado" com a tarefa lenta, esperando pelo momento exato em que a tarefa finaliza, enquanto nÃŖo faz nada, para ser capaz de pegar o resultado da tarefa e dar continuidade ao trabalho. -Ao invÊs disso, sendo um sistema "assíncrono", uma vez finalizada, a tarefa pode esperar um pouco (alguns microssegundos) para que o computador / programa finalize o que quer que esteja fazendo,e entÃŖo volte para pegar o resultado e continue trabalhando com ele. +Ao invÊs disso, sendo um sistema "assíncrono", uma vez finalizada, a tarefa pode esperar na fila um pouco (alguns microssegundos) para que o computador / programa finalize o que quer que esteja fazendo, e entÃŖo volte para pegar o resultado e continue trabalhando com ele. -Para "síncrono" (contrÃĄrio de "assíncrono") tambÊm Ê utilizado o termo "sequencial", porquÃĒ o computador / programa segue todos os passos, na sequÃĒncia, antes de trocar para uma tarefa diferente, mesmo se alguns passos envolvam esperar. +Para "síncrono" (contrÃĄrio de "assíncrono") tambÊm Ê utilizado o termo "sequencial", porquÃĒ o computador / programa segue todos os passos, em sequÃĒncia, antes de trocar para uma tarefa diferente, mesmo se alguns passos envolvam esperar. ### ConcorrÃĒncia e hambÃērgueres -Essa idÊia de cÃŗdigo **assíncrono** descrito acima Ê algo às vezes chamado de **"concorrÃĒncia"**. E Ê diferente de **"paralelismo"**. +Essa idÊia de cÃŗdigo **assíncrono** descrita acima Ê às vezes chamado de **"concorrÃĒncia"**. Isso Ê diferente de **"paralelismo"**. **ConcorrÃĒncia** e **paralelismo** ambos sÃŖo relacionados a "diferentes coisas acontecendo mais ou menos ao mesmo tempo". @@ -105,117 +105,115 @@ Para ver essa diferença, imagine a seguinte histÃŗria sobre hambÃērgueres: ### HambÃērgueres concorrentes -VocÃĒ vai com seu _crush_ :heart_eyes: na lanchonete, fica na fila enquanto o caixa pega os pedidos das pessoas na sua frente. +VocÃĒ vai com seu _crush_ na lanchonete, e fica na fila enquanto o caixa pega os pedidos das pessoas na sua frente. 😍 -EntÃŖo chega a sua vez, vocÃĒ pede dois saborosos hambÃērgueres para vocÃĒ e seu _crush_ :heart_eyes:. +EntÃŖo chega a sua vez, vocÃĒ pede dois saborosos hambÃērgueres para vocÃĒ e seu _crush_. 🍔🍔 -VocÃĒ paga. +O caixa diz alguma coisa para o cozinheiro na cozinha para que eles saivam que tÃĒm que preparar seus hambÃērgueres (mesmo que ele esteja atualmente preparando os lanches dos outros clientes). -O caixa diz alguma coisa para o cara na cozinha para que ele tenha que preparar seus hambÃērgueres (mesmo embora ele esteja preparando os lanches dos outros clientes). +VocÃĒ paga. 💸 O caixa te entrega seu nÃēmero de chamada. -Enquanto vocÃĒ espera, vocÃĒ vai com seu _crush_ :heart_eyes: e pega uma mesa, senta e conversa com seu _crush_ :heart_eyes: por um bom tempo (como seus hambÃērgueres sÃŖo muito saborosos, leva um tempo para serem preparados). +Enquanto vocÃĒ espera, vocÃĒ vai com seu _crush_ e pega uma mesa, senta e conversa com seu _crush_ por um bom tempo (jÃĄ que seus hambÃērgueres sÃŖo muito saborosos, e leva um tempo para serem preparados). -Enquanto vocÃĒ estÃĄ sentado na mesa com seu _crush_ :heart_eyes:, esperando os hambÃērgueres, vocÃĒ pode gastar o tempo admirando como lindo, maravilhoso e esperto Ê seu _crush_ :heart_eyes:. +JÃĄ que vocÃĒ estÃĄ sentado na mesa com seu _crush_, esperando os hambÃērgueres, vocÃĒ pode passar esse tempo admirando o quÃŖo lindo, maravilhoso e esperto Ê seu _crush_ ✨😍✨. -Enquanto espera e conversa com seu _crush_ :heart_eyes:, de tempos em tempos, vocÃĒ verifica o nÃēmero de chamada exibido no balcÃŖo para ver se jÃĄ Ê sua vez. +Enquanto espera e conversa com seu _crush_, de tempos em tempos, vocÃĒ verifica o nÃēmero da chamada exibido no balcÃŖo para ver se jÃĄ Ê sua vez. -EntÃŖo a certo ponto, Ê finalmente sua vez. VocÃĒ vai no balcÃŖo, pega seus hambÃērgueres e volta para a mesa. +EntÃŖo em algum momento, Ê finalmente sua vez. VocÃĒ vai ao balcÃŖo, pega seus hambÃērgueres e volta para a mesa. -VocÃĒ e seu _crush_ :heart_eyes: comem os hambÃērgueres e aproveitam o tempo. +VocÃĒ e seu _crush_ comem os hambÃērgueres e aproveitam o tempo. ✨ --- -Imagine que vocÃĒ seja o computador / programa nessa histÃŗria. +Imagine que vocÃĒ seja o computador / programa nessa histÃŗria. -Enquanto vocÃĒ estÃĄ na fila, tranquilo, esperando por sua vez, nÃŖo estÃĄ fazendo nada "produtivo". Mas a fila Ê rÃĄpida porquÃĒ o caixa sÃŗ estÃĄ pegando os pedidos, entÃŖo estÃĄ tudo bem. +Enquanto vocÃĒ estÃĄ na fila, vocÃĒ estÃĄ somente ocioso 😴, esperando por sua vez, sem fazer nada muito "produtivo". Mas a fila Ê rÃĄpida porque o caixa sÃŗ estÃĄ pegando os pedidos (nÃŖo os preparando), entÃŖo estÃĄ tudo bem. -EntÃŖo, quando Ê sua vez, vocÃĒ faz o trabalho "produtivo" de verdade, vocÃĒ processa o menu, decide o que quer, pega a escolha de seu _crush_ :heart_eyes:, paga, verifica se entregou o valor correto em dinheiro ou cartÃŖo de crÊdito, verifica se foi cobrado corretamente, verifica se seu pedido estÃĄ correto etc. +EntÃŖo, quando Ê sua vez, vocÃĒ faz trabalho realmente "produtivo", vocÃĒ processa o menu, decide o que quer, pega a escolha de seu _crush_, paga, verifica se entregou o cartÃŖo ou a cÊdula correta, verifica se foi cobrado corretamente, verifica se seu pedido estÃĄ correto etc. -Mas entÃŖo, embora vocÃĒ ainda nÃŖo tenha os hambÃērgueres, seu trabalho no caixa estÃĄ "pausado", porquÃĒ vocÃĒ tem que esperar seus hambÃērgueres estarem prontos. +Mas entÃŖo, embora vocÃĒ ainda nÃŖo tenha os hambÃērgueres, seu trabalho no caixa estÃĄ "pausado" ⏸, porque vocÃĒ tem que esperar 🕙 seus hambÃērgueres ficarem prontos. -Mas enquanto vocÃĒ se afasta do balcÃŖo e senta na mesa com o nÃēmero da sua chamada, vocÃĒ pode trocar sua atenÃ§ÃŖo para seu _crush_ :heart_eyes:, e "trabalhar" nisso. EntÃŖo vocÃĒ estÃĄ novamente fazendo algo muito "produtivo", como flertar com seu _crush_ :heart_eyes:. +Contudo, à medida que vocÃĒ se afasta do balcÃŖo e senta na mesa, com um nÃēmero para sua chamada, vocÃĒ pode trocar 🔀 sua atenÃ§ÃŖo para seu _crush_, e "trabalhar" ⏯ 🤓 nisso. EntÃŖo vocÃĒ estÃĄ novamente fazendo algo muito "produtivo", como flertar com seu _crush_ 😍. -EntÃŖo o caixa diz que "seus hambÃērgueres estÃŖo prontos" colocando seu nÃēmero no balcÃŖo, mas vocÃĒ nÃŖo corre que nem um maluco imediatamente quando o nÃēmero exibido Ê o seu. VocÃĒ sabe que ninguÊm irÃĄ roubar seus hambÃērgueres porquÃĒ vocÃĒ tem o nÃēmero de chamada, e os outros tem os nÃēmeros deles. +EntÃŖo o caixa 💁 diz que "seus hambÃērgueres estÃŖo prontos" colocando seu nÃēmero no balcÃŖo, mas vocÃĒ nÃŖo corre que nem um maluco imediatamente quando o nÃēmero exibido Ê o seu. VocÃĒ sabe que ninguÊm irÃĄ roubar seus hambÃērgueres porque vocÃĒ tem o seu nÃēmero da chamada, e os outros tÃĒm os deles. -EntÃŖo vocÃĒ espera que seu _crush_ :heart_eyes: termine a histÃŗria que estava contando (terminar o trabalho atual / tarefa sendo processada), sorri gentilmente e diz que vocÃĒ estÃĄ indo buscar os hambÃērgueres. +EntÃŖo vocÃĒ espera seu _crush_ terminar a histÃŗria que estava contando (terminar o trabalho atual ⏯ / tarefa sendo processada 🤓), sorri gentilmente e diz que vocÃĒ estÃĄ indo buscar os hambÃērgueres. -EntÃŖo vocÃĒ vai no balcÃŖo, para a tarefa inicial que agora estÃĄ finalizada, pega os hambÃērgueres, e leva para a mesa. Isso finaliza esse passo / tarefa da interaÃ§ÃŖo com o balcÃŖo. Agora Ê criada uma nova tarefa, "comer hambÃērgueres", mas a tarefa anterior, "pegar os hambÃērgueres" jÃĄ estÃĄ finalizada. +EntÃŖo vocÃĒ vai ao balcÃŖo 🔀, para a tarefa inicial que agora estÃĄ finalizada⏯, pega os hambÃērgueres, agradece, e leva-os para a mesa. Isso finaliza esse passo / tarefa da interaÃ§ÃŖo com o balcÃŖo ⏚. Isso, por sua vez, cria uma nova tarefa, a de "comer hambÃērgueres" 🔀 ⏯, mas a tarefa anterior de "pegar os hambÃērgueres" jÃĄ estÃĄ finalizada ⏚. ### HambÃērgueres paralelos -VocÃĒ vai com seu _crush_ :heart_eyes: em uma lanchonete paralela. +Agora vamos imaginar que esses nÃŖo sÃŖo "HambÃērgueres Concorrentes", e sim "HambÃērgueres Paralelos" -VocÃĒ fica na fila enquanto alguns (vamos dizer 8) caixas pegam os pedidos das pessoas na sua frente. +VocÃĒ vai com seu _crush_ na lanchonete paralela. -Todo mundo antes de vocÃĒ estÃĄ esperando pelos hambÃērgueres estarem prontos antes de deixar o caixa porquÃĒ cada um dos 8 caixas vai e prepara o hambÃērguer antes de pegar o prÃŗximo pedido. +VocÃĒ fica na fila enquanto vÃĄrios (vamos dizer 8) caixas que tambÊm sÃŖo cozinheiros pegam os pedidos das pessoas na sua frente. -EntÃŖo Ê finalmente sua vez, e pede 2 hambÃērgueres muito saborosos para vocÃĒ e seu _crush_ :heart_eyes:. +Todo mundo na sua frente estÃĄ esperando seus hambÃērgueres ficarem prontos antes de deixar o caixa porque cada um dos 8 caixas vai e prepara o hambÃērguer logo apÃŗs receber o pedido, antes de pegar o prÃŗximo pedido. -VocÃĒ paga. +EntÃŖo Ê finalmente sua vez, vocÃĒ pede 2 hambÃērgueres muito saborosos para vocÃĒ e seu _crush_. + +VocÃĒ paga 💸. O caixa vai para a cozinha. -VocÃĒ espera, na frente do balcÃŖo, para que ninguÊm pegue seus hambÃērgueres antes de vocÃĒ, jÃĄ que nÃŖo tem nÃēmeros de chamadas. +VocÃĒ espera, na frente do balcÃŖo 🕙, para que ninguÊm pegue seus hambÃērgueres antes de vocÃĒ, jÃĄ que nÃŖo tem nÃēmeros de chamadas. -Enquanto vocÃĒ e seu _crush_ :heart_eyes: estÃŖo ocupados nÃŖo permitindo que ninguÊm passe a frente e pegue seus hambÃērgueres assim que estiverem prontos, vocÃĒ nÃŖo pode dar atenÃ§ÃŖo ao seu _crush_ :heart_eyes:. +Como vocÃĒ e seu _crush_ estÃŖo ocupados nÃŖo permitindo que ninguÊm passe na frente e pegue seus hambÃērgueres assim que estiverem prontos, vocÃĒ nÃŖo pode dar atenÃ§ÃŖo ao seu _crush_. 😞 -Isso Ê trabalho "síncrono", vocÃĒ estÃĄ "sincronizado" com o caixa / cozinheiro. VocÃĒ tem que esperar e estar lÃĄ no exato momento que o caixa / cozinheiro terminar os hambÃērgueres e dÃĄ-los a vocÃĒ, ou entÃŖo, outro alguÊm pode pegÃĄ-los. +Isso Ê trabalho "síncrono", vocÃĒ estÃĄ "sincronizado" com o caixa / cozinheirođŸ‘¨â€đŸŗ. VocÃĒ tem que esperar 🕙 e estar lÃĄ no exato momento que o caixa / cozinheiro đŸ‘¨â€đŸŗ terminar os hambÃērgueres e os der a vocÃĒ, ou entÃŖo, outro alguÊm pode pegÃĄ-los. -EntÃŖo seu caixa / cozinheiro finalmente volta com seus hambÃērgueres, depois de um longo tempo esperando por eles em frente ao balcÃŖo. +EntÃŖo seu caixa / cozinheiro đŸ‘¨â€đŸŗ finalmente volta com seus hambÃērgueres, depois de um longo tempo esperando 🕙 por eles em frente ao balcÃŖo. -VocÃĒ pega seus hambÃērgueres e vai para a mesa com seu _crush_ :heart_eyes:. +VocÃĒ pega seus hambÃērgueres e vai para a mesa com seu _crush_. -VocÃĒs comem os hambÃērgueres, e o trabalho estÃĄ terminado. +VocÃĒs comem os hambÃērgueres, e o trabalho estÃĄ terminado. ⏚ -NÃŖo houve muita conversa ou flerte jÃĄ que a maior parte do tempo foi gasto esperando os lanches na frente do balcÃŖo. +NÃŖo houve muita conversa ou flerte jÃĄ que a maior parte do tempo foi gasto esperando 🕙 na frente do balcÃŖo. 😞 --- -Nesse cenÃĄrio dos hambÃērgueres paralelos, vocÃĒ ÃŠ um computador / programa com dois processadores (vocÃĒ e seu _crush_ :heart_eyes:), ambos esperando e dedicando a atenÃ§ÃŖo de estar "esperando no balcÃŖo" por um bom tempo. +Nesse cenÃĄrio dos hambÃērgueres paralelos, vocÃĒ ÃŠ um computador / programa com dois processadores (vocÃĒ e seu _crush_), ambos esperando 🕙 e dedicando sua atenÃ§ÃŖo ⏯ "esperando no balcÃŖo" 🕙 por um bom tempo. -A lanchonete paralela tem 8 processadores (caixas / cozinheiros). Enquanto a lanchonete dos hambÃērgueres concorrentes tinham apenas 2 (um caixa e um cozinheiro). +A lanchonete paralela tem 8 processadores (caixas / cozinheiros), enquanto a lanchonete dos hambÃērgueres concorrentes tinha apenas 2 (um caixa e um cozinheiro). -Ainda assim, a Ãēltima experiÃĒncia nÃŖo foi a melhor. +Ainda assim, a experiÃĒncia final nÃŖo foi a melhor. 😞 --- -Essa poderia ser a histÃŗria paralela equivalente aos hambÃērgueres. +Essa seria o equivalente paralelo à histÃŗrio dos hambÃērgueres. 🍔 Para um exemplo "mais real", imagine um banco. -AtÊ recentemente, a maioria dos bancos tinha muitos caixas e uma grande fila. +AtÊ recentemente, a maioria dos bancos tinham muitos caixas 👨‍đŸ’ŧ👨‍đŸ’ŧ👨‍đŸ’ŧ👨‍đŸ’ŧ e uma grande fila 🕙🕙🕙🕙🕙🕙🕙🕙. -Todos os caixas fazendo todo o trabalho, um cliente apÃŗs o outro. +Todos os caixas fazendo todo o trabalho, um cliente apÃŗs o outro 👨‍đŸ’ŧ⏯. -E vocÃĒ tinha que esperar na fila por um longo tempo ou poderia perder a vez. +E vocÃĒ tinha que esperar 🕙 na fila por um longo tempo ou poderia perder a vez. -VocÃĒ provavelmente nÃŖo gostaria de levar seu _crush_ :heart_eyes: com vocÃĒ para um rolezinho no banco. +VocÃĒ provavelmente nÃŖo gostaria de levar seu _crush_ 😍 com vocÃĒ para um rolezinho no banco đŸĻ. ### ConclusÃŖo dos hambÃērgueres -Nesse cenÃĄrio dos "hambÃērgueres com seu _crush_ :heart_eyes:", como tem muita espera, faz mais sentido ter um sistema concorrente. +Nesse cenÃĄrio dos "hambÃērgueres com seu _crush_", como tem muita espera, faz mais sentido ter um sistema concorrente â¸đŸ”€â¯. Esse Ê o caso da maioria das aplicaçÃĩes web. -Geralmente sÃŖo muitos usuÃĄrios, e seu servidor estÃĄ esperando pelas suas conexÃĩes nÃŖo tÃŖo boas para enviar as requisiçÃĩes. +Muitos, muitos usuÃĄrios, mas seu servidor estÃĄ esperando 🕙 pela sua conexÃŖo nÃŖo tÃŖo boa enviar suas requisiçÃĩes. -E entÃŖo esperando novamente pelas respostas voltarem. +E entÃŖo esperando 🕙 novamente as respostas voltarem. -Essa "espera" Ê medida em microssegundos, e ainda assim, somando tudo, Ê um monte de espera no final. +Essa "espera" 🕙 Ê medida em microssegundos, mas ainda assim, somando tudo, Ê um monte de espera no final. -Por isso que faz muito mais sentido utilizar cÃŗdigo assíncrono para APIs web. +Por isso que faz bastante sentido utilizar cÃŗdigo assíncrono â¸đŸ”€â¯ para APIs web. -A maioria dos frameworks Python existentes mais populares (incluindo Flask e Django) foram criados antes que os novos recursos assíncronos existissem em Python. EntÃŖo, os meios que eles podem ser colocados em produÃ§ÃŖo para suportar execuÃ§ÃŖo paralela mais a forma antiga de execuÃ§ÃŖo assíncrona nÃŖo sÃŖo tÃŖo poderosos quanto as novas capacidades. - -Mesmo embora a especificaÃ§ÃŖo principal para web assíncrono em Python (ASGI) foi desenvolvida no Django, para adicionar suporte para WebSockets. - -Esse tipo de assincronicidade Ê o que fez NodeJS popular (embora NodeJS nÃŖo seja paralelo) e que essa seja a força do Go como uma linguagem de programa. +Esse tipo de assincronicidade Ê o que fez NodeJS popular (embora NodeJS nÃŖo seja paralelo) e essa Ê a força do Go como uma linguagem de programaÃ§ÃŖo. E esse Ê o mesmo nível de performance que vocÃĒ tem com o **FastAPI**. -E como vocÃĒ pode ter paralelismo e sincronicidade ao mesmo tempo, vocÃĒ tem uma maior performance do que a maioria dos frameworks NodeJS testados e lado a lado com Go, que Ê uma linguagem compilada prÃŗxima ao C (tudo graças ao Starlette). +E como vocÃĒ pode ter paralelismo e assincronicidade ao mesmo tempo, vocÃĒ tem uma maior performance do que a maioria dos frameworks NodeJS testados e lado a lado com Go, que Ê uma linguagem compilada, mais prÃŗxima ao C (tudo graças ao Starlette). ### ConcorrÃĒncia Ê melhor que paralelismo? @@ -225,64 +223,64 @@ ConcorrÃĒncia Ê diferente de paralelismo. E Ê melhor em cenÃĄrios **específic EntÃŖo, para equilibrar tudo, imagine a seguinte historinha: -> VocÃĒ tem que limpar uma grande casa suja. +> VocÃĒ tem que limpar uma casa grande e suja. *Sim, essa Ê toda a histÃŗria*. --- -NÃŖo hÃĄ espera em lugar algum, apenas um monte de trabalho para ser feito, em mÃēltiplos cômodos da casa. +NÃŖo hÃĄ espera 🕙 em lugar algum, apenas um monte de trabalho para ser feito, em mÃēltiplos cômodos da casa. -VocÃĒ poderia ter chamadas como no exemplo dos hambÃērgueres, primeiro a sala de estar, entÃŖo a cozinha, mas vocÃĒ nÃŖo estÃĄ esperando por nada, apenas limpar e limpar, as chamadas nÃŖo afetariam em nada. +VocÃĒ poderia ter turnos como no exemplo dos hambÃērgueres, primeiro a sala de estar, entÃŖo a cozinha, mas como vocÃĒ nÃŖo estÃĄ esperando por nada, apenas limpando e limpando, as chamadas nÃŖo afetariam em nada. -Levaria o mesmo tempo para finalizar com ou sem chamadas (concorrÃĒncia) e vocÃĒ teria feito o mesmo tanto de trabalho. +Levaria o mesmo tempo para finalizar com ou sem turnos (concorrÃĒncia) e vocÃĒ teria feito o mesmo tanto de trabalho. Mas nesse caso, se vocÃĒ trouxesse os 8 ex-caixas / cozinheiros / agora-faxineiros, e cada um deles (mais vocÃĒ) pudessem dividir a casa para limpÃĄ-la, vocÃĒs fariam toda a limpeza em **paralelo**, com a ajuda extra, e terminariam muito mais cedo. Nesse cenÃĄrio, cada um dos faxineiros (incluindo vocÃĒ) poderia ser um processador, fazendo a sua parte do trabalho. -E a maior parte do tempo de execuÃ§ÃŖo Ê tomada por trabalho (ao invÊs de ficar esperando), e o trabalho em um computador Ê feito pela CPU, que podem gerar problemas que sÃŖo chamados de "limite de CPU". +E a maior parte do tempo de execuÃ§ÃŖo Ê tomada por trabalho real (ao invÊs de ficar esperando), e o trabalho em um computador Ê feito pela CPU. Eles chamam esses problemas de "limitados por CPU". --- -Exemplos comuns de limite de CPU sÃŖo coisas que exigem processamento matemÃĄtico complexo. +Exemplos comuns de operaçÃĩes limitadas por CPU sÃŖo coisas que exigem processamento matemÃĄtico complexo. Por exemplo: * **Processamento de ÃĄudio** ou **imagem** -* **VisÃŖo do Computador**: uma imagem Ê composta por milhÃĩes de pixels, cada pixel tem 3 valores (cores, processamento que normalmente exige alguma computaÃ§ÃŖo em todos esses pixels ao mesmo tempo) +* **VisÃŖo Computacional**: uma imagem Ê composta por milhÃĩes de pixels, cada pixel tem 3 valores / cores, processar isso normalmente exige alguma computaÃ§ÃŖo em todos esses pixels ao mesmo tempo -* **Machine Learning**: Normalmente exige muita multiplicaÃ§ÃŖo de matrizes e vetores. Pense numa grande folha de papel com nÃēmeros e multiplicando todos eles juntos e ao mesmo tempo. +* **Machine Learning**: Normalmente exige muita multiplicaÃ§ÃŖo de matrizes e vetores. Pense numa grande planilha com nÃēmeros e em multiplicar todos eles juntos e ao mesmo tempo. -* **Deep Learning**: Esse Ê um subcampo do Machine Learning, entÃŖo o mesmo se aplica. A diferença Ê que nÃŖo hÃĄ apenas uma grande folha de papel com nÃēmeros para multiplicar, mas um grande conjunto de folhas de papel, e em muitos casos, vocÃĒ utiliza um processador especial para construir e/ou usar modelos. +* **Deep Learning**: Esse Ê um subcampo do Machine Learning, entÃŖo, o mesmo se aplica. A diferença Ê que nÃŖo hÃĄ apenas uma grande planilha com nÃēmeros para multiplicar, mas um grande conjunto delas, e em muitos casos, vocÃĒ utiliza um processador especial para construir e/ou usar esses modelos. ### ConcorrÃĒncia + Paralelismo: Web + Machine learning Com **FastAPI** vocÃĒ pode levar a vantagem da concorrÃĒncia que Ê muito comum para desenvolvimento web (o mesmo atrativo de NodeJS). -Mas vocÃĒ tambÊm pode explorar os benefícios do paralelismo e multiprocessamento (tendo mÃēltiplos processadores rodando em paralelo) para trabalhos pesados que geram **limite de CPU** como aqueles em sistemas de Machine Learning. +Mas vocÃĒ tambÊm pode explorar os benefícios do paralelismo e multiprocessamento (tendo mÃēltiplos processadores rodando em paralelo) para trabalhos **limitados por CPU** como aqueles em sistemas de Machine Learning. -Isso, mais o simples fato que Python Ê a principal linguagem para **Data Science**, Machine Learning e especialmente Deep Learning, faz do FastAPI uma Ãŗtima escolha para APIs web e aplicaçÃĩes com Data Science / Machine Learning (entre muitas outras). +Isso, somado ao simples fato que Python Ê a principal linguagem para **Data Science**, Machine Learning e especialmente Deep Learning, faz do FastAPI uma Ãŗtima escolha para APIs web e aplicaçÃĩes com Data Science / Machine Learning (entre muitas outras). Para ver como alcançar esse paralelismo em produÃ§ÃŖo veja a seÃ§ÃŖo sobre [Deployment](deployment/index.md){.internal-link target=_blank}. ## `async` e `await` -VersÃĩes modernas do Python tem um modo muito intuitivo para definir cÃŗdigo assíncrono. Isso faz parecer normal o cÃŗdigo "sequencial" e fazer o "esperar" para vocÃĒ nos momentos certos. +VersÃĩes modernas do Python tÃĒm um modo muito intuitivo para definir cÃŗdigo assíncrono. Isso faz parecer do mesmo jeito do cÃŗdigo normal "sequencial" e fazer a "espera" para vocÃĒ nos momentos certos. -Quando tem uma operaÃ§ÃŖo que exigirÃĄ espera antes de dar os resultados e tem suporte para esses recursos Python, vocÃĒ pode escrever assim: +Quando tem uma operaÃ§ÃŖo que exigirÃĄ espera antes de dar os resultados e tem suporte para esses novos recursos do Python, vocÃĒ pode escrever assim: ```Python burgers = await get_burgers(2) ``` -A chave aqui Ê o `await`. Ele diz ao Python que ele tem que esperar por `get_burgers(2)` para finalizar suas coisas antes de armazenar os resultados em `burgers`. Com isso, o Python saberÃĄ que ele pode ir e fazer outras coisas nesse meio tempo (como receber outra requisiÃ§ÃŖo). +A chave aqui Ê o `await`. Ele diz ao Python que ele tem que esperar por `get_burgers(2)` finalizar suas coisas 🕙 antes de armazenar os resultados em `burgers`. Com isso, o Python saberÃĄ que ele pode ir e fazer outras coisas 🔀 ⏯ nesse meio tempo (como receber outra requisiÃ§ÃŖo). Para o `await` funcionar, tem que estar dentro de uma funÃ§ÃŖo que suporte essa assincronicidade. Para fazer isso, apenas declare a funÃ§ÃŖo com `async def`: ```Python hl_lines="1" async def get_burgers(number: int): - # Fazer alguma coisa assíncrona para criar os hambÃērgueres + # Faz alguma coisa assíncrona para criar os hambÃērgueres return burgers ``` @@ -295,9 +293,9 @@ def get_sequential_burgers(number: int): return burgers ``` -Com `async def`, o Python sabe que, dentro dessa funÃ§ÃŖo, tem que estar ciente das expressÃĩes `await`, e que isso pode "pausar" a execuÃ§ÃŖo dessa funÃ§ÃŖo, e poderÃĄ fazer outra coisa antes de voltar. +Com `async def`, o Python sabe que, dentro dessa funÃ§ÃŖo, ele deve estar ciente das expressÃĩes `await`, e que isso poderÃĄ "pausar" ⏸ a execuÃ§ÃŖo dessa funÃ§ÃŖo, e ir fazer outra coisa 🔀 antes de voltar. -Quando vocÃĒ quiser chamar uma funÃ§ÃŖo `async def`, vocÃĒ tem que "esperar". EntÃŖo, isso nÃŖo funcionarÃĄ: +Quando vocÃĒ quiser chamar uma funÃ§ÃŖo `async def`, vocÃĒ tem que "esperar" ela. EntÃŖo, isso nÃŖo funcionarÃĄ: ```Python # Isso nÃŖo irÃĄ funcionar, porquÃĒ get_burgers foi definido com: async def @@ -319,13 +317,24 @@ async def read_burgers(): VocÃĒ deve ter observado que `await` pode ser usado somente dentro de funçÃĩes definidas com `async def`. -Mas ao mesmo tempo, funçÃĩes definidas com `async def` tem que ser aguardadas. EntÃŖo, funçÃĩes com `async def` pdem ser chamadas somente dentro de funçÃĩes definidas com `async def` tambÊm. +Mas ao mesmo tempo, funçÃĩes definidas com `async def` tÃĒm que ser "aguardadas". EntÃŖo, funçÃĩes com `async def` pdem ser chamadas somente dentro de funçÃĩes definidas com `async def` tambÊm. EntÃŖo, sobre o ovo e a galinha, como vocÃĒ chama a primeira funÃ§ÃŖo async? Se vocÃĒ estivar trabalhando com **FastAPI** nÃŖo terÃĄ que se preocupar com isso, porquÃĒ essa "primeira" funÃ§ÃŖo serÃĄ a sua *funÃ§ÃŖo de operaÃ§ÃŖo de rota*, e o FastAPI saberÃĄ como fazer a coisa certa. -Mas se vocÃĒ quiser usar `async` / `await` sem FastAPI, verifique a documentaÃ§ÃŖo oficial Python. +Mas se vocÃĒ quiser usar `async` / `await` sem FastAPI, vocÃĒ tambÊm pode fazÃĒ-lo. + +### Escreva seu prÃŗprio cÃŗdigo assíncrono + +Starlette (e **FastAPI**) sÃŖo baseados no AnyIO, o que o torna compatível com ambos o asyncio da biblioteca padrÃŖo do Python, e o Trio. + +Em particular, vocÃĒ pode usar diretamente o AnyIO para seus casos de uso avançados de concorrÃĒncia que requerem padrÃĩes mais avançados no seu prÃŗprio cÃŗdigo. + +E atÊ se vocÃĒ nÃŖo estiver utilizando FastAPI, vocÃĒ tambÊm pode escrever suas prÃŗprias aplicaçÃĩes assíncronas com o AnyIO por ser altamente compatível e ganhar seus benefícios (e.g. *concorrÃĒncia estruturada*). + +Eu criei outra biblioteca em cima do AnyIO, como uma fina camada acima, para melhorar um pouco as anotaçÃĩes de tipo e obter melhor **autocompletar**, **erros de linha**, etc. Ela tambÊm possui uma introduÃ§ÃŖo amigÃĄvel e um tutorial para ajudar vocÃĒ a **entender** e escrever **seu prÃŗprio cÃŗdigo async**: Asyncer. Seria particularmente Ãētil se vocÃĒ precisar **combinar cÃŗdigo async com cÃŗdigo regular** (bloqueador/síncrono). + ### Outras formas de cÃŗdigo assíncrono @@ -337,25 +346,25 @@ Essa mesma sintaxe (ou quase a mesma) foi tambÊm incluída recentemente em vers Mas antes disso, controlar cÃŗdigo assíncrono era bem mais complexo e difícil. -Nas versÃĩes anteriores do Python, vocÃĒ poderia utilizar threads ou Gevent. Mas o cÃŗdigo Ê um pouco mais complexo de entender, debugar, e pensar sobre. +Nas versÃĩes anteriores do Python, vocÃĒ poderia utilizar threads ou Gevent. Mas o cÃŗdigo Ê bem mais complexo de entender, debugar, e pensar sobre. -Nas versÃĩes anteriores do NodeJS / Navegador JavaScript, vocÃĒ poderia utilizar "callbacks". O que leva ao inferno do callback. +Nas versÃĩes anteriores do NodeJS / Navegador JavaScript, vocÃĒ utilizaria "callbacks". O que leva ao "inferno do callback". ## Corrotinas -**Corrotina** Ê apenas um jeito bonitinho para a coisa que Ê retornada de uma funÃ§ÃŖo `async def`. O Python sabe que Ê uma funÃ§ÃŖo que pode começar e terminar em algum ponto, mas que pode ser pausada internamente tambÊm, sempre que tiver um `await` dentro dela. +**Corrotina** Ê apenas um jeito bonitinho para a coisa que Ê retornada de uma funÃ§ÃŖo `async def`. O Python sabe que Ê algo como uma funÃ§ÃŖo, que pode começar e que vai terminar em algum ponto, mas que pode ser pausada ⏸ internamente tambÊm, sempre que tiver um `await` dentro dela. -Mas toda essa funcionalidade de cÃŗdigo assíncrono com `async` e `await` Ê muitas vezes resumida como "corrotina". É comparÃĄvel ao principal recurso chave do Go, a "Gorotina". +Mas toda essa funcionalidade de cÃŗdigo assíncrono com `async` e `await` Ê muitas vezes resumida como usando "corrotinas". É comparÃĄvel ao principal recurso chave do Go, a "Gorrotina". ## ConclusÃŖo -Vamos ver a mesma frase com o conteÃēdo cima: +Vamos ver a mesma frase de cima: -> VersÃĩes modernas do Python tem suporte para **"cÃŗdigo assíncrono"** usando algo chamado **"corrotinas"**, com sintaxe **`async` e `await`**. +> VersÃĩes modernas do Python tÃĒm suporte para **"cÃŗdigo assíncrono"** usando algo chamado **"corrotinas"**, com sintaxe **`async` e `await`**. -Isso pode fazer mais sentido agora. +Isso pode fazer mais sentido agora. ✨ -Tudo isso Ê o que deixa o FastAPI poderoso (atravÊs do Starlette) e que o faz ter uma performance impressionante. +Tudo isso Ê o que empodera o FastAPI (atravÊs do Starlette) e que o faz ter uma performance tÃŖo impressionante. ## Detalhes muito tÊcnicos @@ -365,25 +374,25 @@ VocÃĒ pode provavelmente pular isso. Esses sÃŖo detalhes muito tÊcnicos de como **FastAPI** funciona por baixo do capô. -Se vocÃĒ tem algum conhecimento tÊcnico (corrotinas, threads, blocking etc) e estÃĄ curioso sobre como o FastAPI controla o `async def` vs normal `def`, vÃĄ em frente. +Se vocÃĒ tem certo conhecimento tÊcnico (corrotinas, threads, blocking etc) e estÃĄ curioso sobre como o FastAPI controla o `async def` vs normal `def`, vÃĄ em frente. /// ### FunçÃĩes de operaÃ§ÃŖo de rota -Quando vocÃĒ declara uma *funÃ§ÃŖo de operaÃ§ÃŖo de rota* com `def` normal ao invÊs de `async def`, ela Ê rodada em uma threadpool externa que entÃŖo Ê aguardada, ao invÊs de ser chamada diretamente (ela poderia bloquear o servidor). +Quando vocÃĒ declara uma *funÃ§ÃŖo de operaÃ§ÃŖo de rota* com `def` normal ao invÊs de `async def`, ela Ê rodada em uma threadpool externa que Ê entÃŖo aguardada, ao invÊs de ser chamada diretamente (jÃĄ que ela bloquearia o servidor). -Se vocÃĒ estÃĄ chegando de outro framework assíncrono que nÃŖo faz o trabalho descrito acima e vocÃĒ estÃĄ acostumado a definir triviais *funçÃĩes de operaÃ§ÃŖo de rota* com simples `def` para ter um mínimo ganho de performance (cerca de 100 nanosegundos), por favor observe que no **FastAPI** o efeito pode ser bem o oposto. Nesses casos, Ê melhor usar `async def` a menos que suas *funçÃĩes de operaÃ§ÃŖo de rota* utilizem cÃŗdigo que performem bloqueamento IO. +Se vocÃĒ estÃĄ chegando de outro framework assíncrono que nÃŖo funciona como descrito acima e vocÃĒ estÃĄ acostumado a definir *funçÃĩes de operaÃ§ÃŖo de rota* triviais somente de computaÃ§ÃŖo com simples `def` para ter um mínimo ganho de performance (cerca de 100 nanosegundos), por favor observe que no **FastAPI** o efeito pode ser bem o oposto. Nesses casos, Ê melhor usar `async def` a menos que suas *funçÃĩes de operaÃ§ÃŖo de rota* utilizem cÃŗdigo que performe bloqueamento IO. -Ainda, em ambas as situaçÃĩes, as chances sÃŖo que o **FastAPI** serÃĄ [ainda mais rÃĄpido](index.md#performance){.internal-link target=_blank} do que (ou ao menos comparÃĄvel a) seus frameworks antecessores. +Ainda, em ambas as situaçÃĩes, as chances sÃŖo que o **FastAPI** [ainda serÃĄ mais rÃĄpido](index.md#performance){.internal-link target=_blank} do que (ou ao menos comparÃĄvel a) seu framework anterior. ### DependÃĒncias -O mesmo se aplica para as dependÃĒncias. Se uma dependÃĒncia tem as funçÃĩes com padrÃŖo `def` ao invÊs de `async def`, ela Ê rodada no threadpool externo. +O mesmo se aplica para as [dependÃĒncias](tutorial/dependencies/index.md){.internal-link target=_blank}. Se uma dependÃĒncia tem as funçÃĩes com padrÃŖo `def` ao invÊs de `async def`, ela Ê rodada no threadpool externo. ### Sub-dependÃĒncias -VocÃĒ pode ter mÃēltiplas dependÃĒncias e sub-dependÃĒncias exigindo uma a outra (como parÃĸmetros de definiçÃĩes de funçÃĩes), algumas delas podem ser criadas com `async def` e algumas com `def` normal. Isso ainda poderia funcionar, e aquelas criadas com `def` podem ser chamadas em uma thread externa ao invÊs de serem "aguardadas". +VocÃĒ pode ter mÃēltiplas dependÃĒncias e [sub-dependÃĒncias](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} requisitando uma à outra (como parÃĸmetros de definiçÃĩes de funçÃĩes), algumas delas podem ser criadas com `async def` e algumas com `def` normal. Isso ainda funcionaria, e aquelas criadas com `def` normal seriam chamadas em uma thread externa (do threadpool) ao invÊs de serem "aguardadas". ### Outras funçÃĩes de utilidade @@ -395,6 +404,6 @@ Se sua funÃ§ÃŖo de utilidade Ê uma funÃ§ÃŖo normal com `def`, ela serÃĄ chamada --- -Novamente, esses sÃŖo detalhes muito tÊcnicos que provavelmente possam ser Ãēteis caso vocÃĒ esteja procurando por eles. +Novamente, esses sÃŖo detalhes muito tÊcnicos que provavelmente seriam Ãēteis caso vocÃĒ esteja procurando por eles. Caso contrÃĄrio, vocÃĒ deve ficar bem com as dicas da seÃ§ÃŖo acima: Com pressa?. diff --git a/docs/pt/docs/deployment/cloud.md b/docs/pt/docs/deployment/cloud.md index e6522f50f..fc490db4d 100644 --- a/docs/pt/docs/deployment/cloud.md +++ b/docs/pt/docs/deployment/cloud.md @@ -10,8 +10,4 @@ Alguns provedores de nuvem ✨ [**patrocinam o FastAPI**](../help-fastapi.md#spo E isso mostra seu verdadeiro comprometimento com o FastAPI e sua **comunidade** (vocÃĒ), pois eles nÃŖo querem apenas fornecer a vocÃĒ um **bom serviço**, mas tambÊm querem ter certeza de que vocÃĒ tenha uma **estrutura boa e saudÃĄvel**, o FastAPI. 🙇 -Talvez vocÃĒ queira experimentar os serviços deles e seguir os guias: - -* Platform.sh -* Porter -* Coherence +Talvez vocÃĒ queira experimentar os serviços deles e seguir os guias. diff --git a/docs/pt/docs/help-fastapi.md b/docs/pt/docs/help-fastapi.md index 3d6e1f9d2..0de1ed648 100644 --- a/docs/pt/docs/help-fastapi.md +++ b/docs/pt/docs/help-fastapi.md @@ -20,9 +20,9 @@ VocÃĒ pode se inscrever (pouco frequente) [**FastAPI e amigos** newsletter](news * Mudanças de Ãēltima hora 🚨 * Truques e dicas ✅ -## Siga o FastAPI no twitter +## Siga o FastAPI no X (Twitter) -Siga @fastapi no **Twitter** para receber as Ãēltimas notícias sobre o **FastAPI**. đŸĻ +Siga @fastapi no **X (Twitter)** para receber as Ãēltimas notícias sobre o **FastAPI**. đŸĻ ## Favorite o **FastAPI** no GitHub @@ -47,19 +47,19 @@ VocÃĒ pode: * Me siga no **GitHub**. * Ver tambÊm outros projetos Open Source criados por mim que podem te ajudar. * Me seguir para saber quando um novo projeto Open Source for criado. -* Me siga no **Twitter**. +* Me siga no **X (Twitter)**. * Me dizer o motivo pelo o qual vocÃĒ estÃĄ usando o FastAPI(Adoro ouvir esse tipo de comentÃĄrio). * Saber quando eu soltar novos anÃēncios ou novas ferramentas. - * TambÊm Ê possivel seguir o @fastapi no Twitter (uma conta aparte). + * TambÊm Ê possivel seguir o @fastapi no X (Twitter) (uma conta aparte). * Conect-se comigo no **Linkedin**. - * Saber quando eu fizer novos anÃēncios ou novas ferramentas (apesar de que uso o twitter com mais frequÃĒncia 🤷‍♂). + * Saber quando eu fizer novos anÃēncios ou novas ferramentas (apesar de que uso o X (Twitter) com mais frequÃĒncia 🤷‍♂). * Ler meus artigos (ou me seguir) no **Dev.to** ou no **Medium**. * Ficar por dentro de novas ideias, artigos, e ferramentas criadas por mim. * Me siga para saber quando eu publicar algo novo. ## Tweete sobre **FastAPI** -Tweete sobre o **FastAPI** e compartilhe comigo e com os outros o porque de gostar do FastAPI. 🎉 +Tweete sobre o **FastAPI** e compartilhe comigo e com os outros o porque de gostar do FastAPI. 🎉 Adoro ouvir sobre como o **FastAPI** Ê usado, o que vocÃĒ gosta nele, em qual projeto/empresa estÃĄ sendo usado, etc. diff --git a/docs/pt/docs/index.md b/docs/pt/docs/index.md index 9f08d5224..ce9929bf4 100644 --- a/docs/pt/docs/index.md +++ b/docs/pt/docs/index.md @@ -87,7 +87,7 @@ Os recursos chave sÃŖo: "*Estou extremamente entusiasmado com o **FastAPI**. É tÃŖo divertido!*" -
Brian Okken - Python Bytes podcaster (ref)
+
Brian Okken - Python Bytes podcaster (ref)
--- @@ -101,7 +101,7 @@ Os recursos chave sÃŖo: "*NÃŗs trocamos nossas **APIs** por **FastAPI** [...] Acredito que vocÃĒs gostarÃŖo dele [...]*" -
Ines Montani - Matthew Honnibal - fundadores da Explosion AI - criadores da spaCy (ref) - (ref)
+
Ines Montani - Matthew Honnibal - fundadores da Explosion AI - criadores da spaCy (ref) - (ref)
--- diff --git a/docs/pt/docs/project-generation.md b/docs/pt/docs/project-generation.md index e5c935fd2..e337ad762 100644 --- a/docs/pt/docs/project-generation.md +++ b/docs/pt/docs/project-generation.md @@ -1,84 +1,28 @@ -# GeraÃ§ÃŖo de Projetos - Modelo +# Full Stack FastAPI Template -VocÃĒ pode usar um gerador de projetos para começar, por jÃĄ incluir configuraçÃĩes iniciais, segurança, banco de dados e os primeiros _endpoints_ API jÃĄ feitos para vocÃĒ. +_Templates_, embora tipicamente venham com alguma configuraÃ§ÃŖo específica, sÃŖo desenhados para serem flexíveis e customizÃĄveis. Isso permite que vocÃĒ os modifique e adapte para as especificaçÃĩes do seu projeto, fazendo-os um excelente ponto de partida. 🏁 -Um gerador de projetos sempre terÃĄ uma prÊ-configuraÃ§ÃŖo que vocÃĒ pode atualizar e adaptar para suas prÃŗprias necessidades, mas pode ser um bom ponto de partida para seu projeto. +VocÃĒ pode usar esse _template_ para começar, jÃĄ que ele inclui vÃĄrias configuraçÃĩes iniciais, segurança, banco de dados, e alguns _endpoints_ de API jÃĄ feitos para vocÃĒ. -## Full Stack FastAPI PostgreSQL +RepositÃŗrio GitHub: Full Stack FastAPI Template -GitHub: https://github.com/tiangolo/full-stack-fastapi-postgresql +## Full Stack FastAPI Template - Pilha de Tecnologias e Recursos -### Full Stack FastAPI PostgreSQL - Recursos - -* IntegraÃ§ÃŖo completa **Docker**. -* Modo de implantaÃ§ÃŖo Docker Swarm. -* IntegraÃ§ÃŖo e otimizaÃ§ÃŖo **Docker Compose** para desenvolvimento local. -* **Pronto para ProduÃ§ÃŖo** com servidor _web_ usando Uvicorn e Gunicorn. -* _Backend_ **FastAPI** Python: - * **RÃĄpido**: Alta performance, no nível de **NodeJS** e **Go** (graças ao Starlette e Pydantic). - * **Intuitivo**: Ótimo suporte de editor. _Auto-Complete_ em todo lugar. Menos tempo _debugando_. - * **FÃĄcil**: Projetado para ser fÃĄcil de usar e aprender. Menos tempo lendo documentaçÃĩes. - * **Curto**: Minimize duplicaÃ§ÃŖo de cÃŗdigo. MÃēltiplos recursos para cada declaraÃ§ÃŖo de parÃĸmetro. - * **Robusto**: Tenha cÃŗdigo pronto para produÃ§ÃŖo. Com documentaÃ§ÃŖo interativa automÃĄtica. - * **Baseado em PadrÃĩes**: Baseado em (e completamente compatível com) padrÃĩes abertos para APIs: OpenAPI e JSON Schema. - * **Muitos outros recursos** incluindo validaÃ§ÃŖo automÃĄtica, serializaÃ§ÃŖo, documentaÃ§ÃŖo interativa, autenticaÃ§ÃŖo com _tokens_ OAuth2 JWT etc. -* **Senha segura** _hashing_ por padrÃŖo. -* AutenticaÃ§ÃŖo **Token JWT**. -* Modelos **SQLAlchemy** (independente de extensÃĩes Flask, para que eles possam ser usados com _workers_ Celery diretamente). -* Modelos bÃĄsicos para usuÃĄrios (modifique e remova conforme suas necessidades). -* MigraçÃĩes **Alembic**. -* **CORS** (_Cross Origin Resource Sharing_ - Compartilhamento de Recursos Entre Origens). -* _Worker_ **Celery** que pode importar e usar modelos e cÃŗdigos do resto do _backend_ seletivamente. -* Testes _backend_ _REST_ baseados no **Pytest**, integrados com Docker, entÃŖo vocÃĒ pode testar a interaÃ§ÃŖo completa da API, independente do banco de dados. Como roda no Docker, ele pode construir um novo repositÃŗrio de dados do zero toda vez (assim vocÃĒ pode usar ElasticSearch, MongoDB, CouchDB, ou o que quiser, e apenas testar que a API esteja funcionando). -* FÃĄcil integraÃ§ÃŖo com Python atravÊs dos **Kernels Jupyter** para desenvolvimento remoto ou no Docker com extensÃĩes como Atom Hydrogen ou Visual Studio Code Jupyter. -* _Frontend_ **Vue**: - * Gerado com Vue CLI. - * Controle de **AutenticaÃ§ÃŖo JWT**. - * VisualizaÃ§ÃŖo de _login_. - * ApÃŗs o _login_, visualizaÃ§ÃŖo do painel de controle principal. - * Painel de controle principal com criaÃ§ÃŖo e ediÃ§ÃŖo de usuÃĄrio. - * EdiÃ§ÃŖo do prÃŗprio usuÃĄrio. - * **Vuex**. - * **Vue-router**. - * **Vuetify** para belos componentes _material design_. - * **TypeScript**. - * Servidor Docker baseado em **Nginx** (configurado para rodar "lindamente" com Vue-router). - * ConstruÃ§ÃŖo multi-estÃĄgio Docker, entÃŖo vocÃĒ nÃŖo precisa salvar ou _commitar_ cÃŗdigo compilado. - * Testes _frontend_ rodados na hora da construÃ§ÃŖo (pode ser desabilitado tambÊm). - * Feito tÃŖo modular quanto possível, entÃŖo ele funciona fora da caixa, mas vocÃĒ pode gerar novamente com Vue CLI ou criar conforme vocÃĒ queira, e reutilizar o que quiser. -* **PGAdmin** para banco de dados PostgreSQL, vocÃĒ pode modificar para usar PHPMyAdmin e MySQL facilmente. -* **Flower** para monitoraÃ§ÃŖo de tarefas Celery. -* Balanceamento de carga entre _frontend_ e _backend_ com **Traefik**, entÃŖo vocÃĒ pode ter ambos sob o mesmo domínio, separados por rota, mas servidos por diferentes containers. -* IntegraÃ§ÃŖo Traefik, incluindo geraÃ§ÃŖo automÃĄtica de certificados **HTTPS** Let's Encrypt. -* GitLab **CI** (integraÃ§ÃŖo contínua), incluindo testes _frontend_ e _backend_. - -## Full Stack FastAPI Couchbase - -GitHub: https://github.com/tiangolo/full-stack-fastapi-couchbase - -âš ī¸ **WARNING** âš ī¸ - -Se vocÃĒ estÃĄ iniciando um novo projeto do zero, verifique as alternativas aqui. - -Por exemplo, o gerador de projetos Full Stack FastAPI PostgreSQL pode ser uma alternativa melhor, como ele Ê ativamente mantido e utilizado. E ele inclui todos os novos recursos e melhorias. - -VocÃĒ ainda Ê livre para utilizar o gerador baseado em Couchbase se quiser, ele provavelmente ainda funciona bem, e vocÃĒ jÃĄ tem um projeto gerado com ele que roda bem tambÊm (e vocÃĒ provavelmente jÃĄ atualizou ele para encaixar nas suas necessidades). - -VocÃĒ pode ler mais sobre nas documentaÃ§ÃŖoes do repositÃŗrio. - -## Full Stack FastAPI MongoDB - -...pode demorar, dependendo do meu tempo disponível e outros fatores. 😅 🎉 - -## Modelos de Aprendizado de MÃĄquina com spaCy e FastAPI - -GitHub: https://github.com/microsoft/cookiecutter-spacy-fastapi - -### Modelos de Aprendizado de MÃĄquina com spaCy e FastAPI - Recursos - -* IntegraÃ§ÃŖo com modelo NER **spaCy**. -* Formato de requisiÃ§ÃŖo **Busca Cognitiva Azure** acoplado. -* Servidor Python _web_ **Pronto para ProduÃ§ÃŖo** usando Uvicorn e Gunicorn. -* ImplantaÃ§ÃŖo **Azure DevOps** Kubernetes (AKS) CI/CD acoplada. -* **Multilingual** facilmente escolhido como uma das linguagens spaCy acopladas durante a configuraÃ§ÃŖo do projeto. -* **Facilmente extensível** para outros modelos de _frameworks_ (Pytorch, Tensorflow), nÃŖo apenas spaCy. +- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) para a API do backend em Python. + - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) para as interaçÃĩes do Python com bancos de dados SQL (ORM). + - 🔍 [Pydantic](https://docs.pydantic.dev), usado pelo FastAPI, para validaÃ§ÃŖo de dados e gerenciamento de configuraçÃĩes. + - 💾 [PostgreSQL](https://www.postgresql.org) como banco de dados SQL. +- 🚀 [React](https://react.dev) para o frontend. + - 💃 Usando TypeScript, hooks, [Vite](https://vitejs.dev), e outras partes de uma _stack_ frontend moderna. + - 🎨 [Chakra UI](https://chakra-ui.com) para os componentes de frontend. + - 🤖 Um cliente frontend automaticamente gerado. + - đŸ§Ē [Playwright](https://playwright.dev) para testes Ponta-a-Ponta. + - đŸĻ‡ Suporte para modo escuro. +- 🐋 [Docker Compose](https://www.docker.com) para desenvolvimento e produÃ§ÃŖo. +- 🔒 _Hash_ seguro de senhas por padrÃŖo. +- 🔑 AutenticaÃ§ÃŖo por token JWT. +- đŸ“Ģ RecuperaÃ§ÃŖo de senhas baseada em email. +- ✅ Testes com [Pytest](https://pytest.org). +- 📞 [Traefik](https://traefik.io) como proxy reverso / balanceador de carga. +- đŸšĸ InstruçÃĩes de _deployment_ usando Docker Compose, incluindo como configurar um proxy frontend com Traefik para gerenciar automaticamente certificados HTTPS. +- 🏭 CI (IntegraÃ§ÃŖo Contínua) e CD (_Deploy_ Contínuo) baseado em GitHub Actions. diff --git a/docs/pt/docs/tutorial/security/index.md b/docs/pt/docs/tutorial/security/index.md index b4440ec04..2ebb87fcd 100644 --- a/docs/pt/docs/tutorial/security/index.md +++ b/docs/pt/docs/tutorial/security/index.md @@ -22,7 +22,7 @@ Ela Ê bastante extensiva na especificaÃ§ÃŖo e cobre casos de uso muito complexo Ela inclui uma forma para autenticaÃ§ÃŖo usando “third party”/aplicaçÃĩes de terceiros. -Isso Ê o que todos os sistemas com “Login with Facebook, Google, Twitter, GitHub” usam por baixo. +Isso Ê o que todos os sistemas com “Login with Facebook, Google, X (Twitter), GitHub” usam por baixo. ### OAuth 1 @@ -79,7 +79,7 @@ OpenAPI define os seguintes esquemas de segurança: * HTTP Basic authentication. * HTTP Digest, etc. * `oauth2`: todas as formas do OAuth2 para lidar com segurança (chamados "fluxos"). - * VÃĄrios desses fluxos sÃŖo apropriados para construir um provedor de autenticaÃ§ÃŖo OAuth2 (como Google, Facebook, Twitter, GitHub, etc): + * VÃĄrios desses fluxos sÃŖo apropriados para construir um provedor de autenticaÃ§ÃŖo OAuth2 (como Google, Facebook, X (Twitter), GitHub, etc): * `implicit` * `clientCredentials` * `authorizationCode` @@ -91,7 +91,7 @@ OpenAPI define os seguintes esquemas de segurança: /// tip | Dica -IntegraÃ§ÃŖo com outros provedores de autenticaÃ§ÃŖo/autorizaÃ§ÃŖo como Google, Facebook, Twitter, GitHub, etc. Ê bem possível e relativamente fÃĄcil. +IntegraÃ§ÃŖo com outros provedores de autenticaÃ§ÃŖo/autorizaÃ§ÃŖo como Google, Facebook, X (Twitter), GitHub, etc. Ê bem possível e relativamente fÃĄcil. O problema mais complexo Ê criar um provedor de autenticaÃ§ÃŖo/autorizaÃ§ÃŖo como eles, mas o FastAPI dÃĄ a vocÃĒ ferramentas para fazer isso facilmente, enquanto faz o trabalho pesado para vocÃĒ. diff --git a/docs/pt/docs/tutorial/security/oauth2-jwt.md b/docs/pt/docs/tutorial/security/oauth2-jwt.md index 4b99c4c59..7d80d12fa 100644 --- a/docs/pt/docs/tutorial/security/oauth2-jwt.md +++ b/docs/pt/docs/tutorial/security/oauth2-jwt.md @@ -271,4 +271,4 @@ Mas ele fornece as ferramentas para simplificar o processo o mÃĄximo possível, E vocÃĒ pode usar e implementar protocolos padrÃŖo seguros, como o OAuth2, de uma maneira relativamente simples. -VocÃĒ pode aprender mais no **Guia Avançado do UsuÃĄrio** sobre como usar os "scopes" do OAuth2 para um sistema de permissÃĩes mais refinado, seguindo esses mesmos padrÃĩes. O OAuth2 com scopes Ê o mecanismo usado por muitos provedores grandes de autenticaÃ§ÃŖo, como o Facebook, Google, GitHub, Microsoft, Twitter, etc. para autorizar aplicativos de terceiros a interagir com suas APIs em nome de seus usuÃĄrios. +VocÃĒ pode aprender mais no **Guia Avançado do UsuÃĄrio** sobre como usar os "scopes" do OAuth2 para um sistema de permissÃĩes mais refinado, seguindo esses mesmos padrÃĩes. O OAuth2 com scopes Ê o mecanismo usado por muitos provedores grandes de autenticaÃ§ÃŖo, como o Facebook, Google, GitHub, Microsoft, X (Twitter), etc. para autorizar aplicativos de terceiros a interagir com suas APIs em nome de seus usuÃĄrios. diff --git a/docs/ru/docs/_llm-test.md b/docs/ru/docs/_llm-test.md new file mode 100644 index 000000000..476cc1924 --- /dev/null +++ b/docs/ru/docs/_llm-test.md @@ -0,0 +1,503 @@ +# ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đš Ņ„Đ°ĐšĐģ LLM { #llm-test-file } + +Đ­Ņ‚ĐžŅ‚ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚, ĐŋĐžĐŊиĐŧаĐĩŅ‚ Đģи LLM, ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´ŅŅ‰Đ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, `general_prompt` в `scripts/translate.py` и ŅĐˇŅ‹ĐēОвОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐŧĐŋŅ‚ в `docs/{language code}/llm-prompt.md`. Đ¯ĐˇŅ‹ĐēОвОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐŧĐŋŅ‚ дОйавĐģŅĐĩŅ‚ŅŅ Đē `general_prompt`. + +ĐĸĐĩҁ҂ҋ, дОйавĐģĐĩĐŊĐŊŅ‹Đĩ СдĐĩҁҌ, ŅƒĐ˛Đ¸Đ´ŅŅ‚ Đ˛ŅĐĩ ŅĐžĐˇĐ´Đ°Ņ‚ĐĩĐģи ŅĐˇŅ‹ĐēĐžĐ˛Ņ‹Ņ… ĐŋŅ€ĐžĐŧĐŋŅ‚ĐžĐ˛. + +Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ: + +* ĐŸĐžĐ´ĐŗĐžŅ‚ĐžĐ˛ŅŒŅ‚Đĩ ŅĐˇŅ‹ĐēОвОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐŧĐŋŅ‚ — `docs/{language code}/llm-prompt.md`. +* Đ’Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚Đĩ ĐŊĐžĐ˛Ņ‹Đš ĐŋĐĩŅ€ĐĩвОд ŅŅ‚ĐžĐŗĐž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ° ĐŊа ĐŊ҃ĐļĐŊŅ‹Đš ҆ĐĩĐģĐĩвОК ŅĐˇŅ‹Đē (ҁĐŧ., ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžĐŧаĐŊĐ´Ņƒ `translate-page` в `translate.py`). Đ­Ņ‚Đž ŅĐžĐˇĐ´Đ°ŅŅ‚ ĐŋĐĩŅ€ĐĩвОд в `docs/{language code}/docs/_llm-test.md`. +* ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Đ˛ŅŅ‘ Đģи в ĐŋĐžŅ€ŅĐ´ĐēĐĩ в ĐŋĐĩŅ€ĐĩвОдĐĩ. +* ĐŸŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚Đĩ Đ˛Đ°Ņˆ ŅĐˇŅ‹ĐēОвОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐŧĐŋŅ‚, ĐžĐąŅ‰Đ¸Đš ĐŋŅ€ĐžĐŧĐŋŅ‚ иĐģи аĐŊĐŗĐģĐ¸ĐšŅĐēиК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚. +* Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ Đ¸ŅĐŋŅ€Đ°Đ˛ŅŒŅ‚Đĩ ĐžŅŅ‚Đ°Đ˛ŅˆĐ¸ĐĩŅŅ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ в ĐŋĐĩŅ€ĐĩвОдĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ ĐąŅ‹Đģ Ņ…ĐžŅ€ĐžŅˆĐ¸Đŧ. +* ПĐĩŅ€ĐĩвĐĩĐ´Đ¸Ņ‚Đĩ СаĐŊОвО, иĐŧĐĩŅ Ņ…ĐžŅ€ĐžŅˆĐ¸Đš ĐŋĐĩŅ€ĐĩвОд ĐŊа ĐŧĐĩҁ҂Đĩ. ИдĐĩаĐģҌĐŊŅ‹Đŧ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ĐžĐŧ ĐąŅƒĐ´ĐĩŅ‚ ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸Ņ, ĐēĐžĐŗĐ´Đ° LLM йОĐģҌ҈Đĩ ĐŊĐĩ вĐŊĐžŅĐ¸Ņ‚ иСĐŧĐĩĐŊĐĩĐŊиК в ĐŋĐĩŅ€ĐĩвОд. Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐžĐąŅ‰Đ¸Đš ĐŋŅ€ĐžĐŧĐŋŅ‚ и Đ˛Đ°Ņˆ ŅĐˇŅ‹ĐēОвОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐŧĐŋŅ‚ ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž Ņ…ĐžŅ€ĐžŅˆĐ¸ (иĐŊĐžĐŗĐ´Đ° ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ´ĐĩĐģĐ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž, ĐēаСаĐģĐžŅŅŒ ĐąŅ‹, ҁĐģŅƒŅ‡Đ°ĐšĐŊҋ҅ иСĐŧĐĩĐŊĐĩĐŊиК, ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊа в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž LLM — ĐŊĐĩĐ´ĐĩŅ‚ĐĩŅ€ĐŧиĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ аĐģĐŗĐžŅ€Đ¸Ņ‚ĐŧŅ‹). + +ĐĸĐĩҁ҂ҋ: + +## Đ¤Ņ€Đ°ĐŗĐŧĐĩĐŊ҂ҋ ĐēОда { #code-snippets} + +//// tab | ĐĸĐĩҁ҂ + +Đ­Ņ‚Đž Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ ĐēОда: `foo`. А ŅŅ‚Đž Đĩ҉ґ ОдиĐŊ Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ ĐēОда: `bar`. И Đĩ҉ґ ОдиĐŊ: `baz quux`. + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ХОдĐĩŅ€ĐļиĐŧĐžĐĩ Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ĐžĐ˛ ĐēОда Đ´ĐžĐģĐļĐŊĐž ĐžŅŅ‚Đ°Đ˛Đ°Ņ‚ŅŒŅŅ ĐēаĐē ĐĩŅŅ‚ŅŒ. + +ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ `### Content of code snippets` в ĐžĐąŅ‰ĐĩĐŧ ĐŋŅ€ĐžĐŧĐŋŅ‚Đĩ в `scripts/translate.py`. + +//// + +## ĐšĐ°Đ˛Ņ‹Ņ‡Đēи { #quotes } + +//// tab | ĐĸĐĩҁ҂ + +Đ’Ņ‡ĐĩŅ€Đ° ĐŧОК Đ´Ņ€ŅƒĐŗ ĐŊаĐŋĐ¸ŅĐ°Đģ: "Đ•ŅĐģи Đ˛Ņ‹ ĐŊаĐŋĐ¸ŅĐ°Đģи incorrectly ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž, СĐŊĐ°Ņ‡Đ¸Ņ‚ Đ˛Ņ‹ ĐŊаĐŋĐ¸ŅĐ°Đģи ŅŅ‚Đž ĐŊĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž". На Ņ‡Ņ‚Đž Ņ ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Đģ: "ВĐĩŅ€ĐŊĐž, ĐŊĐž 'incorrectly' — ŅŅ‚Đž ĐŊĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž, а ĐŊĐĩ '"incorrectly"'". + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +LLM, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŋĐĩŅ€ĐĩвĐĩĐ´Ņ‘Ņ‚ ŅŅ‚Đž ĐŊĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž. ИĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐž ĐģĐ¸ŅˆŅŒ Ņ‚Đž, ŅĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ Đģи ĐžĐŊа Ņ„Đ¸ĐēŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ĐŋĐĩŅ€ĐĩвОд ĐŋŅ€Đ¸ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐžĐŧ ĐŋĐĩŅ€ĐĩвОдĐĩ. + +/// + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐĐ˛Ņ‚ĐžŅ€ ĐŋŅ€ĐžĐŧĐŋŅ‚Đ° ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ, Ņ…ĐžŅ‡ĐĩŅ‚ Đģи ĐžĐŊ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐŊĐĩĐšŅ‚Ņ€Đ°ĐģҌĐŊŅ‹Đĩ ĐēĐ°Đ˛Ņ‹Ņ‡Đēи в Ņ‚Đ¸ĐŋĐžĐŗŅ€Đ°Ņ„ŅĐēиĐĩ. ДоĐŋ҃ҁĐēаĐĩŅ‚ŅŅ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ Đ¸Ņ… ĐēаĐē ĐĩŅŅ‚ŅŒ. + +ĐĄĐŧ., ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ€Đ°ĐˇĐ´ĐĩĐģ `### Quotes` в `docs/de/llm-prompt.md`. + +//// + +## ĐšĐ°Đ˛Ņ‹Ņ‡Đēи вО Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚Đ°Ņ… ĐēОда { #quotes-in-code-snippets} + +//// tab | ĐĸĐĩҁ҂ + +`pip install "foo[bar]"` + +ĐŸŅ€Đ¸ĐŧĐĩҀҋ ŅŅ‚Ņ€ĐžĐēĐžĐ˛Ņ‹Ņ… ĐģĐ¸Ņ‚ĐĩŅ€Đ°ĐģОв вО Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚Đ°Ņ… ĐēОда: `"this"`, `'that'`. + +ĐĄĐģĐžĐļĐŊŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€ ŅŅ‚Ņ€ĐžĐēĐžĐ˛Ņ‹Ņ… ĐģĐ¸Ņ‚ĐĩŅ€Đ°ĐģОв вО Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚Đ°Ņ… ĐēОда: `f"I like {'oranges' if orange else "apples"}"` + +ĐĨĐ°Ņ€Đ´ĐēĐžŅ€: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"` + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +... ОдĐŊаĐēĐž ĐēĐ°Đ˛Ņ‹Ņ‡Đēи вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ĐžĐ˛ ĐēОда Đ´ĐžĐģĐļĐŊŅ‹ ĐžŅŅ‚Đ°Đ˛Đ°Ņ‚ŅŒŅŅ ĐēаĐē ĐĩŅŅ‚ŅŒ. + +//// + +## БĐģĐžĐēи ĐēОда { #code-blocks } + +//// tab | ĐĸĐĩҁ҂ + +ĐŸŅ€Đ¸ĐŧĐĩŅ€ ĐēОда Bash... + +```bash +# Đ’Ņ‹Đ˛ĐĩŅŅ‚Đ¸ ĐŋŅ€Đ¸Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đĩ Đ˛ŅĐĩĐģĐĩĐŊĐŊОК +echo "Hello universe" +``` + +...и ĐŋŅ€Đ¸ĐŧĐĩŅ€ Đ˛Ņ‹Đ˛ĐžĐ´Đ° в ĐēĐžĐŊŅĐžĐģи... + +```console +$ fastapi run main.py + FastAPI Starting server + Searching for package file structure +``` + +...и Đĩ҉ґ ОдиĐŊ ĐŋŅ€Đ¸ĐŧĐĩŅ€ Đ˛Ņ‹Đ˛ĐžĐ´Đ° в ĐēĐžĐŊŅĐžĐģи... + +```console +// ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ "Code" +$ mkdir code +// ПĐĩŅ€ĐĩĐšŅ‚Đ¸ в ŅŅ‚Ņƒ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ +$ cd code +``` + +...и ĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐēОда ĐŊа Python... + +```Python +wont_work() # Đ­Ņ‚Đž ĐŊĐĩ ŅŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ 😱 +works(foo="bar") # Đ­Ņ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ 🎉 +``` + +...и ĐŊа ŅŅ‚ĐžĐŧ Đ˛ŅŅ‘. + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +Код в ĐąĐģĐžĐēĐ°Ņ… ĐēОда ĐŊĐĩ Đ´ĐžĐģĐļĐĩĐŊ иСĐŧĐĩĐŊŅŅ‚ŅŒŅŅ, Са Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩĐŧ ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đĩв. + +ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ `### Content of code blocks` в ĐžĐąŅ‰ĐĩĐŧ ĐŋŅ€ĐžĐŧĐŋŅ‚Đĩ в `scripts/translate.py`. + +//// + +## ВĐēĐģадĐēи и Ņ†Đ˛ĐĩŅ‚ĐŊŅ‹Đĩ ĐąĐģĐžĐēи { #tabs-and-colored-boxes } + +//// tab | ĐĸĐĩҁ҂ + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +/// check | ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +/// tip | ХОвĐĩŅ‚ +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +/// danger | ОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐēҁ҂ +/// + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ДĐģŅ вĐēĐģадОĐē и ĐąĐģĐžĐēОв `Info`/`Note`/`Warning`/и Ņ‚.Đŋ. ĐŊ҃ĐļĐŊĐž Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩвОд Đ¸Ņ… ĐˇĐ°ĐŗĐžĐģОвĐēа ĐŋĐžŅĐģĐĩ вĐĩŅ€Ņ‚Đ¸ĐēаĐģҌĐŊОК ҇ĐĩҀ҂ҋ (`|`). + +ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‹ `### Special blocks` и `### Tab blocks` в ĐžĐąŅ‰ĐĩĐŧ ĐŋŅ€ĐžĐŧĐŋŅ‚Đĩ в `scripts/translate.py`. + +//// + +## ВĐĩĐą- и вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ ҁҁҋĐģĐēи { #web-and-internal-links } + +//// tab | ĐĸĐĩҁ҂ + +ĐĸĐĩĐēҁ҂ ҁҁҋĐģĐžĐē Đ´ĐžĐģĐļĐĩĐŊ ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´Đ¸Ņ‚ŅŒŅŅ, Đ°Đ´Ņ€Đĩҁ ҁҁҋĐģĐēи ĐŊĐĩ Đ´ĐžĐģĐļĐĩĐŊ иСĐŧĐĩĐŊŅŅ‚ŅŒŅŅ: + +* [ĐĄŅŅ‹ĐģĐēа ĐŊа ĐˇĐ°ĐŗĐžĐģОвОĐē Đ˛Ņ‹ŅˆĐĩ](#code-snippets) +* [ВĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊŅŅ ҁҁҋĐģĐēа](index.md#installation){.internal-link target=_blank} +* ВĐŊĐĩ҈ĐŊŅŅ ҁҁҋĐģĐēа +* ĐĄŅŅ‹ĐģĐēа ĐŊа ŅŅ‚Đ¸ĐģҌ +* ĐĄŅŅ‹ĐģĐēа ĐŊа ҁĐēŅ€Đ¸ĐŋŅ‚ +* ĐĄŅŅ‹ĐģĐēа ĐŊа Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиĐĩ + +ĐĸĐĩĐēҁ҂ ҁҁҋĐģĐžĐē Đ´ĐžĐģĐļĐĩĐŊ ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´Đ¸Ņ‚ŅŒŅŅ, Đ°Đ´Ņ€Đĩҁ ҁҁҋĐģĐēи Đ´ĐžĐģĐļĐĩĐŊ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ĐŊа ĐŋĐĩŅ€ĐĩвОд: + +* ĐĄŅŅ‹ĐģĐēа ĐŊа FastAPI + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐĄŅŅ‹ĐģĐēи Đ´ĐžĐģĐļĐŊŅ‹ ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´Đ¸Ņ‚ŅŒŅŅ, ĐŊĐž Đ¸Ņ… Đ°Đ´Ņ€ĐĩŅĐ° ĐŊĐĩ Đ´ĐžĐģĐļĐŊŅ‹ иСĐŧĐĩĐŊŅŅ‚ŅŒŅŅ. Đ˜ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ — Đ°ĐąŅĐžĐģŅŽŅ‚ĐŊŅ‹Đĩ ҁҁҋĐģĐēи ĐŊа ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņ‹ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ FastAPI. В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ҁҁҋĐģĐēа Đ´ĐžĐģĐļĐŊа вĐĩŅŅ‚Đ¸ ĐŊа ĐŋĐĩŅ€ĐĩвОд. + +ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ `### Links` в ĐžĐąŅ‰ĐĩĐŧ ĐŋŅ€ĐžĐŧĐŋŅ‚Đĩ в `scripts/translate.py`. + +//// + +## HTML-ŅĐģĐĩĐŧĐĩĐŊ҂ҋ "abbr" { #html-abbr-elements } + +//// tab | ĐĸĐĩҁ҂ + +Đ’ĐžŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅĐģĐĩĐŧĐĩĐŊ҂ҋ, ĐžĐąŅ‘Ņ€ĐŊŅƒŅ‚Ņ‹Đĩ в HTML-ŅĐģĐĩĐŧĐĩĐŊ҂ҋ "abbr" (Ņ‡Đ°ŅŅ‚ŅŒ Đ˛Ņ‹Đ´ŅƒĐŧаĐŊа): + +### abbr Đ´Đ°Ņ‘Ņ‚ ĐŋĐžĐģĐŊŅƒŅŽ Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đē҃ { #the-abbr-gives-a-full-phrase } + +* GTD +* lt +* XWT +* PSGI + +### abbr Đ´Đ°Ņ‘Ņ‚ ĐžĐąŅŠŅŅĐŊĐĩĐŊиĐĩ { #the-abbr-gives-an-explanation } + +* ĐēĐģĐ°ŅŅ‚ĐĩŅ€ +* ГĐģŅƒĐąĐžĐēĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ + +### abbr Đ´Đ°Ņ‘Ņ‚ ĐŋĐžĐģĐŊŅƒŅŽ Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đē҃ и ĐžĐąŅŠŅŅĐŊĐĩĐŊиĐĩ { #the-abbr-gives-a-full-phrase-and-an-explanation } + +* MDN +* I/O. + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐŅ‚Ņ€Đ¸ĐąŅƒŅ‚Ņ‹ "title" ŅĐģĐĩĐŧĐĩĐŊŅ‚ĐžĐ˛ "abbr" ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´ŅŅ‚ŅŅ ĐŋĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧ ĐŋŅ€Đ°Đ˛Đ¸ĐģаĐŧ. + +ПĐĩŅ€ĐĩĐ˛ĐžĐ´Ņ‹ ĐŧĐžĐŗŅƒŅ‚ дОйавĐģŅŅ‚ŅŒ ŅĐ˛ĐžĐ¸ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ ŅĐģĐĩĐŧĐĩĐŊ҂ҋ "abbr", ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ LLM ĐŊĐĩ Đ´ĐžĐģĐļĐŊа ŅƒĐ´Đ°ĐģŅŅ‚ŅŒ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐąŅŠŅŅĐŊĐ¸Ņ‚ŅŒ аĐŊĐŗĐģĐ¸ĐšŅĐēиĐĩ ҁĐģОва. + +ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ `### HTML abbr elements` в ĐžĐąŅ‰ĐĩĐŧ ĐŋŅ€ĐžĐŧĐŋŅ‚Đĩ в `scripts/translate.py`. + +//// + +## Đ—Đ°ĐŗĐžĐģОвĐēи { #headings } + +//// tab | ĐĸĐĩҁ҂ + +### Đ Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа вĐĩб‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž { #develop-a-webapp-a-tutorial } + +ĐŸŅ€Đ¸Đ˛ĐĩŅ‚. + +### АĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв и -аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ { #type-hints-and-annotations } + +ĐĄĐŊОва ĐŋŅ€Đ¸Đ˛ĐĩŅ‚. + +### ĐĄŅƒĐŋĐĩŅ€- и ĐŋОдĐēĐģĐ°ŅŅŅ‹ { #super-and-subclasses } + +ĐĄĐŊОва ĐŋŅ€Đ¸Đ˛ĐĩŅ‚. + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ЕдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ Đļґҁ҂ĐēĐžĐĩ ĐŋŅ€Đ°Đ˛Đ¸ĐģĐž Đ´ĐģŅ ĐˇĐ°ĐŗĐžĐģОвĐēОв — LLM Đ´ĐžĐģĐļĐŊа ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ Ņ‡Đ°ŅŅ‚ŅŒ Ņ…ĐĩŅˆĐ° в Ņ„Đ¸ĐŗŅƒŅ€ĐŊҋ҅ ҁĐēОйĐēĐ°Ņ… ĐąĐĩС иСĐŧĐĩĐŊĐĩĐŊиК, Ņ‡Ņ‚ĐžĐąŅ‹ ҁҁҋĐģĐēи ĐŊĐĩ ĐģĐžĐŧаĐģĐ¸ŅŅŒ. + +ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ `### Headings` в ĐžĐąŅ‰ĐĩĐŧ ĐŋŅ€ĐžĐŧĐŋŅ‚Đĩ в `scripts/translate.py`. + +ДĐģŅ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ŅĐˇŅ‹ĐēĐžĐ˛Ņ‹Ņ… иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Đš ҁĐŧ., ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ€Đ°ĐˇĐ´ĐĩĐģ `### Headings` в `docs/de/llm-prompt.md`. + +//// + +## ĐĸĐĩŅ€ĐŧиĐŊŅ‹, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đĩ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #terms-used-in-the-docs } + +//// tab | ĐĸĐĩҁ҂ + +* Đ˛Ņ‹ +* Đ˛Đ°Ņˆ + +* ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ +* и Ņ‚.Đ´. + +* `foo` ĐēаĐē `int` +* `bar` ĐēаĐē `str` +* `baz` ĐēаĐē `list` + +* ĐŖŅ‡ĐĩĐąĐŊиĐē — Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ +* Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐžĐĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ +* ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ ĐŋĐž SQLModel +* ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API +* ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ + +* ĐĐ°ŅƒĐēа Đž даĐŊĐŊҋ҅ +* ГĐģŅƒĐąĐžĐēĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ +* ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ +* ВĐŊĐĩĐ´Ņ€ĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš +* ĐŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ HTTP Basic +* HTTP Digest +* Ņ„ĐžŅ€ĐŧĐ°Ņ‚ ISO +* ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ JSON Schema +* JSON-ҁ҅ĐĩĐŧа +* ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ҁ҅ĐĩĐŧŅ‹ +* password flow +* МобиĐģҌĐŊŅ‹Đš + +* ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐ¸Đš +* ҁĐŋŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš +* ĐŊĐĩĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đš +* ĐŊа ĐģĐĩŅ‚Ņƒ +* ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ +* ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ +* Ņ‡ŅƒĐ˛ŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš Đē Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Ņƒ +* ĐŊĐĩŅ‡ŅƒĐ˛ŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš Đē Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Ņƒ + +* ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ +* ĐžŅ‚Đ´Đ°Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņƒ + +* ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ +* ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ + +* HTTP-СаĐŋŅ€ĐžŅ +* HTTP-ĐžŅ‚Đ˛ĐĩŅ‚ +* ĐžŅ‚Đ˛ĐĩŅ‚ ҁ ĐžŅˆĐ¸ĐąĐēОК + +* ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸ +* Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ +* Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸ + +* Ņ‚ĐĩĐģĐž +* Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° +* Ņ‚ĐĩĐģĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° +* JSON-Ņ‚ĐĩĐģĐž +* Ņ‚ĐĩĐģĐž Ņ„ĐžŅ€ĐŧŅ‹ +* Ņ‚ĐĩĐģĐž Ņ„Đ°ĐšĐģа +* Ņ‚ĐĩĐģĐž Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ + +* ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ +* body-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ +* path-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ +* query-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ +* cookie-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ +* ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ ĐˇĐ°ĐŗĐžĐģОвĐēа +* ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ„ĐžŅ€ĐŧŅ‹ +* ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ + +* ŅĐžĐąŅ‹Ņ‚Đ¸Đĩ +* ŅĐžĐąŅ‹Ņ‚Đ¸Đĩ СаĐŋ҃ҁĐēа +* СаĐŋ҃ҁĐē ҁĐĩŅ€Đ˛ĐĩŅ€Đ° +* ŅĐžĐąŅ‹Ņ‚Đ¸Đĩ ĐžŅŅ‚Đ°ĐŊОвĐēи +* ŅĐžĐąŅ‹Ņ‚Đ¸Đĩ lifespan + +* ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē +* ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ŅĐžĐąŅ‹Ņ‚Đ¸Ņ +* ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК +* ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ + +* ĐŧОдĐĩĐģҌ +* Pydantic-ĐŧОдĐĩĐģҌ +* ĐŧОдĐĩĐģҌ даĐŊĐŊҋ҅ +* ĐŧОдĐĩĐģҌ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ +* ĐŧОдĐĩĐģҌ Ņ„ĐžŅ€ĐŧŅ‹ +* ĐžĐąŅŠĐĩĐēŅ‚ ĐŧОдĐĩĐģи + +* ĐēĐģĐ°ŅŅ +* ĐąĐ°ĐˇĐžĐ˛Ņ‹Đš ĐēĐģĐ°ŅŅ +* Ņ€ĐžĐ´Đ¸Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ +* ĐŋОдĐēĐģĐ°ŅŅ +* Đ´ĐžŅ‡ĐĩŅ€ĐŊиК ĐēĐģĐ°ŅŅ +* Ņ€ĐžĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đš ĐēĐģĐ°ŅŅ +* ĐŧĐĩŅ‚ĐžĐ´ ĐēĐģĐ°ŅŅĐ° + +* ĐˇĐ°ĐŗĐžĐģОвОĐē +* HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи +* ĐˇĐ°ĐŗĐžĐģОвОĐē Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ +* ĐˇĐ°ĐŗĐžĐģОвОĐē `Authorization` +* ĐˇĐ°ĐŗĐžĐģОвОĐē `Forwarded` + +* ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš +* ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ +* ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧŅ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ +* ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧŅ‹Đš + +* ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đš ввОдОĐŧ/Đ˛Ņ‹Đ˛ĐžĐ´ĐžĐŧ +* ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐžĐŧ +* ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ +* ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ +* ĐŧĐŊĐžĐŗĐžĐŋŅ€ĐžŅ†ĐĩҁҁĐŊĐžŅŅ‚ŅŒ + +* ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ +* ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ +* `PATH` +* ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ `PATH` + +* Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ +* ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ +* Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸Ņ +* Ņ„ĐžŅ€Đŧа Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ +* ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ +* ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ŅƒĐĩŅ‚ŅŅ +* ŅĐ¸ŅŅ‚ĐĩĐŧа Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ŅƒĐĩŅ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ + +* CLI +* иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи + +* ҁĐĩŅ€Đ˛ĐĩŅ€ +* ĐēĐģиĐĩĐŊŅ‚ + +* ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ +* ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ + +* Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа +* ŅŅ‚Đ°ĐŋŅ‹ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи + +* dict +* ҁĐģĐžĐ˛Đ°Ņ€ŅŒ +* ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊиĐĩ +* enum +* ҇ĐģĐĩĐŊ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ + +* ĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē +* Đ´ĐĩĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē +* ĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ +* Đ´ĐĩĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ + +* Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ +* Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ + +* Đ˛Ņ‹Ņ€Đ°ĐļĐĩĐŊиĐĩ +* ĐžĐŋĐĩŅ€Đ°Ņ‚ĐžŅ€ + +* Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´ +* ĐąŅĐēĐĩĐŊĐ´ + +* ĐžĐąŅŅƒĐļĐ´ĐĩĐŊиĐĩ ĐŊа GitHub +* Issue ĐŊа GitHub (Ņ‚Đ¸ĐēĐĩŅ‚/ĐžĐąŅ€Đ°Ņ‰ĐĩĐŊиĐĩ) + +* ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ +* ĐžĐŋŅ‚Đ¸ĐŧĐ¸ĐˇĐ°Ņ†Đ¸Ņ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ + +* Ņ‚Đ¸Đŋ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐŗĐž СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ +* Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ + +* ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ +* ҁ҅ĐĩĐŧа ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ + +* ĐˇĐ°Đ´Đ°Ņ‡Đ° +* Ņ„ĐžĐŊĐžĐ˛Đ°Ņ ĐˇĐ°Đ´Đ°Ņ‡Đ° +* Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ + +* ŅˆĐ°ĐąĐģĐžĐŊ +* ŅˆĐ°ĐąĐģĐžĐŊĐ¸ĐˇĐ°Ņ‚ĐžŅ€ + +* аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Ņ Ņ‚Đ¸ĐŋОв +* аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Ņ Ņ‚Đ¸ĐŋОв + +* Đ˛ĐžŅ€ĐēĐĩŅ€ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° +* Đ˛ĐžŅ€ĐēĐĩŅ€ Uvicorn +* Đ˛ĐžŅ€ĐēĐĩŅ€ Gunicorn +* Đ˛ĐžŅ€ĐēĐĩŅ€-ĐŋŅ€ĐžŅ†Đĩҁҁ +* ĐēĐģĐ°ŅŅ Đ˛ĐžŅ€ĐēĐĩŅ€Đ° +* Ņ€Đ°ĐąĐžŅ‡Đ°Ņ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēа + +* Đ´ĐĩĐŋĐģОК +* Ņ€Đ°ĐˇĐ˛ĐĩŅ€ĐŊŅƒŅ‚ŅŒ + +* SDK +* ĐŊĐ°ĐąĐžŅ€ ҁҀĐĩĐ´ŅŅ‚Đ˛ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи ПО + +* `APIRouter` +* `requirements.txt` +* Ņ‚ĐžĐēĐĩĐŊ Bearer +* ĐŊĐĩŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐžĐĩ иСĐŧĐĩĐŊĐĩĐŊиĐĩ +* ĐąĐ°Đŗ +* ĐēĐŊĐžĐŋĐēа +* Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧŅ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ +* ĐēОд +* ĐēĐžĐŧĐŧĐ¸Ņ‚ +* ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° +* ĐēĐžŅ€ŅƒŅ‚Đ¸ĐŊа +* ҁĐĩŅŅĐ¸Ņ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ +* Đ´Đ¸ŅĐē +* Đ´ĐžĐŧĐĩĐŊ +* двиĐļĐžĐē +* Ņ„Đ¸ĐēŅ‚Đ¸Đ˛ĐŊŅ‹Đš X +* ĐŧĐĩŅ‚ĐžĐ´ HTTP GET +* ŅĐģĐĩĐŧĐĩĐŊŅ‚ +* йийĐģĐ¸ĐžŅ‚ĐĩĐēа +* lifespan +* ĐąĐģĐžĐēĐ¸Ņ€ĐžĐ˛Đēа +* middleware (ĐŸŅ€ĐžĐŧĐĩĐļŅƒŅ‚ĐžŅ‡ĐŊŅ‹Đš ҁĐģОК) +* ĐŧОйиĐģҌĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ +* ĐŧĐžĐ´ŅƒĐģҌ +* ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ +* ҁĐĩŅ‚ŅŒ +* origin (Đ¸ŅŅ‚ĐžŅ‡ĐŊиĐē) +* ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ +* ĐŋĐžĐģĐĩСĐŊĐ°Ņ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēа +* ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ +* ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž +* ĐŋŅ€ĐžĐēŅĐ¸ +* Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ (СаĐŋŅ€ĐžŅ ĐŊа иСĐŧĐĩĐŊĐĩĐŊиĐĩ) +* СаĐŋŅ€ĐžŅ +* ĐžĐ—ĐŖ +* ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа +* ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд +* ŅŅ‚Ņ€ĐžĐēа +* Ņ‚ĐĩĐŗ +* вĐĩĐąâ€‘Ņ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē +* ĐŋĐžĐ´ŅŅ‚Đ°ĐŊĐžĐ˛ĐžŅ‡ĐŊŅ‹Đš СĐŊаĐē +* вĐĩŅ€ĐŊŅƒŅ‚ŅŒ +* ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ + +//// + +//// tab | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +Đ­Ņ‚Đž ĐŊĐĩĐŋĐžĐģĐŊŅ‹Đš и ĐŊĐĩĐŊĐžŅ€ĐŧĐ°Ņ‚Đ¸Đ˛ĐŊŅ‹Đš ҁĐŋĐ¸ŅĐžĐē (в ĐžŅĐŊОвĐŊĐžĐŧ) Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēĐ¸Ņ… Ņ‚ĐĩŅ€ĐŧиĐŊОв, Đ˛ŅŅ‚Ņ€ĐĩŅ‡Đ°ŅŽŅ‰Đ¸Ņ…ŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. ОĐŊ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŧĐžŅ‡ŅŒ Đ°Đ˛Ņ‚ĐžŅ€Ņƒ ĐŋŅ€ĐžĐŧĐŋŅ‚Đ° ĐŋĐžĐŊŅŅ‚ŅŒ, ĐŋĐž ĐēаĐēиĐŧ Ņ‚ĐĩŅ€ĐŧиĐŊаĐŧ LLM ĐŊ҃ĐļĐŊа ĐŋĐžĐ´ŅĐēаСĐēа. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžĐŗĐ´Đ° ĐžĐŊа ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž Ņ…ĐžŅ€ĐžŅˆĐ¸Đš ĐŋĐĩŅ€ĐĩвОд Đē ĐŊĐĩĐžĐŋŅ‚Đ¸ĐŧаĐģҌĐŊĐžĐŧ҃. ИĐģи ĐēĐžĐŗĐ´Đ° ҃ ĐŊĐĩŅ‘ вОСĐŊиĐēĐ°ŅŽŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ ŅĐž ҁĐēĐģĐžĐŊĐĩĐŊиĐĩĐŧ/ҁĐŋŅ€ŅĐļĐĩĐŊиĐĩĐŧ Ņ‚ĐĩŅ€ĐŧиĐŊа ĐŊа Đ˛Đ°ŅˆĐĩĐŧ ŅĐˇŅ‹ĐēĐĩ. + +ĐĄĐŧ., ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ€Đ°ĐˇĐ´ĐĩĐģ `### List of English terms and their preferred German translations` в `docs/de/llm-prompt.md`. + +//// diff --git a/docs/ru/docs/about/index.md b/docs/ru/docs/about/index.md index 1015b667a..4f48266a7 100644 --- a/docs/ru/docs/about/index.md +++ b/docs/ru/docs/about/index.md @@ -1,3 +1,3 @@ -# О ĐŋŅ€ĐžĐĩĐēŅ‚Đĩ +# О ĐŋŅ€ĐžĐĩĐēŅ‚Đĩ { #about } -FastAPI: вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐĩ ŅƒŅŅ‚Ņ€ĐžĐšŅŅ‚Đ˛Đž, ĐŋОвĐģĐ¸ŅĐ˛ŅˆĐ¸Đĩ Ņ‚ĐĩŅ…ĐŊĐžĐģĐžĐŗĐ¸Đ¸ и Đ˛ŅŅ‘ Ņ‚Đ°ĐēĐžĐĩ ĐŋŅ€ĐžŅ‡ĐĩĐĩ. 🤓 +О FastAPI, ĐĩĐŗĐž диСаКĐŊĐĩ, Đ¸ŅŅ‚ĐžŅ‡ĐŊиĐēĐ°Ņ… Đ˛Đ´ĐžŅ…ĐŊОвĐĩĐŊĐ¸Ņ и ĐŧĐŊĐžĐŗĐžĐŧ Đ´Ņ€ŅƒĐŗĐžĐŧ. 🤓 diff --git a/docs/ru/docs/advanced/additional-responses.md b/docs/ru/docs/advanced/additional-responses.md new file mode 100644 index 000000000..c63c0c08b --- /dev/null +++ b/docs/ru/docs/advanced/additional-responses.md @@ -0,0 +1,247 @@ +# ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ в OpenAPI { #additional-responses-in-openapi } + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ­Ņ‚Đž дОвОĐģҌĐŊĐž ĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Đ°Ņ Ņ‚ĐĩĐŧа. + +Đ•ŅĐģи Đ˛Ņ‹ Ņ‚ĐžĐģҌĐēĐž ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚Đĩ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ **FastAPI**, вОСĐŧĐžĐļĐŊĐž, ваĐŧ ŅŅ‚Đž ĐŋĐžĐēа ĐŊĐĩ ĐŊ҃ĐļĐŊĐž. + +/// + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ ҁ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдаĐŧи, Ņ‚Đ¸ĐŋаĐŧи ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, ĐžĐŋĐ¸ŅĐ°ĐŊĐ¸ŅĐŧи и Ņ‚.Đ´. + +Đ­Ņ‚Đ¸ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ ĐąŅƒĐ´ŅƒŅ‚ вĐēĐģŅŽŅ‡ĐĩĐŊŅ‹ в ҁ҅ĐĩĐŧ҃ OpenAPI, и ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŋĐžŅĐ˛ŅŅ‚ŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API. + +Но Đ´ĐģŅ Ņ‚Đ°ĐēĐ¸Ņ… Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ ŅƒĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `JSONResponse`, ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ŅĐž ŅĐ˛ĐžĐ¸Đŧ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдОĐŧ и ŅĐžĐ´ĐĩŅ€ĐļиĐŧŅ‹Đŧ. + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚ ҁ `model` { #additional-response-with-model } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ Đ˛Đ°ŅˆĐ¸Đŧ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đ°Đŧ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `responses`. + +ОĐŊ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ `dict`: ĐēĐģŅŽŅ‡Đ¸ — ŅŅ‚Đž ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēĐžĐ´Ņ‹ Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `200`), а СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ — Đ´Ņ€ŅƒĐŗĐ¸Đĩ `dict` ҁ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ĐĩĐš Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž иС ĐŊĐ¸Ņ…. + +КаĐļĐ´Ņ‹Đš иС ŅŅ‚Đ¸Ņ… `dict` Đ´ĐģŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŧĐžĐļĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ĐēĐģŅŽŅ‡ `model`, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš Pydantic-ĐŧОдĐĩĐģҌ, аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž `response_model`. + +**FastAPI** Đ˛ĐžĐˇŅŒĐŧґ҂ ŅŅ‚Ņƒ ĐŧОдĐĩĐģҌ, ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ Đ´ĐģŅ ĐŊĐĩŅ‘ JSONâ€‘ŅŅ…ĐĩĐŧ҃ и вĐēĐģŅŽŅ‡Đ¸Ņ‚ ĐĩŅ‘ в ĐŊ҃ĐļĐŊĐžĐĩ ĐŧĐĩŅŅ‚Đž в OpenAPI. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ Đĩ҉ґ ОдиĐŊ ĐžŅ‚Đ˛ĐĩŅ‚ ŅĐž ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдОĐŧ `404` и Pydantic-ĐŧОдĐĩĐģŅŒŅŽ `Message`, ĐŧĐžĐļĐŊĐž ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ: + +{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *} + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ `JSONResponse` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +/// + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +КĐģŅŽŅ‡ `model` ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Ņ‡Đ°ŅŅ‚ŅŒŅŽ OpenAPI. + +**FastAPI** Đ˛ĐžĐˇŅŒĐŧґ҂ Pydantic-ĐŧОдĐĩĐģҌ ĐžŅ‚Ņ‚ŅƒĐ´Đ°, ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ JSONâ€‘ŅŅ…ĐĩĐŧ҃ и ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ ĐĩŅ‘ в ĐŊ҃ĐļĐŊĐžĐĩ ĐŧĐĩŅŅ‚Đž. + +ĐŅƒĐļĐŊĐžĐĩ ĐŧĐĩŅŅ‚Đž: + +* В ĐēĐģŅŽŅ‡Đĩ `content`, СĐŊĐ°Ņ‡ĐĩĐŊиĐĩĐŧ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Đ´Ņ€ŅƒĐŗĐžĐš JSONâ€‘ĐžĐąŅŠĐĩĐēŅ‚ (`dict`), ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš: + * КĐģŅŽŅ‡ ҁ Ņ‚Đ¸ĐŋĐžĐŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `application/json`, СĐŊĐ°Ņ‡ĐĩĐŊиĐĩĐŧ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Đ´Ņ€ŅƒĐŗĐžĐš JSONâ€‘ĐžĐąŅŠĐĩĐēŅ‚, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš: + * КĐģŅŽŅ‡ `schema`, СĐŊĐ°Ņ‡ĐĩĐŊиĐĩĐŧ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ŅĐ˛ĐģŅĐĩŅ‚ŅŅ JSONâ€‘ŅŅ…ĐĩĐŧа иС ĐŧОдĐĩĐģи — Đ˛ĐžŅ‚ ĐŊ҃ĐļĐŊĐžĐĩ ĐŧĐĩŅŅ‚Đž. + * **FastAPI** дОйавĐģŅĐĩŅ‚ СдĐĩҁҌ ҁҁҋĐģĐē҃ ĐŊа ĐŗĐģОйаĐģҌĐŊŅ‹Đĩ JSONâ€‘ŅŅ…ĐĩĐŧŅ‹ в Đ´Ņ€ŅƒĐŗĐžĐŧ ĐŧĐĩҁ҂Đĩ Đ˛Đ°ŅˆĐĩĐŗĐž OpenAPI вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. ĐĸаĐē Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ и ĐēĐģиĐĩĐŊ҂ҋ ҁĐŧĐžĐŗŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ JSONâ€‘ŅŅ…ĐĩĐŧŅ‹ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅ‚ŅŒ ĐģŅƒŅ‡ŅˆĐ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐēОда и Ņ‚.Đ´. + +/// + +ĐĄĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ в OpenAPI ĐžŅ‚Đ˛Đĩ҂ҋ Đ´ĐģŅ ŅŅ‚ĐžĐš ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ ĐąŅƒĐ´ŅƒŅ‚ Ņ‚Đ°ĐēиĐŧи: + +```JSON hl_lines="3-12" +{ + "responses": { + "404": { + "description": "Additional Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Message" + } + } + } + }, + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Item" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } +} +``` + +ĐĄŅ…ĐĩĐŧŅ‹ даĐŊŅ‹ ĐēаĐē ҁҁҋĐģĐēи ĐŊа Đ´Ņ€ŅƒĐŗĐžĐĩ ĐŧĐĩŅŅ‚Đž вĐŊŅƒŅ‚Ņ€Đ¸ ҁ҅ĐĩĐŧŅ‹ OpenAPI: + +```JSON hl_lines="4-16" +{ + "components": { + "schemas": { + "Message": { + "title": "Message", + "required": [ + "message" + ], + "type": "object", + "properties": { + "message": { + "title": "Message", + "type": "string" + } + } + }, + "Item": { + "title": "Item", + "required": [ + "id", + "value" + ], + "type": "object", + "properties": { + "id": { + "title": "Id", + "type": "string" + }, + "value": { + "title": "Value", + "type": "string" + } + } + }, + "ValidationError": { + "title": "ValidationError", + "required": [ + "loc", + "msg", + "type" + ], + "type": "object", + "properties": { + "loc": { + "title": "Location", + "type": "array", + "items": { + "type": "string" + } + }, + "msg": { + "title": "Message", + "type": "string" + }, + "type": { + "title": "Error Type", + "type": "string" + } + } + }, + "HTTPValidationError": { + "title": "HTTPValidationError", + "type": "object", + "properties": { + "detail": { + "title": "Detail", + "type": "array", + "items": { + "$ref": "#/components/schemas/ValidationError" + } + } + } + } + } + } +} +``` + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž Đ´ĐģŅ ĐžŅĐŊОвĐŊĐžĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° { #additional-media-types-for-the-main-response } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐļĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `responses`, Ņ‡Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž Đ´ĐģŅ Ņ‚ĐžĐŗĐž ĐļĐĩ ĐžŅĐŊОвĐŊĐžĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž `image/png`, ĐžĐąŅŠŅĐ˛Đ¸Đ˛, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐ° ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸ ĐŧĐžĐļĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ JSONâ€‘ĐžĐąŅŠĐĩĐēŅ‚ (ҁ Ņ‚Đ¸ĐŋĐžĐŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž `application/json`) иĐģи PNGâ€‘Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиĐĩ: + +{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *} + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +ĐŖŅ‡Ņ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиĐĩ ĐŊ҃ĐļĐŊĐž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `FileResponse`. + +/// + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +Đ•ŅĐģи Đ˛Ņ‹ ŅĐ˛ĐŊĐž ĐŊĐĩ ҃ĐēаĐļĐĩŅ‚Đĩ Đ´Ņ€ŅƒĐŗĐžĐš Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂ҀĐĩ `responses`, FastAPI ĐąŅƒĐ´ĐĩŅ‚ ŅŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ĐžŅ‚Đ˛ĐĩŅ‚ иĐŧĐĩĐĩŅ‚ Ņ‚ĐžŅ‚ ĐļĐĩ Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, Ņ‡Ņ‚Đž и ĐžŅĐŊОвĐŊОК ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° (ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ `application/json`). + +Но ĐĩҁĐģи Đ˛Ņ‹ ҃ĐēаСаĐģи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ҁ `None` в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐĩĐŗĐž Ņ‚Đ¸Đŋа ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ `application/json` Đ´ĐģŅ ĐģŅŽĐąĐžĐŗĐž Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ°, ҃ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ĐĩŅŅ‚ŅŒ ŅĐ˛ŅĐˇĐ°ĐŊĐŊĐ°Ņ ĐŧОдĐĩĐģҌ. + +/// + +## КоĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Đ¸ { #combining-information } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Ой ĐžŅ‚Đ˛ĐĩŅ‚Đ°Ņ… иС ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŧĐĩҁ҂, вĐēĐģŅŽŅ‡Đ°Ņ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ `response_model`, `status_code` и `responses`. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ `response_model`, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ `200` (иĐģи ŅĐ˛ĐžĐš, ĐĩҁĐģи ĐŊ҃ĐļĐŊĐž), а ĐˇĐ°Ņ‚ĐĩĐŧ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐļĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ° в `responses`, ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в ҁ҅ĐĩĐŧĐĩ OpenAPI. + +**FastAPI** ŅĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ иС `responses` и ĐžĐąŅŠĐĩдиĐŊĐ¸Ņ‚ ĐĩŅ‘ ҁ JSONâ€‘ŅŅ…ĐĩĐŧОК иС Đ˛Đ°ŅˆĐĩĐš ĐŧОдĐĩĐģи. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚ ŅĐž ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдОĐŧ `404`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Pydantic-ĐŧОдĐĩĐģҌ и иĐŧĐĩĐĩŅ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐĩ `description`. + +А Ņ‚Đ°ĐēĐļĐĩ ĐžŅ‚Đ˛ĐĩŅ‚ ŅĐž ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдОĐŧ `200`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đ˛Đ°Ņˆ `response_model`, ĐŊĐž вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК `example`: + +{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *} + +Đ’ŅŅ‘ ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅŠĐĩдиĐŊĐĩĐŊĐž и вĐēĐģŅŽŅ‡ĐĩĐŊĐž в Đ˛Đ°Ņˆ OpenAPI и ĐžŅ‚ĐžĐąŅ€Đ°ĐļĐĩĐŊĐž в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API: + + + +## КоĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€ĐĩĐ´ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ и ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ { #combine-predefined-responses-and-custom-ones } + +ВозĐŧĐžĐļĐŊĐž, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€ĐĩĐ´ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ, ĐŋŅ€Đ¸ĐŧĐĩĐŊиĐŧŅ‹Đĩ ĐēĐž ĐŧĐŊĐžĐŗĐ¸Đŧ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧ ĐŋŅƒŅ‚Đ¸, ĐŊĐž ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… ҁ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐŧи ĐžŅ‚Đ˛ĐĩŅ‚Đ°Đŧи, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đŧи Đ´ĐģŅ ĐēаĐļдОК ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸. + +В Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸Ņ‘Đŧ Python ÂĢŅ€Đ°ŅĐŋаĐēОвĐēиÂģ `dict` ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `**dict_to_unpack`: + +```Python +old_dict = { + "old key": "old value", + "second old key": "second old value", +} +new_dict = {**old_dict, "new key": "new value"} +``` + +ЗдĐĩҁҌ `new_dict` ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐŋĐ°Ņ€Ņ‹ ĐēĐģŅŽŅ‡-СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ иС `old_dict` ĐŋĐģŅŽŅ ĐŊĐžĐ˛ŅƒŅŽ ĐŋĐ°Ņ€Ņƒ ĐēĐģŅŽŅ‡-СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ: + +```Python +{ + "old key": "old value", + "second old key": "second old value", + "new key": "new value", +} +``` + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐŋŅ€Đ¸Ņ‘Đŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€ĐĩĐ´ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ в Đ˛Đ°ŅˆĐ¸Ņ… ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŅ… ĐŋŅƒŅ‚Đ¸ и ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… ҁ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐŧи. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *} + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Ой ĐžŅ‚Đ˛ĐĩŅ‚Đ°Ņ… OpenAPI { #more-information-about-openapi-responses } + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž иĐŧĐĩĐŊĐŊĐž ĐŧĐžĐļĐŊĐž вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ в ĐžŅ‚Đ˛Đĩ҂ҋ, ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ŅŅ‚Đ¸ Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‹ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ OpenAPI: + +* ĐžĐąŅŠĐĩĐēŅ‚ Responses OpenAPI, ĐžĐŊ вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ `Response Object`. +* ĐžĐąŅŠĐĩĐēŅ‚ Response OpenAPI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ вĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Đ˛ŅŅ‘ иС ŅŅ‚ĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ° ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в ĐēаĐļĐ´Ņ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚ вĐŊŅƒŅ‚Ņ€Đ¸ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `responses`. ВĐēĐģŅŽŅ‡Đ°Ņ `description`, `headers`, `content` (вĐŊŅƒŅ‚Ņ€Đ¸ ĐŊĐĩĐŗĐž Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ Ņ€Đ°ĐˇĐŊŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž и JSONâ€‘ŅŅ…ĐĩĐŧŅ‹) и `links`. diff --git a/docs/ru/docs/advanced/additional-status-codes.md b/docs/ru/docs/advanced/additional-status-codes.md index aab1f8ee3..7c73cf5d5 100644 --- a/docs/ru/docs/advanced/additional-status-codes.md +++ b/docs/ru/docs/advanced/additional-status-codes.md @@ -1,28 +1,28 @@ -# ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅŅ‚Đ°Ņ‚ŅƒŅ ĐēĐžĐ´Ņ‹ +# ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēĐžĐ´Ņ‹ { #additional-status-codes } -По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ **FastAPI** Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐžŅ‚Đ˛Đĩ҂ҋ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `JSONResponse`, ĐŋĐžĐŧĐĩŅ‰Đ°Ņ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ иС Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, вĐŊŅƒŅ‚Ņ€ŅŒ ŅŅ‚ĐžĐŗĐž `JSONResponse`. +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ **FastAPI** ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ĐžŅ‚Đ˛Đĩ҂ҋ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `JSONResponse`, ĐŋĐžĐŧĐĩŅ‰Đ°Ņ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ иС Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, вĐŊŅƒŅ‚Ņ€ŅŒ ŅŅ‚ĐžĐŗĐž `JSONResponse`. -ОĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēОд ŅŅ‚Đ°Ņ‚ŅƒŅĐ° ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ иĐģи Ņ‚ĐžŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ҃ĐēаĐļĐĩŅ‚Đĩ в Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. +ОĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ иĐģи Ņ‚ĐžŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ҃ĐēаĐļĐĩŅ‚Đĩ в Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. -## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅŅ‚Đ°Ņ‚ŅƒŅ ĐēĐžĐ´Ņ‹ +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēĐžĐ´Ņ‹ { #additional-status-codes_1 } -Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ŅŅ‚Đ°Ņ‚ŅƒŅ ĐēОд ĐŋĐžĐŧиĐŧĐž ĐžŅĐŊОвĐŊĐžĐŗĐž, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ ĐžĐąŅŠĐĩĐēŅ‚ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐēаĐē `JSONResponse`, и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ ĐŊ҃ĐļĐŊŅ‹Đš ŅŅ‚Đ°Ņ‚ŅƒŅ ĐēОд ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. +Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēĐžĐ´Ņ‹ ĐŋĐžĐŧиĐŧĐž ĐžŅĐŊОвĐŊĐžĐŗĐž, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `JSONResponse`, и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. -НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҁĐēаĐļĐĩĐŧ, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋОСвОĐģŅĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ŅĐģĐĩĐŧĐĩĐŊ҂ҋ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ HTTP-ĐēОд 200 "OK" ĐŋŅ€Đ¸ ҃ҁĐŋĐĩ҈ĐŊĐžĐŧ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊии. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐžĐļиĐŧ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋОСвОĐģŅĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ŅĐģĐĩĐŧĐĩĐŊ҂ҋ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ HTTP ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд 200 ÂĢOKÂģ ĐŋŅ€Đ¸ ҃ҁĐŋĐĩ҈ĐŊĐžĐŧ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊии. -Но Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊа ĐŋŅ€Đ¸ĐŊиĐŧаĐģа ĐŊĐžĐ˛Ņ‹Đĩ ŅĐģĐĩĐŧĐĩĐŊ҂ҋ. И ĐĩҁĐģи ŅĐģĐĩĐŧĐĩĐŊŅ‚ Ņ€Đ°ĐŊĐĩĐĩ ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģ, ĐžĐŊ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ŅŅ, и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐģŅŅ HTTP-ĐēОд 201 "Created". +Но Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊа ĐŋŅ€Đ¸ĐŊиĐŧаĐģа ĐŊĐžĐ˛Ņ‹Đĩ ŅĐģĐĩĐŧĐĩĐŊ҂ҋ. И ĐĩҁĐģи ŅĐģĐĩĐŧĐĩĐŊ҂ҋ Ņ€Đ°ĐŊĐĩĐĩ ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģи, ĐžĐŊа ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ Đ¸Ņ… и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ HTTP ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд 201 ÂĢCreatedÂģ. -Đ§Ņ‚ĐžĐąŅ‹ Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž, иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `JSONResponse` и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐšŅ‚Đĩ Đ˛Đ°Ņˆ ĐēĐžĐŊŅ‚ĐĩĐŊŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ ĐŊ҃ĐļĐŊŅ‹Đš `status_code`: +Đ§Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ŅŅ‚ĐžĐŗĐž, иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `JSONResponse` и вĐĩŅ€ĐŊĐ¸Ņ‚Đĩ Ņ‚ŅƒĐ´Đ° ŅĐ˛ĐžĐš ĐēĐžĐŊŅ‚ĐĩĐŊŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ŅƒŅŅ‚Đ°ĐŊОвив ĐŊ҃ĐļĐŊŅ‹Đš ваĐŧ `status_code`: {* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *} /// warning | ВĐŊиĐŧаĐŊиĐĩ -ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐēаĐē в ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ Đ˛Ņ‹ŅˆĐĩ, ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊ ĐēаĐē ĐĩŅŅ‚ŅŒ. +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐēаĐē в ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ Đ˛Ņ‹ŅˆĐĩ, ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊ ĐēаĐē ĐĩŅŅ‚ŅŒ. -ОĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ҁĐĩŅ€Đ¸Đ°ĐģиСОваĐŊ ĐŋŅ€Đ¸ ĐŋĐžĐŧĐžŅ‰Đ¸ ĐŧОдĐĩĐģи и Ņ‚.Đ´. +ОĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ҁĐĩŅ€Đ¸Đ°ĐģиСОваĐŊ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŧОдĐĩĐģи и Ņ‚.Đŋ. -ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž в ĐŊŅ‘Đŧ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŅ иĐŧĐĩĐŊĐŊĐž Ņ‚Đĩ даĐŊĐŊŅ‹Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, и Ņ‡Ņ‚Đž СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ŅĐ˛ĐģŅŅŽŅ‚ŅŅ ваĐģидĐŊŅ‹Đŧ JSON (ĐĩҁĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ `JSONResponse`). +ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž в ĐŊŅ‘Đŧ иĐŧĐĩĐŊĐŊĐž Ņ‚Đĩ даĐŊĐŊŅ‹Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, и Ņ‡Ņ‚Đž СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ŅĐ˛ĐģŅŅŽŅ‚ŅŅ ваĐģидĐŊŅ‹Đŧ JSON (ĐĩҁĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ `JSONResponse`). /// @@ -30,12 +30,12 @@ Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.responses import JSONResponse`. -**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚ĐžŅ‚ ĐļĐĩ `starlette.responses` ҇ĐĩŅ€ĐĩС `fastapi.responses` ĐŋŅ€ĐžŅŅ‚Đž Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ°, ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. Но йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ Response-ĐēĐģĐ°ŅŅĐžĐ˛ ĐŋĐžŅŅ‚ŅƒĐŋĐ°ŅŽŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС Starlette. ĐĸĐž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ ĐēĐ°ŅĐ°ĐĩŅ‚ŅŅ и `status`. +**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚ĐžŅ‚ ĐļĐĩ `starlette.responses` ҇ĐĩŅ€ĐĩС `fastapi.responses` ĐŋŅ€ĐžŅŅ‚Đž Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ° ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. Но йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ Response-ĐēĐģĐ°ŅŅĐžĐ˛ ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС Starlette. ĐĸĐž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ ŅĐž `status`. /// -## OpenAPI и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API +## OpenAPI и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API { #openapi-and-api-docs } -Đ•ŅĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐēĐžĐ´Ņ‹ ŅŅ‚Đ°Ņ‚ŅƒŅĐžĐ˛ и ĐžŅ‚Đ˛Đĩ҂ҋ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐžĐŊи ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ вĐēĐģŅŽŅ‡ĐĩĐŊŅ‹ в ҁ҅ĐĩĐŧ҃ OpenAPI (Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API), ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž FastAPI ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐˇĐ°Ņ€Đ°ĐŊĐĩĐĩ СĐŊĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ŅĐžĐąĐ¸Ņ€Đ°ĐĩŅ‚ĐĩҁҌ вĐĩŅ€ĐŊŅƒŅ‚ŅŒ. +Đ•ŅĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēĐžĐ´Ņ‹ и ĐžŅ‚Đ˛Đĩ҂ҋ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐžĐŊи ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ вĐēĐģŅŽŅ‡ĐĩĐŊŅ‹ в ҁ҅ĐĩĐŧ҃ OpenAPI (Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API), ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ҃ FastAPI ĐŊĐĩŅ‚ ҁĐŋĐžŅĐžĐąĐ° ĐˇĐ°Ņ€Đ°ĐŊĐĩĐĩ СĐŊĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ŅĐžĐąĐ¸Ņ€Đ°ĐĩŅ‚ĐĩҁҌ вĐĩŅ€ĐŊŅƒŅ‚ŅŒ. -Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ: [ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ в OpenAPI](additional-responses.md){.internal-link target=_blank}. +Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž в ŅĐ˛ĐžŅ‘Đŧ ĐēОдĐĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ: [ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ](additional-responses.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/advanced-dependencies.md b/docs/ru/docs/advanced/advanced-dependencies.md new file mode 100644 index 000000000..75a6f0d1f --- /dev/null +++ b/docs/ru/docs/advanced/advanced-dependencies.md @@ -0,0 +1,153 @@ +# ĐŸŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Ņ‹Đĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ { #advanced-dependencies } + +## ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ĐˇĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ { #parameterized-dependencies } + +Đ’ŅĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧŅ‹ видĐĩĐģи, — ŅŅ‚Đž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ иĐģи ĐēĐģĐ°ŅŅ. + +Но ĐąŅ‹Đ˛Đ°ŅŽŅ‚ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° ĐŊ҃ĐļĐŊĐž ĐˇĐ°Đ´Đ°Đ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, ĐŊĐĩ ĐžĐąŅŠŅĐ˛ĐģŅŅ ĐŧĐŊĐžĐŗĐž Ņ€Đ°ĐˇĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš иĐģи ĐēĐģĐ°ŅŅĐžĐ˛. + +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž ĐŊаĐŧ ĐŊ҃ĐļĐŊа ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚, ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ Đģи query-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `q` ĐŊĐĩĐēĐžŅ‚ĐžŅ€ĐžĐĩ Ņ„Đ¸ĐēŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ. + +Но ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐŧŅ‹ Ņ…ĐžŅ‚Đ¸Đŧ иĐŧĐĩŅ‚ŅŒ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž Ņ„Đ¸ĐēŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ. + +## ÂĢĐ’Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧŅ‹ĐšÂģ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ { #a-callable-instance } + +В Python ĐĩŅŅ‚ŅŒ ҁĐŋĐžŅĐžĐą ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ĐēĐģĐ°ŅŅĐ° ÂĢĐ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧŅ‹ĐŧÂģ ĐžĐąŅŠĐĩĐēŅ‚ĐžĐŧ. + +НĐĩ ŅĐ°Đŧ ĐēĐģĐ°ŅŅ (ĐžĐŊ ҃ĐļĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧŅ‹Đŧ), а ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ŅŅ‚ĐžĐŗĐž ĐēĐģĐ°ŅŅĐ°. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ĐŧĐĩŅ‚ĐžĐ´ `__call__`: + +{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *} + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ иĐŧĐĩĐŊĐŊĐž `__call__` **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ и ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, и иĐŧĐĩĐŊĐŊĐž ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐˇĐ˛Đ°ĐŊ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋОСĐļĐĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Ņƒ в Đ˛Đ°ŅˆĐĩĐš *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸*. + +## ĐŸĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ĐˇŅƒĐĩĐŧ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ { #parameterize-the-instance } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `__init__`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ŅĐēСĐĩĐŧĐŋĐģŅŅ€Đ°, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐąŅƒĐ´ĐĩĐŧ ÂĢĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒÂģ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ: + +{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *} + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ **FastAPI** Đ˛ĐžĐ˛ŅĐĩ ĐŊĐĩ Ņ‚Ņ€ĐžĐŗĐ°ĐĩŅ‚ `__init__` и ĐŊĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ ĐŊĐĩĐŗĐž — ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ĐĩĐŗĐž ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в ĐŊĐ°ŅˆĐĩĐŧ ĐēОдĐĩ. + +## ĐĄĐžĐˇĐ´Đ°Ņ‘Đŧ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ { #create-an-instance } + +ĐœŅ‹ ĐŧĐžĐļĐĩĐŧ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ŅŅ‚ĐžĐŗĐž ĐēĐģĐ°ŅŅĐ° Ņ‚Đ°Đē: + +{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *} + +ĐĸаĐē ĐŧŅ‹ ÂĢĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ¸ĐˇŅƒĐĩĐŧÂģ ĐŊĐ°ŅˆŅƒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ: Ņ‚ĐĩĐŋĐĩŅ€ŅŒ вĐŊŅƒŅ‚Ņ€Đ¸ ĐŊĐĩŅ‘ Ņ…Ņ€Đ°ĐŊĐ¸Ņ‚ŅŅ "bar" в Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Đĩ `checker.fixed_content`. + +## Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ĐēаĐē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ { #use-the-instance-as-a-dependency } + +Đ—Đ°Ņ‚ĐĩĐŧ ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ `checker` в `Depends(checker)` вĐŧĐĩŅŅ‚Đž `Depends(FixedContentQueryChecker)`, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒŅŽ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ `checker`, а ĐŊĐĩ ŅĐ°Đŧ ĐēĐģĐ°ŅŅ. + +И ĐŋŅ€Đ¸ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊии ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ **FastAPI** Đ˛Ņ‹ĐˇĐžĐ˛ĐĩŅ‚ `checker` ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž Ņ‚Đ°Đē: + +```Python +checker(q="somequery") +``` + +â€Ļи ĐŋĐĩŅ€ĐĩĐ´Đ°ŅŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊĐŊĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐēаĐē СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ в ĐŊĐ°ŅˆŅƒ *Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸* в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `fixed_content_included`: + +{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *} + +/// tip | ХОвĐĩŅ‚ + +Đ’ŅĐĩ ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸Ņ‚ŅĐŊŅƒŅ‚Ņ‹Đŧ Са ŅƒŅˆĐ¸. И ĐŋĐžĐēа ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŊĐĩ ŅĐžĐ˛ŅĐĩĐŧ ĐŋĐžĐŊŅŅ‚ĐŊĐž, ҇ĐĩĐŧ ŅŅ‚Đž ĐŋĐžĐģĐĩСĐŊĐž. + +Đ­Ņ‚Đ¸ ĐŋŅ€Đ¸ĐŧĐĩҀҋ ĐŊаĐŧĐĩŅ€ĐĩĐŊĐŊĐž ĐŋŅ€ĐžŅŅ‚Ņ‹Đĩ, ĐŊĐž ĐžĐŊи ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚, ĐēаĐē Đ˛ŅŅ‘ ŅƒŅŅ‚Ņ€ĐžĐĩĐŊĐž. + +В ĐŗĐģĐ°Đ˛Đ°Ņ… ĐŋŅ€Đž ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ ĐĩŅŅ‚ŅŒ Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, Ņ€ĐĩаĐģиСОваĐŊĐŊŅ‹Đĩ Ņ‚ĐĩĐŧ ĐļĐĩ ҁĐŋĐžŅĐžĐąĐžĐŧ. + +Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐžĐŊŅĐģи Đ˛ŅŅ‘ Đ˛Ņ‹ŅˆĐĩ, Đ˛Ņ‹ ҃ĐļĐĩ СĐŊаĐĩŅ‚Đĩ, ĐēаĐē ÂĢĐŋОд ĐēаĐŋĐžŅ‚ĐžĐŧÂģ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ ŅŅ‚Đ¸ ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ Đ´ĐģŅ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸. + +/// + +## Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield`, `HTTPException`, `except` и Ņ„ĐžĐŊĐžĐ˛Ņ‹Đŧи ĐˇĐ°Đ´Đ°Ņ‡Đ°Đŧи { #dependencies-with-yield-httpexception-except-and-background-tasks } + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ваĐŧ ĐŊĐĩ ĐŋĐžĐŊĐ°Đ´ĐžĐąŅŅ‚ŅŅ ŅŅ‚Đ¸ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи. + +ОĐŊи ĐŋĐžĐģĐĩСĐŊŅ‹ ĐŗĐģавĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐĩҁĐģи ҃ Đ˛Đ°Ņ ĐąŅ‹ĐģĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI вĐĩŅ€ŅĐ¸Đ¸ ĐŊиĐļĐĩ 0.118.0 и Đ˛Ņ‹ ŅŅ‚ĐžĐģĐēĐŊ҃ĐģĐ¸ŅŅŒ ҁ ĐŋŅ€ĐžĐąĐģĐĩĐŧаĐŧи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ҁ `yield`. + +/// + +Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield` ŅĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊĐĩĐŧ иСĐŧĐĩĐŊŅĐģĐ¸ŅŅŒ, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ ҁĐģŅƒŅ‡Đ°Đ¸ ĐŋŅ€Đ¸ĐŧĐĩĐŊĐĩĐŊĐ¸Ņ и Đ¸ŅĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. НиĐļĐĩ — ĐēŅ€Đ°Ņ‚ĐēĐžĐĩ Ņ€ĐĩĐˇŅŽĐŧĐĩ иСĐŧĐĩĐŊĐĩĐŊиК. + +### Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield` и `StreamingResponse`, Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи { #dependencies-with-yield-and-streamingresponse-technical-details } + +До FastAPI 0.118.0, ĐĩҁĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ ҁ `yield`, ĐēОд ĐŋĐžŅĐģĐĩ `yield` Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģŅŅ ĐŋĐžŅĐģĐĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‚Đ° иС *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸*, ĐŊĐž ĐŋŅ€ŅĐŧĐž ĐŋĐĩŅ€ĐĩĐ´ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐēОК ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +ИдĐĩŅ ŅĐžŅŅ‚ĐžŅĐģа в Ņ‚ĐžĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊĐĩ ŅƒĐ´ĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ Ņ€ĐĩŅŅƒŅ€ŅŅ‹ Đ´ĐžĐģҌ҈Đĩ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžĐŗĐž, ĐŋĐžĐēа ĐžŅ‚Đ˛ĐĩŅ‚ ÂĢĐŋŅƒŅ‚Đĩ҈ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚Âģ ĐŋĐž ҁĐĩŅ‚Đ¸. + +Đ­Ņ‚Đž иСĐŧĐĩĐŊĐĩĐŊиĐĩ Ņ‚Đ°ĐēĐļĐĩ ОСĐŊĐ°Ņ‡Đ°ĐģĐž, Ņ‡Ņ‚Đž ĐĩҁĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Đģи `StreamingResponse`, ĐēОд ĐŋĐžŅĐģĐĩ `yield` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҃ĐļĐĩ ҃ҁĐŋĐĩваĐģ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒŅŅ. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ҃ Đ˛Đ°Ņ ĐąŅ‹Đģа ҁĐĩŅŅĐ¸Ņ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield`, `StreamingResponse` ĐŊĐĩ ҁĐŧĐžĐŗ ĐąŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ ҁĐĩŅŅĐ¸ŅŽ вО Đ˛Ņ€ĐĩĐŧŅ ŅŅ‚Ņ€Đ¸ĐŧиĐŊĐŗĐ° даĐŊĐŊҋ҅, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ҁĐĩŅŅĐ¸Ņ ҃ĐļĐĩ ĐąŅ‹Đģа СаĐēŅ€Ņ‹Ņ‚Đ° в ĐēОдĐĩ ĐŋĐžŅĐģĐĩ `yield`. + +В вĐĩŅ€ŅĐ¸Đ¸ 0.118.0 ŅŅ‚Đž ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ ĐąŅ‹ĐģĐž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊĐž Đē Ņ‚ĐžĐŧ҃, Ņ‡Ņ‚Đž ĐēОд ĐŋĐžŅĐģĐĩ `yield` Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ ĐŋĐžŅĐģĐĩ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēи ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +КаĐē Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐŊиĐļĐĩ, ŅŅ‚Đž ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ Đ´Đž вĐĩŅ€ŅĐ¸Đ¸ 0.106.0, ĐŊĐž ҁ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ҃ĐģŅƒŅ‡ŅˆĐĩĐŊĐ¸ŅĐŧи и Đ¸ŅĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸ŅĐŧи ĐēŅ€Đ°ĐĩĐ˛Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°Đĩв. + +/// + +#### ĐĄŅ†ĐĩĐŊĐ°Ņ€Đ¸Đ¸ ҁ Ņ€Đ°ĐŊĐŊиĐŧ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩĐŧ ĐēОда ĐŋĐžŅĐģĐĩ `yield` { #use-cases-with-early-exit-code } + +Đ•ŅŅ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸ ŅĐž ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐĩҁĐēиĐŧи ҃ҁĐģĐžĐ˛Đ¸ŅĐŧи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ ĐŧĐžĐŗĐģĐž ĐąŅ‹ ĐŋĐžĐŧĐžŅ‡ŅŒ ŅŅ‚Đ°Ņ€ĐžĐĩ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ — Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ ĐēОда ĐŋĐžŅĐģĐĩ `yield` ĐŋĐĩŅ€ĐĩĐ´ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐēОК ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ҁĐĩŅŅĐ¸ŅŽ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield` Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ, а в ŅĐ°ĐŧОК *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸* ŅŅ‚Đ° ҁĐĩŅŅĐ¸Ņ йОĐģҌ҈Đĩ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ, и ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐžŅ‚Đ˛ĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ Đ´ĐžĐģĐŗĐž, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅŅ‚Đž `StreamingResponse`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐĩĐ´ĐģĐĩĐŊĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ даĐŊĐŊŅ‹Đĩ и ĐŋĐž ĐēаĐēОК-Ņ‚Đž ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊĐĩ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅. + +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ҁĐĩŅŅĐ¸Ņ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ ĐąŅƒĐ´ĐĩŅ‚ ŅƒĐ´ĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒŅŅ Đ´Đž СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēи ĐžŅ‚Đ˛ĐĩŅ‚Đ°, Ņ…ĐžŅ‚Ņ ĐĩҁĐģи Đ˛Ņ‹ ĐĩŅ‘ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ, ŅƒĐ´ĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐĩŅ‘ ĐŊĐĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ. + +Đ­Ņ‚Đž ĐŧĐžĐŗĐģĐž ĐąŅ‹ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py *} + +Код ĐŋĐžŅĐģĐĩ `yield`, Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ СаĐēŅ€Ņ‹Ņ‚Đ¸Đĩ `Session` в: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *} + +â€ĻĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊ ĐŋĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž, ĐēаĐē ĐžŅ‚Đ˛ĐĩŅ‚ СаĐēĐžĐŊŅ‡Đ¸Ņ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đē҃ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊҋ҅ даĐŊĐŊҋ҅: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *} + +Но ĐŋĐžŅĐēĐžĐģҌĐē҃ `generate_stream()` ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ҁĐĩŅŅĐ¸ŅŽ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅, ĐŊĐĩŅ‚ Ņ€ĐĩаĐģҌĐŊОК ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ Đ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ҁĐĩŅŅĐ¸ŅŽ ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ĐžĐš вО Đ˛Ņ€ĐĩĐŧŅ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēи ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +Đ•ŅĐģи ҃ Đ˛Đ°Ņ иĐŧĐĩĐŊĐŊĐž Ņ‚Đ°ĐēОК ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đš ҁ SQLModel (иĐģи SQLAlchemy), Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ˛ĐŊĐž СаĐēŅ€Ņ‹Ņ‚ŅŒ ҁĐĩŅŅĐ¸ŅŽ, ĐēĐžĐŗĐ´Đ° ĐžĐŊа йОĐģҌ҈Đĩ ĐŊĐĩ ĐŊ҃ĐļĐŊа: + +{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *} + +ĐĸаĐē ҁĐĩŅŅĐ¸Ņ ĐžŅĐ˛ĐžĐąĐžĐ´Đ¸Ņ‚ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ Đē йаСĐĩ даĐŊĐŊҋ҅, и Đ´Ņ€ŅƒĐŗĐ¸Đĩ СаĐŋŅ€ĐžŅŅ‹ ҁĐŧĐžĐŗŅƒŅ‚ ĐĩĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ. + +Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đš, ĐŗĐ´Đĩ ĐŊ҃ĐļĐŊĐž Ņ€Đ°ĐŊĐŊĐĩĐĩ СавĐĩŅ€ŅˆĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield`, ĐŋĐžĐļаĐģŅƒĐšŅŅ‚Đ°, ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ вОĐŋŅ€ĐžŅ в GitHub Discussions ҁ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩĐŧ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž ĐēĐĩĐšŅĐ° и ĐŋĐžŅ‡ĐĩĐŧ҃ ваĐŧ ĐąŅ‹ĐģĐž ĐąŅ‹ ĐŋĐžĐģĐĩСĐŊĐž иĐŧĐĩŅ‚ŅŒ Ņ€Đ°ĐŊĐŊĐĩĐĩ СаĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Đ´ĐģŅ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ҁ `yield`. + +Đ•ŅĐģи ĐŋĐžŅĐ˛ŅŅ‚ŅŅ вĐĩҁĐēиĐĩ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊŅ‹ Đ´ĐģŅ Ņ€Đ°ĐŊĐŊĐĩĐŗĐž СаĐēŅ€Ņ‹Ņ‚Đ¸Ņ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… ҁ `yield`, Ņ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€ŅŽ дОйавĐģĐĩĐŊиĐĩ ĐŊĐžĐ˛ĐžĐŗĐž ҁĐŋĐžŅĐžĐąĐ° ĐžĐŋŅ†Đ¸ĐžĐŊаĐģҌĐŊĐž вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ Ņ€Đ°ĐŊĐŊĐĩĐĩ СаĐēŅ€Ņ‹Ņ‚Đ¸Đĩ. + +### Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield` и `except`, Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи { #dependencies-with-yield-and-except-technical-details } + +До FastAPI 0.110.0, ĐĩҁĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ ҁ `yield`, ĐˇĐ°Ņ‚ĐĩĐŧ ĐŋĐĩŅ€ĐĩŅ…Đ˛Đ°Ņ‚Ņ‹Đ˛Đ°Đģи Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ ҁ `except` в ŅŅ‚ĐžĐš ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ и ĐŊĐĩ ĐŋŅ€ĐžĐąŅ€Đ°ŅŅ‹Đ˛Đ°Đģи Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ ҁĐŊОва, Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€ĐžĐąŅ€Đ°ŅŅ‹Đ˛Đ°ĐģĐžŅŅŒ даĐģҌ҈Đĩ Đē ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК иĐģи Đē ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē҃ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐš ĐžŅˆĐ¸ĐąĐēи ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. + +В вĐĩŅ€ŅĐ¸Đ¸ 0.110.0 ŅŅ‚Đž ĐąŅ‹ĐģĐž иСĐŧĐĩĐŊĐĩĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ Đ¸ŅĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŊĐĩĐēĐžĐŊŅ‚Ņ€ĐžĐģĐ¸Ņ€ŅƒĐĩĐŧĐžĐĩ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚Đ¸ из‑за ĐŋŅ€ĐžĐąŅ€ĐžŅˆĐĩĐŊĐŊҋ҅ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК ĐąĐĩС ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа (вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ ĐžŅˆĐ¸ĐąĐēи ҁĐĩŅ€Đ˛ĐĩŅ€Đ°) и ĐŋŅ€Đ¸Đ˛ĐĩŅŅ‚Đ¸ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đĩ ҁ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩĐŧ Python-ĐēОда. + +### ФОĐŊĐžĐ˛Ņ‹Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ и ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield`, Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи { #background-tasks-and-dependencies-with-yield-technical-details } + +До FastAPI 0.106.0 Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ĐŋĐžŅĐģĐĩ `yield` ĐąŅ‹ĐģĐž ĐŊĐĩвОСĐŧĐžĐļĐŊĐž: ĐēОд ĐŋĐžŅĐģĐĩ `yield` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģŅŅ ҃ĐļĐĩ ĐŋĐžŅĐģĐĩ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēи ĐžŅ‚Đ˛ĐĩŅ‚Đ°, ĐŋĐžŅŅ‚ĐžĐŧ҃ [ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} Đē Ņ‚ĐžĐŧ҃ ĐŧĐžĐŧĐĩĐŊŅ‚Ņƒ ҃ĐļĐĩ ĐžŅ‚Ņ€Đ°ĐąĐžŅ‚Đ°Đģи. + +ĐĸаĐē ĐąŅ‹ĐģĐž ŅĐ´ĐĩĐģаĐŊĐž в ĐžŅĐŊОвĐŊĐžĐŧ Đ´ĐģŅ Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŧĐžĐļĐŊĐž ĐąŅ‹ĐģĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đĩ ĐļĐĩ ĐžĐąŅŠĐĩĐē҂ҋ, ÂĢĐžŅ‚Đ´Đ°ĐŊĐŊŅ‹ĐĩÂģ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи ҇ĐĩŅ€ĐĩС `yield`, вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ĐžĐŊĐžĐ˛Ņ‹Ņ… ĐˇĐ°Đ´Đ°Ņ‡, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēОд ĐŋĐžŅĐģĐĩ `yield` Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģŅŅ ĐŋĐžŅĐģĐĩ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ„ĐžĐŊĐžĐ˛Ņ‹Ņ… ĐˇĐ°Đ´Đ°Ņ‡. + +В FastAPI 0.106.0 ŅŅ‚Đž иСĐŧĐĩĐŊиĐģи, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊĐĩ ŅƒĐ´ĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ Ņ€ĐĩŅŅƒŅ€ŅŅ‹, ĐŋĐžĐēа ĐžŅ‚Đ˛ĐĩŅ‚ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ŅŅ ĐŋĐž ҁĐĩŅ‚Đ¸. + +/// tip | ХОвĐĩŅ‚ + +ĐšŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž, Ņ„ĐžĐŊĐžĐ˛Đ°Ņ ĐˇĐ°Đ´Đ°Ņ‡Đ° ĐžĐąŅ‹Ņ‡ĐŊĐž — ŅŅ‚Đž ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊŅ‹Đš Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ ĐģĐžĐŗĐ¸Đēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐžŅ‚Đ´ĐĩĐģҌĐŊĐž, ŅĐž ŅĐ˛ĐžĐ¸Đŧи Ņ€ĐĩŅŅƒŅ€ŅĐ°Đŧи (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅĐž ŅĐ˛ĐžĐ¸Đŧ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊиĐĩĐŧ Đē йаСĐĩ даĐŊĐŊҋ҅). + +ĐĸаĐē ĐēОд, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐąŅƒĐ´ĐĩŅ‚ Ņ‡Đ¸Ņ‰Đĩ. + +/// + +Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐžĐģĐ°ĐŗĐ°ĐģĐ¸ŅŅŒ ĐŊа ĐŋŅ€ĐĩĐļĐŊĐĩĐĩ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ, Ņ‚ĐĩĐŋĐĩŅ€ŅŒ Ņ€ĐĩŅŅƒŅ€ŅŅ‹ Đ´ĐģŅ Ņ„ĐžĐŊĐžĐ˛Ņ‹Ņ… ĐˇĐ°Đ´Đ°Ņ‡ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ вĐŊŅƒŅ‚Ņ€Đ¸ ŅĐ°ĐŧОК Ņ„ĐžĐŊОвОК ĐˇĐ°Đ´Đ°Ņ‡Đ¸ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ вĐŊŅƒŅ‚Ņ€Đ¸ ĐŊĐĩŅ‘ Ņ‚ĐžĐģҌĐēĐž даĐŊĐŊŅ‹Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐĩ ĐˇĐ°Đ˛Đ¸ŅŅŅ‚ ĐžŅ‚ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ҁ `yield`. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, вĐŧĐĩŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ‚ĐžĐš ĐļĐĩ ҁĐĩŅŅĐ¸Đ¸ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅, ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŊĐžĐ˛ŅƒŅŽ ҁĐĩŅŅĐ¸ŅŽ в Ņ„ĐžĐŊОвОК ĐˇĐ°Đ´Đ°Ņ‡Đĩ и ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐžĐąŅŠĐĩĐē҂ҋ иС ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ŅŅ‚ĐžĐš ĐŊОвОК ҁĐĩŅŅĐ¸Đ¸. И ĐˇĐ°Ņ‚ĐĩĐŧ, вĐŧĐĩŅŅ‚Đž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ ĐžĐąŅŠĐĩĐēŅ‚Đ° иС ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐŧ в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ Ņ„ĐžĐŊОвОК ĐˇĐ°Đ´Đ°Ņ‡Đ¸, ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°ĐšŅ‚Đĩ идĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžŅ€ ŅŅ‚ĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ° и СаĐŊОвО ĐŋĐžĐģŅƒŅ‡Đ°ĐšŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Ņ„ĐžĐŊОвОК ĐˇĐ°Đ´Đ°Ņ‡Đ¸. diff --git a/docs/ru/docs/advanced/async-tests.md b/docs/ru/docs/advanced/async-tests.md index 7849ad109..5062bc52e 100644 --- a/docs/ru/docs/advanced/async-tests.md +++ b/docs/ru/docs/advanced/async-tests.md @@ -1,4 +1,4 @@ -# ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐĩ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ +# ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐĩ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ { #async-tests } Đ’Ņ‹ ҃ĐļĐĩ видĐĩĐģи ĐēаĐē Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ **FastAPI** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ иĐŧĐĩŅŽŅ‰Đ¸ĐšŅŅ ĐēĐģĐ°ŅŅ `TestClient`. К ŅŅ‚ĐžĐŧ҃ ĐŧĐžĐŧĐĩĐŊŅ‚Ņƒ Đ˛Ņ‹ видĐĩĐģи Ņ‚ĐžĐģҌĐēĐž ĐēаĐē ĐŋĐ¸ŅĐ°Ņ‚ŅŒ Ņ‚Đĩҁ҂ҋ в ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŧ ŅŅ‚Đ¸ĐģĐĩ ĐąĐĩС Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ `async` Ņ„ŅƒĐŊĐēŅ†Đ¸Đš. @@ -6,11 +6,11 @@ Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ŅŅ‚Đž Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ. -## pytest.mark.anyio +## pytest.mark.anyio { #pytest-mark-anyio } Đ•ŅĐģи ĐŧŅ‹ Ņ…ĐžŅ‚Đ¸Đŧ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ в ĐŊĐ°ŅˆĐ¸Ņ… Ņ‚ĐĩŅŅ‚Đ°Ņ…, Ņ‚Đž ĐŊĐ°ŅˆĐ¸ Ņ‚ĐĩŅŅ‚ĐžĐ˛Ņ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đŧи. AnyIO ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš ĐŋĐģĐ°ĐŗĐ¸ĐŊ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋОСвОĐģŅĐĩŅ‚ ĐŊаĐŧ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ, ĐēаĐēиĐĩ Ņ‚ĐĩŅŅ‚ĐžĐ˛Ņ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Đ´ĐžĐģĐļĐŊŅ‹ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒŅŅ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐž. -## HTTPX +## HTTPX { #httpx } ДаĐļĐĩ ĐĩҁĐģи **FastAPI** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ `def` вĐŧĐĩŅŅ‚Đž `async def`, ŅŅ‚Đž Đ˛ŅĐĩ Ņ€Đ°Đ˛ĐŊĐž `async` ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ 'ĐŋОд ĐēаĐŋĐžŅ‚ĐžĐŧ'. @@ -18,7 +18,7 @@ `TestClient` ĐžŅĐŊОваĐŊ ĐŊа HTTPX, и, Đē ŅŅ‡Đ°ŅŅ‚ŅŒŅŽ, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž (`HTTPX`) ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Đ´ĐģŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ API. -## ĐŸŅ€Đ¸ĐŧĐĩŅ€ +## ĐŸŅ€Đ¸ĐŧĐĩŅ€ { #example } В ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŋŅ€ĐžŅŅ‚ĐžĐŗĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°, Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ Ņ„Đ°ĐšĐģĐžĐ˛ŅƒŅŽ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņƒ, ŅŅ…ĐžĐļŅƒŅŽ ҁ ĐžĐŋĐ¸ŅĐ°ĐŊĐŊОК в [БоĐģŅŒŅˆĐ¸Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ](../tutorial/bigger-applications.md){.internal-link target=_blank} и [ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ](../tutorial/testing.md){.internal-link target=_blank}: @@ -38,7 +38,7 @@ {* ../../docs_src/async_tests/test_main.py *} -## ЗаĐŋ҃ҁĐē Ņ‚ĐĩŅŅ‚ĐžĐ˛ +## ЗаĐŋ҃ҁĐē Ņ‚ĐĩŅŅ‚ĐžĐ˛ { #run-it } Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ŅĐ˛ĐžĐ¸ Ņ‚Đĩҁ҂ҋ ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐž: @@ -52,7 +52,7 @@ $ pytest -## ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ +## ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ { #in-detail } ĐœĐ°Ņ€ĐēĐĩŅ€ `@pytest.mark.anyio` ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ pytest, Ņ‡Ņ‚Đž Ņ‚ĐĩŅŅ‚ĐžĐ˛Đ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ Đ´ĐžĐģĐļĐŊа ĐąŅ‹Ņ‚ŅŒ Đ˛Ņ‹ĐˇĐ˛Đ°ĐŊа Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐž: @@ -88,7 +88,7 @@ response = client.get('/') /// -## Đ’Ņ‹ĐˇĐžĐ˛ Đ´Ņ€ŅƒĐŗĐ¸Ņ… Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš +## Đ’Ņ‹ĐˇĐžĐ˛ Đ´Ņ€ŅƒĐŗĐ¸Ņ… Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš { #other-asynchronous-function-calls } ĐĸĐĩĐŋĐĩŅ€ŅŒ Ņ‚ĐĩŅŅ‚ĐžĐ˛Đ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ŅŅ‚Đ°Đģа Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊОК, ĐŋĐžŅŅ‚ĐžĐŧ҃ вĐŊŅƒŅ‚Ņ€Đ¸ ĐŊĐĩĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ Ņ‚Đ°ĐēĐļĐĩ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ `async` Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐŊĐĩ ŅĐ˛ŅĐˇĐ°ĐŊĐŊŅ‹Đĩ ҁ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ СаĐŋŅ€ĐžŅĐžĐ˛ в Đ˛Đ°ŅˆĐĩ FastAPI ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. КаĐē ĐĩҁĐģи ĐąŅ‹ Đ˛Ņ‹ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Đģи Đ¸Ņ… в ĐģŅŽĐąĐžĐŧ Đ´Ņ€ŅƒĐŗĐžĐŧ ĐŧĐĩҁ҂Đĩ Đ˛Đ°ŅˆĐĩĐŗĐž ĐēОда. diff --git a/docs/ru/docs/advanced/behind-a-proxy.md b/docs/ru/docs/advanced/behind-a-proxy.md new file mode 100644 index 000000000..281cb7f73 --- /dev/null +++ b/docs/ru/docs/advanced/behind-a-proxy.md @@ -0,0 +1,458 @@ +# За ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ { #behind-a-proxy } + +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐŋĐĩŅ€ĐĩĐ´ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Traefik иĐģи Nginx. + +ĐĸаĐēиĐĩ ĐŋŅ€ĐžĐēŅĐ¸ ĐŧĐžĐŗŅƒŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ HTTPSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ и ĐŧĐŊĐžĐŗĐžĐĩ Đ´Ņ€ŅƒĐŗĐžĐĩ. + +## ПĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸ { #proxy-forwarded-headers } + +ĐŸŅ€ĐžĐēŅĐ¸ ĐŋĐĩŅ€ĐĩĐ´ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊа ĐģĐĩŅ‚Ņƒ дОйавĐģŅĐĩŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ HTTPâ€‘ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋĐĩŅ€ĐĩĐ´ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐēОК СаĐŋŅ€ĐžŅĐ° ĐŊа Đ˛Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐžĐžĐąŅ‰Đ¸Ņ‚ŅŒ ĐĩĐŧ҃, Ņ‡Ņ‚Đž СаĐŋŅ€ĐžŅ ĐąŅ‹Đģ ĐŋĐĩŅ€ĐĩҁĐģаĐŊ ĐŋŅ€ĐžĐēŅĐ¸, а Ņ‚Đ°ĐēĐļĐĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš (ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš) URL (вĐēĐģŅŽŅ‡Đ°Ņ Đ´ĐžĐŧĐĩĐŊ), иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Ой Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии HTTPS и Ņ‚.Đ´. + +ĐŸŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ҁĐĩŅ€Đ˛ĐĩŅ€Đ° (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn, СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ҇ĐĩŅ€ĐĩС FastAPI CLI) ҃ĐŧĐĩĐĩŅ‚ иĐŊŅ‚ĐĩŅ€ĐŋŅ€ĐĩŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ ĐˇĐ°ĐŗĐžĐģОвĐēи и ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ŅƒŅŽ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ. + +Но иС ŅĐžĐžĐąŅ€Đ°ĐļĐĩĐŊиК ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ĐŋĐžĐēа ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŊĐĩ ŅƒĐ˛ĐĩŅ€ĐĩĐŊ, Ņ‡Ņ‚Đž ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ Са дОвĐĩŅ€ĐĩĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐžĐēŅĐ¸, ĐžĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ иĐŊŅ‚ĐĩŅ€ĐŋŅ€ĐĩŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ ĐˇĐ°ĐŗĐžĐģОвĐēи. + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +Đ—Đ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +### ВĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸ { #enable-proxy-forwarded-headers } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ FastAPI CLI ҁ ĐžĐŋŅ†Đ¸ĐĩĐš ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--forwarded-allow-ips` и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ дОвĐĩŅ€ŅŅ‚ŅŒ ĐŋŅ€Đ¸ ҇҂ĐĩĐŊии ŅŅ‚Đ¸Ņ… ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧҋ҅ ĐˇĐ°ĐŗĐžĐģОвĐēОв. + +Đ•ŅĐģи ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ `--forwarded-allow-ips="*"`, ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ дОвĐĩŅ€ŅŅ‚ŅŒ Đ˛ŅĐĩĐŧ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đŧ IP. + +Đ•ŅĐģи Đ˛Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ Са дОвĐĩŅ€ĐĩĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐžĐēŅĐ¸ и Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžĐēŅĐ¸ ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ Đē ĐŊĐĩĐŧ҃, ŅŅ‚ĐžĐŗĐž Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ ĐŋŅ€Đ¸ĐŊиĐŧаĐģ IP ŅŅ‚ĐžĐŗĐž ĐŋŅ€ĐžĐēŅĐ¸. + +
+ +```console +$ fastapi run --forwarded-allow-ips="*" + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +### Đ ĐĩĐ´Đ¸Ņ€ĐĩĐē҂ҋ ҁ HTTPS { #redirects-with-https } + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛Đ¸Đģи ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸ `/items/`: + +{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *} + +Đ•ŅĐģи ĐēĐģиĐĩĐŊŅ‚ ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŅ Đē `/items`, ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐžĐšĐ´Ņ‘Ņ‚ Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚ ĐŊа `/items/`. + +Но Đ´Đž ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐžĐŋŅ†Đ¸Đ¸ `--forwarded-allow-ips` Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚ ĐŧĐžĐļĐĩŅ‚ вĐĩŅŅ‚Đ¸ ĐŊа `http://localhost:8000/items/`. + +ОдĐŊаĐēĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐž ĐŋĐž `https://mysuperapp.com`, и Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚ Đ´ĐžĐģĐļĐĩĐŊ вĐĩŅŅ‚Đ¸ ĐŊа `https://mysuperapp.com/items/`. + +ĐŖĐēаСав `--proxy-headers`, FastAPI ҁĐŧĐžĐļĐĩŅ‚ Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚Đ¸Ņ‚ŅŒ ĐŊа ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đš Đ°Đ´Ņ€Đĩҁ. 😎 + +``` +https://mysuperapp.com/items/ +``` + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ Ой HTTPS, ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž [О HTTPS](../deployment/https.md){.internal-link target=_blank}. + +/// + +### КаĐē Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸ + +НиĐļĐĩ ĐŋĐžĐēаСаĐŊĐž, ĐēаĐē ĐŋŅ€ĐžĐēŅĐ¸ дОйавĐģŅĐĩŅ‚ ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŧĐĩĐļĐ´Ņƒ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ и ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ: + +```mermaid +sequenceDiagram + participant Client as КĐģиĐĩĐŊŅ‚ + participant Proxy as ĐŸŅ€ĐžĐēŅĐ¸/БаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи + participant Server as FastAPI-ҁĐĩŅ€Đ˛ĐĩŅ€ + + Client->>Proxy: HTTPS-СаĐŋŅ€ĐžŅ
Host: mysuperapp.com
Path: /items + + Note over Proxy: ĐŸŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ дОйавĐģŅĐĩŅ‚ ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи + + Proxy->>Server: HTTP-СаĐŋŅ€ĐžŅ
X-Forwarded-For: [client IP]
X-Forwarded-Proto: https
X-Forwarded-Host: mysuperapp.com
Path: /items + + Note over Server: Server иĐŊŅ‚ĐĩŅ€ĐŋŅ€ĐĩŅ‚Đ¸Ņ€ŅƒĐĩŅ‚ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи
(ĐĩҁĐģи --forwarded-allow-ips ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ) + + Server->>Proxy: HTTP-ĐžŅ‚Đ˛ĐĩŅ‚
ҁ вĐĩŅ€ĐŊŅ‹Đŧи HTTPS URLs + + Proxy->>Client: HTTPS-ĐžŅ‚Đ˛ĐĩŅ‚ +``` + +ĐŸŅ€ĐžĐēŅĐ¸ ĐŋĐĩŅ€ĐĩŅ…Đ˛Đ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš ĐēĐģиĐĩĐŊ҂ҁĐēиК СаĐŋŅ€ĐžŅ и дОйавĐģŅĐĩŅ‚ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊŅ‹Đĩ ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи (`X-Forwarded-*`) ĐŋĐĩŅ€ĐĩĐ´ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡ĐĩĐš СаĐŋŅ€ĐžŅĐ° ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. + +Đ­Ņ‚Đ¸ ĐˇĐ°ĐŗĐžĐģОвĐēи ŅĐžŅ…Ņ€Đ°ĐŊŅŅŽŅ‚ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Ой Đ¸ŅŅ…ĐžĐ´ĐŊĐžĐŧ СаĐŋŅ€ĐžŅĐĩ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ иĐŊĐ°Ņ‡Đĩ ĐąŅ‹Đģа ĐąŅ‹ ĐŋĐžŅ‚ĐĩŅ€ŅĐŊа: + +* X-Forwarded-For: Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš IPâ€‘Đ°Đ´Ņ€Đĩҁ ĐēĐģиĐĩĐŊŅ‚Đ° +* X-Forwarded-Proto: Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ (`https`) +* X-Forwarded-Host: Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš Ņ…ĐžŅŅ‚ (`mysuperapp.com`) + +ĐšĐžĐŗĐ´Đ° FastAPI CLI ҁĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊ ҁ `--forwarded-allow-ips`, ĐžĐŊ дОвĐĩŅ€ŅĐĩŅ‚ ŅŅ‚Đ¸Đŧ ĐˇĐ°ĐŗĐžĐģОвĐēаĐŧ и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đ¸Ņ…, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ„ĐžŅ€ĐŧĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đĩ URL в Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚Đ°Ņ…. + +## ĐŸŅ€ĐžĐēŅĐ¸ ҁ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš ŅƒĐ´Đ°ĐģĐĩĐŊĐ¸Ņ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ° ĐŋŅƒŅ‚Đ¸ { #proxy-with-a-stripped-path-prefix } + +ĐŸŅ€ĐžĐēŅĐ¸ ĐŧĐžĐļĐĩŅ‚ дОйавĐģŅŅ‚ŅŒ Đē Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ ĐŋŅƒŅ‚Đ¸ (Ņ€Đ°ĐˇĐŧĐĩŅ‰Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŋĐž ĐŋŅƒŅ‚Đ¸ ҁ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ). + +В Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `root_path` Đ´ĐģŅ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. + +МĐĩŅ…Đ°ĐŊиСĐŧ `root_path` ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ĐĩĐš ASGI (ĐŊа ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊ FastAPI, ҇ĐĩŅ€ĐĩС Starlette). + +`root_path` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи Ņ‚Đ°ĐēĐ¸Ņ… ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°Đĩв. + +ОĐŊ Ņ‚Đ°ĐēĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ ĐŋŅ€Đ¸ ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊии вĐģĐžĐļĐĩĐŊĐŊҋ҅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. + +ĐŸŅ€ĐžĐēŅĐ¸ ҁ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš ŅƒĐ´Đ°ĐģĐĩĐŊĐ¸Ņ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ° ĐŋŅƒŅ‚Đ¸ в ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ ĐŋŅƒŅ‚ŅŒ `/app` в ĐēОдĐĩ, а ĐˇĐ°Ņ‚ĐĩĐŧ дОйавĐģŅĐĩŅ‚Đĩ ŅĐ˛ĐĩŅ€Ņ…Ņƒ ҁĐģОК (ĐŋŅ€ĐžĐēŅĐ¸), ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€Đ°ĐˇĐŧĐĩŅ‰Đ°ĐĩŅ‚ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI ĐŋОд ĐŋŅƒŅ‚Ņ‘Đŧ вида `/api/v1`. + +ĐĸĐžĐŗĐ´Đ° Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš ĐŋŅƒŅ‚ŅŒ `/app` Ņ„Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒŅŅ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ `/api/v1/app`. + +ĐĨĐžŅ‚Ņ вĐĩҁҌ Đ˛Đ°Ņˆ ĐēОд ĐŊаĐŋĐ¸ŅĐ°ĐŊ ҁ Ņ€Đ°ŅŅ‡Ņ‘Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŋŅƒŅ‚ŅŒ ОдиĐŊ — `/app`. + +{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *} + +ĐŸŅ€ĐžĐēŅĐ¸ ĐąŅƒĐ´ĐĩŅ‚ ÂĢĐžĐąŅ€ĐĩĐˇĐ°Ņ‚ŅŒÂģ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ ĐŋŅƒŅ‚Đ¸ ĐŊа ĐģĐĩŅ‚Ņƒ ĐŋĐĩŅ€ĐĩĐ´ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡ĐĩĐš СаĐŋŅ€ĐžŅĐ° ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ (ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž Uvicorn, СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ҇ĐĩŅ€ĐĩС FastAPI CLI), ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ ҃ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ иĐģĐģŅŽĐˇĐ¸ŅŽ, Ņ‡Ņ‚Đž ĐĩĐŗĐž ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°ŅŽŅ‚ ĐŋĐž `/app`, Ņ‡Ņ‚ĐžĐąŅ‹ ваĐŧ ĐŊĐĩ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐŧĐĩĐŊŅŅ‚ŅŒ вĐĩҁҌ ĐēОд и дОйавĐģŅŅ‚ŅŒ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ `/api/v1`. + +До ŅŅ‚ĐžĐŗĐž ĐŧĐžĐŧĐĩĐŊŅ‚Đ° Đ˛ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐž. + +Но ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐžŅ‚ĐēŅ€ĐžĐĩŅ‚Đĩ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đš иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ (Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´), ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ `/openapi.json`, а ĐŊĐĩ `/api/v1/openapi.json`. + +ĐŸĐžŅŅ‚ĐžĐŧ҃ Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´ (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đĩ) ĐŋĐžĐŋŅ‹Ņ‚Đ°ĐĩŅ‚ŅŅ ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒŅŅ Đē `/openapi.json` и ĐŊĐĩ ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI. + +ĐĸаĐē ĐēаĐē Đ´ĐģŅ ĐŊĐ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ĐŋŅ€ĐžĐēŅĐ¸ ҁ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸ `/api/v1`, Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´Ņƒ ĐŊ҃ĐļĐŊĐž ĐˇĐ°ĐąĐ¸Ņ€Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI ĐŋĐž `/api/v1/openapi.json`. + +```mermaid +graph LR + +browser("Browser") +proxy["Proxy on http://0.0.0.0:9999/api/v1/app"] +server["Server on http://127.0.0.1:8000/app"] + +browser --> proxy +proxy --> server +``` + +/// tip | ХОвĐĩŅ‚ + +IP `0.0.0.0` ĐžĐąŅ‹Ņ‡ĐŊĐž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ҁĐģŅƒŅˆĐ°ĐĩŅ‚ ĐŊа Đ˛ŅĐĩŅ… IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ°Ņ…, Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐŊа ŅŅ‚ĐžĐš ĐŧĐ°ŅˆĐ¸ĐŊĐĩ/ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ. + +/// + +ИĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅƒ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ°ĐēĐļĐĩ ĐŊ҃ĐļĐŊа ҁ҅ĐĩĐŧа OpenAPI, в ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐąŅƒĐ´ĐĩŅ‚ ҃ĐēаСаĐŊĐž, Ņ‡Ņ‚Đž ŅŅ‚ĐžŅ‚ API `server` ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐŋĐž ĐŋŅƒŅ‚Đ¸ `/api/v1` (Са ĐŋŅ€ĐžĐēŅĐ¸). НаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +```JSON hl_lines="4-8" +{ + "openapi": "3.1.0", + // ЗдĐĩҁҌ Đĩ҉ґ Ņ‡Ņ‚Đž-Ņ‚Đž + "servers": [ + { + "url": "/api/v1" + } + ], + "paths": { + // ЗдĐĩҁҌ Đĩ҉ґ Ņ‡Ņ‚Đž-Ņ‚Đž + } +} +``` + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ÂĢProxyÂģ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Traefik. А ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ĐąŅƒĐ´ĐĩŅ‚ Ņ‡Ņ‚Đžâ€‘Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ FastAPI CLI ҁ Uvicorn, ĐŊа ĐēĐžŅ‚ĐžŅ€ĐžĐŧ СаĐŋŅƒŅ‰ĐĩĐŊĐž Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI. + +### ĐŖĐēаСаĐŊиĐĩ `root_path` { #providing-the-root-path } + +ДĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐžĐŋŅ†Đ¸ŅŽ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--root-path`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Ņ‚Đ°Đē: + +
+ +```console +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Hypercorn, ҃ ĐŊĐĩĐŗĐž Ņ‚ĐžĐļĐĩ ĐĩŅŅ‚ŅŒ ĐžĐŋŅ†Đ¸Ņ `--root-path`. + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +ĐĄĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ ASGI ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚ `root_path` Đ´ĐģŅ Ņ‚Đ°ĐēĐžĐŗĐž ҁĐģŅƒŅ‡Đ°Ņ. + +А ĐžĐŋŅ†Đ¸Ņ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--root-path` ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ ŅŅ‚ĐžŅ‚ `root_path`. + +/// + +### ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа Ņ‚ĐĩĐēŅƒŅ‰ĐĩĐŗĐž `root_path` { #checking-the-current-root-path } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ‚ĐĩĐēŅƒŅ‰Đ¸Đš `root_path`, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đš Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°, — ĐžĐŊ Đ˛Ņ…ĐžĐ´Đ¸Ņ‚ в ҁĐģĐžĐ˛Đ°Ņ€ŅŒ `scope` (Ņ‡Đ°ŅŅ‚ŅŒ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ASGI). + +ЗдĐĩҁҌ ĐŧŅ‹ дОйавĐģŅĐĩĐŧ ĐĩĐŗĐž в ŅĐžĐžĐąŅ‰ĐĩĐŊиĐĩ ĐģĐ¸ŅˆŅŒ Đ´ĐģŅ Đ´ĐĩĐŧĐžĐŊŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸. + +{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *} + +Đ—Đ°Ņ‚ĐĩĐŧ, ĐĩҁĐģи Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ Uvicorn Ņ‚Đ°Đē: + +
+ +```console +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +ĐžŅ‚Đ˛ĐĩŅ‚ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž Ņ‚Đ°ĐēиĐŧ: + +```JSON +{ + "message": "Hello World", + "root_path": "/api/v1" +} +``` + +### ĐŖŅŅ‚Đ°ĐŊОвĐēа `root_path` в ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии FastAPI { #setting-the-root-path-in-the-fastapi-app } + +Đ•ŅĐģи ĐŊĐĩŅ‚ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐžĐŋŅ†Đ¸ŅŽ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--root-path` (иĐģи аĐŊаĐģĐžĐŗ), Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `root_path` ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI: + +{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *} + +ПĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ° `root_path` в `FastAPI` ŅĐēвиваĐģĐĩĐŊŅ‚ĐŊа ĐžĐŋŅ†Đ¸Đ¸ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--root-path` Đ´ĐģŅ Uvicorn иĐģи Hypercorn. + +### О `root_path` { #about-root-path } + +ĐŖŅ‡Ņ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ҁĐĩŅ€Đ˛ĐĩŅ€ (Uvicorn) ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ `root_path` ĐŊи Đ´ĐģŅ ҇ĐĩĐŗĐž, ĐēŅ€ĐžĐŧĐĩ ĐēаĐē ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐĩĐŗĐž в ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. + +Đ•ŅĐģи Đ˛Ņ‹ ĐžŅ‚ĐēŅ€ĐžĐĩŅ‚Đĩ в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đĩ http://127.0.0.1:8000/app, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚: + +```JSON +{ + "message": "Hello World", + "root_path": "/api/v1" +} +``` + +ĐĸĐž ĐĩŅŅ‚ŅŒ ĐžĐŊ ĐŊĐĩ ĐžĐļидаĐĩŅ‚, Ņ‡Ņ‚Đž Đē ĐŊĐĩĐŧ҃ ĐžĐąŅ€Đ°Ņ‚ŅŅ‚ŅŅ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ `http://127.0.0.1:8000/api/v1/app`. + +Uvicorn ĐžĐļидаĐĩŅ‚, Ņ‡Ņ‚Đž ĐŋŅ€ĐžĐēŅĐ¸ ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŅ Đē ĐŊĐĩĐŧ҃ ĐŋĐž `http://127.0.0.1:8000/app`, а ҃ĐļĐĩ ĐˇĐ°Đ´Đ°Ņ‡Đ° ĐŋŅ€ĐžĐēŅĐ¸ — Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ŅĐ˛ĐĩŅ€Ņ…Ņƒ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ `/api/v1`. + +## О ĐŋŅ€ĐžĐēŅĐ¸ ҁ ŅƒŅ€ĐĩСаĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸ { #about-proxies-with-a-stripped-path-prefix } + +ПоĐŧĐŊĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ĐŋŅ€ĐžĐēŅĐ¸ ҁ ŅƒŅ€ĐĩСаĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸ — ĐģĐ¸ŅˆŅŒ ОдиĐŊ иС Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐ˛ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи. + +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐŋŅ€ĐžĐēŅĐ¸ ĐąŅƒĐ´ĐĩŅ‚ ĐąĐĩС ŅƒŅ€ĐĩСаĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ° ĐŋŅƒŅ‚Đ¸. + +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ (ĐąĐĩС ŅƒŅ€ĐĩСаĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ°) ĐŋŅ€ĐžĐēŅĐ¸ ҁĐģŅƒŅˆĐ°ĐĩŅ‚, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ `https://myawesomeapp.com`, и ĐĩҁĐģи ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ Đ¸Đ´Ņ‘Ņ‚ ĐŊа `https://myawesomeapp.com/api/v1/app`, а Đ˛Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn) ҁĐģŅƒŅˆĐ°ĐĩŅ‚ ĐŊа `http://127.0.0.1:8000`, Ņ‚Đž ĐŋŅ€ĐžĐēŅĐ¸ (ĐąĐĩС ŅƒŅ€ĐĩСаĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ°) ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŅ Đē Uvicorn ĐŋĐž Ņ‚ĐžĐŧ҃ ĐļĐĩ ĐŋŅƒŅ‚Đ¸: `http://127.0.0.1:8000/api/v1/app`. + +## ЛоĐēаĐģҌĐŊĐžĐĩ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ҁ Traefik { #testing-locally-with-traefik } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐģĐĩĐŗĐēĐž ĐŋĐžŅĐēҁĐŋĐĩŅ€Đ¸ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐģĐžĐēаĐģҌĐŊĐž ҁ ŅƒŅ€ĐĩСаĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Traefik. + +ĐĄĐēĐ°Ņ‡Đ°ĐšŅ‚Đĩ Traefik — ŅŅ‚Đž ОдиĐŊ йиĐŊĐ°Ņ€ĐŊŅ‹Đš Ņ„Đ°ĐšĐģ; Ņ€Đ°ŅĐŋаĐēŅƒĐšŅ‚Đĩ Đ°Ņ€Ņ…Đ¸Đ˛ и СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐĩĐŗĐž ĐŋŅ€ŅĐŧĐž иС Ņ‚ĐĩŅ€ĐŧиĐŊаĐģа. + +Đ—Đ°Ņ‚ĐĩĐŧ ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `traefik.toml` ŅĐž ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧŅ‹Đŧ: + +```TOML hl_lines="3" +[entryPoints] + [entryPoints.http] + address = ":9999" + +[providers] + [providers.file] + filename = "routes.toml" +``` + +Đ­Ņ‚Đž ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Traefik ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ĐŋĐžŅ€Ņ‚ 9999 и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš Ņ„Đ°ĐšĐģ `routes.toml`. + +/// tip | ХОвĐĩŅ‚ + +ĐœŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ĐŋĐžŅ€Ņ‚ 9999 вĐŧĐĩŅŅ‚Đž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊĐžĐŗĐž HTTP‑ĐŋĐžŅ€Ņ‚Đ° 80, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐąŅ‹ĐģĐž СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ҁ ĐŋŅ€Đ°Đ˛Đ°Đŧи адĐŧиĐŊĐ¸ŅŅ‚Ņ€Đ°Ņ‚ĐžŅ€Đ° (`sudo`). + +/// + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Đ˛Ņ‚ĐžŅ€ĐžĐš Ņ„Đ°ĐšĐģ `routes.toml`: + +```TOML hl_lines="5 12 20" +[http] + [http.middlewares] + + [http.middlewares.api-stripprefix.stripPrefix] + prefixes = ["/api/v1"] + + [http.routers] + + [http.routers.app-http] + entryPoints = ["http"] + service = "app" + rule = "PathPrefix(`/api/v1`)" + middlewares = ["api-stripprefix"] + + [http.services] + + [http.services.app] + [http.services.app.loadBalancer] + [[http.services.app.loadBalancer.servers]] + url = "http://127.0.0.1:8000" +``` + +Đ­Ņ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩŅ‚ Traefik ĐŊа Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ° ĐŋŅƒŅ‚Đ¸ `/api/v1`. + +ДаĐģĐĩĐĩ Traefik ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžĐēŅĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ ĐŊа Đ˛Đ°Ņˆ Uvicorn, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đš ĐŊа `http://127.0.0.1:8000`. + +ĐĸĐĩĐŋĐĩŅ€ŅŒ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ Traefik: + +
+ +```console +$ ./traefik --configFile=traefik.toml + +INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml +``` + +
+ +И СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁ ĐžĐŋŅ†Đ¸ĐĩĐš `--root-path`: + +
+ +```console +$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +### ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ { #check-the-responses } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐĩҁĐģи Đ˛Ņ‹ ĐŋĐĩŅ€ĐĩĐšĐ´Ņ‘Ņ‚Đĩ ĐŊа URL ҁ ĐŋĐžŅ€Ņ‚ĐžĐŧ Uvicorn: http://127.0.0.1:8000/app, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚: + +```JSON +{ + "message": "Hello World", + "root_path": "/api/v1" +} +``` + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž Ņ…ĐžŅ‚Ņ Đ˛Ņ‹ ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ĐĩҁҌ ĐŋĐž `http://127.0.0.1:8000/app`, в ĐžŅ‚Đ˛ĐĩŅ‚Đĩ ҃ĐēаСаĐŊ `root_path` Ņ€Đ°Đ˛ĐŊŅ‹Đš `/api/v1`, Đ˛ĐˇŅŅ‚Ņ‹Đš иС ĐžĐŋŅ†Đ¸Đ¸ `--root-path`. + +/// + +А Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐžŅ‚ĐēŅ€ĐžĐšŅ‚Đĩ URL ҁ ĐŋĐžŅ€Ņ‚ĐžĐŧ Traefik и ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸: http://127.0.0.1:9999/api/v1/app. + +ĐœŅ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Đŧ Ņ‚ĐžŅ‚ ĐļĐĩ ĐžŅ‚Đ˛ĐĩŅ‚: + +```JSON +{ + "message": "Hello World", + "root_path": "/api/v1" +} +``` + +ĐŊĐž ҃ĐļĐĩ ĐŋĐž URL ҁ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš дОйавĐģŅĐĩŅ‚ ĐŋŅ€ĐžĐēŅĐ¸: `/api/v1`. + +Đ Đ°ĐˇŅƒĐŧĐĩĐĩŅ‚ŅŅ, ĐˇĐ°Đ´ŅƒĐŧŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ, Ņ‡Ņ‚Đž Đ˛ŅĐĩ ĐąŅƒĐ´ŅƒŅ‚ ĐžĐąŅ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ Đē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ҇ĐĩŅ€ĐĩС ĐŋŅ€ĐžĐēŅĐ¸, ĐŋĐžŅŅ‚ĐžĐŧ҃ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ ҁ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸ `/api/v1` ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ÂĢĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊŅ‹ĐŧÂģ. + +А Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ ĐąĐĩС ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ° (`http://127.0.0.1:8000/app`), Đ˛Ņ‹Đ´Đ°Đ˛Đ°ĐĩĐŧŅ‹Đš ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Uvicorn, ĐŋŅ€ĐĩĐ´ĐŊаСĐŊĐ°Ņ‡ĐĩĐŊ Đ¸ŅĐēĐģŅŽŅ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž Đ´ĐģŅ Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐžĐēŅĐ¸ (Traefik) ĐŧĐžĐŗ Đē ĐŊĐĩĐŧ҃ ĐžĐąŅ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ. + +Đ­Ņ‚Đž Đ´ĐĩĐŧĐžĐŊŅŅ‚Ņ€Đ¸Ņ€ŅƒĐĩŅ‚, ĐēаĐē ĐŋŅ€ĐžĐēŅĐ¸ (Traefik) Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ ĐŋŅƒŅ‚Đ¸ и ĐēаĐē ҁĐĩŅ€Đ˛ĐĩŅ€ (Uvicorn) Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ `root_path`, ĐŋĐĩŅ€ĐĩдаĐŊĐŊŅ‹Đš ҇ĐĩŅ€ĐĩС ĐžĐŋŅ†Đ¸ŅŽ `--root-path`. + +### ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #check-the-docs-ui } + +А Đ˛ĐžŅ‚ ŅĐ°ĐŧĐžĐĩ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐžĐĩ. ✨ + +ÂĢĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹ĐšÂģ ҁĐŋĐžŅĐžĐą Đ´ĐžŅŅ‚ŅƒĐŋа Đē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ — ҇ĐĩŅ€ĐĩС ĐŋŅ€ĐžĐēŅĐ¸ ҁ СадаĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸. ĐŸĐžŅŅ‚ĐžĐŧ҃, ĐēаĐē и ĐžĐļидаĐĩŅ‚ŅŅ, ĐĩҁĐģи ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ŅŒ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, ĐžŅ‚Đ´Đ°Đ˛Đ°ĐĩĐŧŅ‹Đš ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Uvicorn, ĐąĐĩС ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐ° ĐŋŅƒŅ‚Đ¸ в URL, ĐžĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ, Ņ‚Đ°Đē ĐēаĐē ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚ŅŅ Đ´ĐžŅŅ‚ŅƒĐŋ ҇ĐĩŅ€ĐĩС ĐŋŅ€ĐžĐēŅĐ¸. + +ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:8000/docs: + + + +А Đ˛ĐžŅ‚ ĐĩҁĐģи ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ŅŒ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŋĐž ÂĢĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ҃Âģ URL ҇ĐĩŅ€ĐĩС ĐŋŅ€ĐžĐēŅĐ¸ ĐŊа ĐŋĐžŅ€Ņ‚Ņƒ `9999`, ĐŋĐž `/api/v1/docs`, Đ˛ŅŅ‘ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž! 🎉 + +ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:9999/api/v1/docs: + + + +ИĐŧĐĩĐŊĐŊĐž ĐēаĐē и Ņ…ĐžŅ‚ĐĩĐģĐžŅŅŒ. âœ”ī¸ + +Đ­Ņ‚Đž ĐŋĐžŅ‚ĐžĐŧ҃, Ņ‡Ņ‚Đž FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ `root_path`, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ в OpenAPI ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ҁ URL иС `root_path`. + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ҁĐĩŅ€Đ˛ĐĩҀҋ { #additional-servers } + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ­Ņ‚Đž йОĐģĐĩĐĩ ĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Ņ‹Đš ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đš. МоĐļĐŊĐž ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ. + +/// + +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ FastAPI ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ в ҁ҅ĐĩĐŧĐĩ OpenAPI `server` ҁ URL иС `root_path`. + +Но Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ `servers`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ОдиĐŊ и Ņ‚ĐžŅ‚ ĐļĐĩ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Ņ€Đ°ĐąĐžŅ‚Đ°Đģ и ŅĐž ҁ҂ĐĩКдĐļиĐŊĐŗĐžĐŧ, и ҁ ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ. + +Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐĩŅ€ĐĩĐ´Đ°Đ´Đ¸Ņ‚Đĩ ŅĐ˛ĐžĐš ҁĐŋĐ¸ŅĐžĐē `servers` и ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ СадаĐŊ `root_path` (ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž Đ˛Đ°Ņˆ API Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Са ĐŋŅ€ĐžĐēŅĐ¸), FastAPI Đ˛ŅŅ‚Đ°Đ˛Đ¸Ņ‚ ÂĢserverÂģ ҁ ŅŅ‚Đ¸Đŧ `root_path` в ĐŊĐ°Ņ‡Đ°ĐģĐž ҁĐŋĐ¸ŅĐēа. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *} + +Đ‘ŅƒĐ´ĐĩŅ‚ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊа ҁ҅ĐĩĐŧа OpenAPI ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž Ņ‚Đ°ĐēĐ°Ņ: + +```JSON hl_lines="5-7" +{ + "openapi": "3.1.0", + // ЗдĐĩҁҌ Đĩ҉ґ Ņ‡Ņ‚Đž-Ņ‚Đž + "servers": [ + { + "url": "/api/v1" + }, + { + "url": "https://stag.example.com", + "description": "Staging environment" + }, + { + "url": "https://prod.example.com", + "description": "Production environment" + } + ], + "paths": { + // ЗдĐĩҁҌ Đĩ҉ґ Ņ‡Ņ‚Đž-Ņ‚Đž + } +} +``` + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ ĐŊа Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи дОйавĐģĐĩĐŊĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ ҁ `url` Ņ€Đ°Đ˛ĐŊŅ‹Đŧ `/api/v1`, Đ˛ĐˇŅŅ‚Ņ‹Đŧ иС `root_path`. + +/// + +В иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:9999/api/v1/docs ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: + + + +/// tip | ХОвĐĩŅ‚ + +ИĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐąŅƒĐ´ĐĩŅ‚ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ Đ˛Ņ‹ĐąĐĩŅ€ĐĩŅ‚Đĩ. + +/// + +### ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ дОйавĐģĐĩĐŊиĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° иС `root_path` { #disable-automatic-server-from-root-path } + +Đ•ŅĐģи Đ˛Ņ‹ ĐŊĐĩ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ FastAPI дОйавĐģŅĐģ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиК ҁĐĩŅ€Đ˛ĐĩŅ€, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `root_path`, ҃ĐēаĐļĐ¸Ņ‚Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `root_path_in_servers=False`: + +{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *} + +и Ņ‚ĐžĐŗĐ´Đ° ŅŅ‚ĐžŅ‚ ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ дОйавĐģĐĩĐŊ в ҁ҅ĐĩĐŧ҃ OpenAPI. + +## МоĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ вĐģĐžĐļĐĩĐŊĐŊĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ { #mounting-a-sub-application } + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž ҁĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ вĐģĐžĐļĐĩĐŊĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ (ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž в [ВĐģĐžĐļĐĩĐŊĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ](sub-applications.md){.internal-link target=_blank}), и ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐŋŅ€ĐžĐēŅĐ¸ ҁ `root_path`, Đ´ĐĩĐģĐ°ĐšŅ‚Đĩ ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ — Đ˛ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ, ĐēаĐē ĐžĐļидаĐĩŅ‚ŅŅ. + +FastAPI ҃ĐŧĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ `root_path` вĐŊŅƒŅ‚Ņ€Đ¸, Ņ‚Đ°Đē Ņ‡Ņ‚Đž Đ˛ŅŅ‘ ĐŋŅ€ĐžŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚. ✨ diff --git a/docs/ru/docs/advanced/custom-response.md b/docs/ru/docs/advanced/custom-response.md new file mode 100644 index 000000000..2c238bd95 --- /dev/null +++ b/docs/ru/docs/advanced/custom-response.md @@ -0,0 +1,312 @@ +# ĐšĐ°ŅŅ‚ĐžĐŧĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ — HTML, ĐŋĐžŅ‚ĐžĐē, Ņ„Đ°ĐšĐģ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ { #custom-response-html-stream-file-others } + +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ **FastAPI** Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐžŅ‚Đ˛Đĩ҂ҋ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `JSONResponse`. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ŅŅ‚Đž, вĐĩŅ€ĐŊŅƒĐ˛ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐēаĐē ĐŋĐžĐēаСаĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ Response ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ](response-directly.md){.internal-link target=_blank}. + +Но ĐĩҁĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (иĐģи ĐģŅŽĐąĐžĐš ĐĩĐŗĐž ĐŋОдĐēĐģĐ°ŅŅ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `JSONResponse`), даĐŊĐŊŅ‹Đĩ ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊŅ‹ (даĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛Đ¸Đģи `response_model`), и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊа (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅĐž ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đŧ ÂĢŅ‚Đ¸ĐŋĐžĐŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐžÂģ в HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēĐĩ `Content-Type` ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒŅŽ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž OpenAPI). + +Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Ņ‚Đ°ĐēĐļĐĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ `Response`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐģŅŽĐąĐžĐš ĐŋОдĐēĐģĐ°ŅŅ `Response`), в Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_class`. + +ХОдĐĩŅ€ĐļиĐŧĐžĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ иС ŅĐ˛ĐžĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸, ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐŧĐĩ҉ĐĩĐŊĐž вĐŊŅƒŅ‚Ņ€ŅŒ ŅŅ‚ĐžĐŗĐž `Response`. + +И ĐĩҁĐģи ҃ ŅŅ‚ĐžĐŗĐž `Response` Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž JSON (`application/json`), ĐēаĐē в ҁĐģŅƒŅ‡Đ°Đĩ ҁ `JSONResponse` и `UJSONResponse`, даĐŊĐŊŅ‹Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ, ĐąŅƒĐ´ŅƒŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊŅ‹ (и ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊŅ‹) ĐģŅŽĐąŅ‹Đŧ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đŧ ваĐŧи в Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ Pydantic `response_model`. + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐąĐĩС Ņ‚Đ¸Đŋа ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, FastAPI ĐąŅƒĐ´ĐĩŅ‚ ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ҃ Đ˛Đ°ŅˆĐĩĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŊĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐžĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Ņ„ĐžŅ€ĐŧĐ°Ņ‚ ĐžŅ‚Đ˛ĐĩŅ‚Đ° в ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ OpenAPI. + +/// + +## Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `ORJSONResponse` { #use-orjsonresponse } + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи Đ˛Ņ‹ Đ˛Ņ‹ĐļиĐŧаĐĩŅ‚Đĩ ĐŧаĐēŅĐ¸Đŧ҃Đŧ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `orjson` и ĐˇĐ°Đ´Đ°Ņ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚ ĐēаĐē `ORJSONResponse`. + +ИĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ ĐēĐģĐ°ŅŅ (ĐŋОдĐēĐģĐ°ŅŅ) `Response`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ, и ĐžĐąŅŠŅĐ˛Đ¸Ņ‚Đĩ ĐĩĐŗĐž в Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸. + +ДĐģŅ йОĐģŅŒŅˆĐ¸Ņ… ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ, ҇ĐĩĐŧ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ҁĐģĐžĐ˛Đ°Ņ€ŅŒ. + +Đ­Ņ‚Đž ĐŋĐžŅ‚ĐžĐŧ҃, Ņ‡Ņ‚Đž ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ FastAPI ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚ ĐēаĐļĐ´Ņ‹Đš ŅĐģĐĩĐŧĐĩĐŊŅ‚ вĐŊŅƒŅ‚Ņ€Đ¸ и ŅƒĐąĐĩĐļдаĐĩŅ‚ŅŅ, Ņ‡Ņ‚Đž ĐžĐŊ ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇŅƒĐĩĐŧ в JSON, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ‚ĐžŅ‚ ĐļĐĩ [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}, ĐžĐąŅŠŅŅĐŊŅ‘ĐŊĐŊŅ‹Đš в Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đĩ. Đ­Ņ‚Đž ĐŋОСвОĐģŅĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ **ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐģҌĐŊŅ‹Đĩ ĐžĐąŅŠĐĩĐē҂ҋ**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐŧОдĐĩĐģи иС ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅. + +Но ĐĩҁĐģи Đ˛Ņ‹ ŅƒĐ˛ĐĩŅ€ĐĩĐŊŅ‹, Ņ‡Ņ‚Đž ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ, **ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇŅƒĐĩĐŧĐž в JSON**, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐĩĐŗĐž ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° и иСйĐĩĐļĐ°Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ĐŊаĐēĐģадĐŊҋ҅ Ņ€Đ°ŅŅ…ĐžĐ´ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ FastAPI ĐŋĐžĐŊґҁ ĐąŅ‹, ĐŋŅ€ĐžĐŋ҃ҁĐēĐ°Ņ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ ҇ĐĩŅ€ĐĩС `jsonable_encoder` ĐŋĐĩŅ€ĐĩĐ´ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡ĐĩĐš в ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_class` Ņ‚Đ°ĐēĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ҃ĐēаСаĐŊĐ¸Ņ ÂĢŅ‚Đ¸Đŋа ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐžÂģ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвОĐē `Content-Type` ĐąŅƒĐ´ĐĩŅ‚ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ в `application/json`. + +И ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐž ĐēаĐē Ņ‚Đ°ĐēОвОĐĩ в OpenAPI. + +/// + +/// tip | ХОвĐĩŅ‚ + +`ORJSONResponse` Đ´ĐžŅŅ‚ŅƒĐŋĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž в FastAPI, а ĐŊĐĩ в Starlette. + +/// + +## HTML-ĐžŅ‚Đ˛ĐĩŅ‚ { #html-response } + +Đ§Ņ‚ĐžĐąŅ‹ вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚ ҁ HTML ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС **FastAPI**, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `HTMLResponse`. + +- ИĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `HTMLResponse`. +- ПĐĩŅ€ĐĩĐ´Đ°ĐšŅ‚Đĩ `HTMLResponse` в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_class` Đ˛Đ°ŅˆĐĩĐŗĐž Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đ° ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸. + +{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_class` Ņ‚Đ°ĐēĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ҃ĐēаСаĐŊĐ¸Ņ ÂĢŅ‚Đ¸Đŋа ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐžÂģ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвОĐē `Content-Type` ĐąŅƒĐ´ĐĩŅ‚ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ в `text/html`. + +И ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐž ĐēаĐē Ņ‚Đ°ĐēОвОĐĩ в OpenAPI. + +/// + +### ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ `Response` { #return-a-response } + +КаĐē ĐŋĐžĐēаСаĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ Response ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ](response-directly.md){.internal-link target=_blank}, Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚ ĐŋŅ€ŅĐŧĐž в ŅĐ˛ĐžĐĩĐš ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸, ĐŋŅ€ĐžŅŅ‚Đž вĐĩŅ€ĐŊŅƒĐ˛ ĐĩĐŗĐž. + +ĐĸĐžŅ‚ ĐļĐĩ ĐŋŅ€Đ¸ĐŧĐĩŅ€ ŅĐ˛ĐĩŅ€Ņ…Ņƒ, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ŅŽŅ‰Đ¸Đš `HTMLResponse`, ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: + +{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *} + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +`Response`, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊĐŊŅ‹Đš ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Đ˛Đ°ŅˆĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ ĐŋŅƒŅ‚Đ¸, ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊ в OpenAPI (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `Content-Type` ĐŊĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°) и ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ видĐĩĐŊ в Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊОК иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. + +/// + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +Đ Đ°ĐˇŅƒĐŧĐĩĐĩŅ‚ŅŅ, Ņ„Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ ĐˇĐ°ĐŗĐžĐģОвОĐē `Content-Type`, ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд и Ņ‚.Đ´. Đ˛ĐžĐˇŅŒĐŧŅƒŅ‚ŅŅ иС ĐžĐąŅŠĐĩĐēŅ‚Đ° `Response`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ вĐĩŅ€ĐŊ҃Đģи. + +/// + +### ЗадоĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ в OpenAPI и ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ `Response` { #document-in-openapi-and-override-response } + +Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚ вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐŊĐž ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ÂĢŅ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐžÂģ в OpenAPI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_class` И вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐžĐąŅŠĐĩĐēŅ‚ `Response`. + +ĐĸĐžĐŗĐ´Đ° `response_class` ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* в OpenAPI, а Đ˛Đ°Ņˆ `Response` ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ ĐēаĐē ĐĩŅŅ‚ŅŒ. + +#### ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ `HTMLResponse` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ { #return-an-htmlresponse-directly } + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ: + +{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *} + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `generate_html_response()` ҃ĐļĐĩ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ `Response` вĐŧĐĩŅŅ‚Đž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‚Đ° HTML в `str`. + +Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ Đ˛Ņ‹ĐˇĐžĐ˛Đ° `generate_html_response()`, Đ˛Ņ‹ ҃ĐļĐĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ **FastAPI** ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. + +Но ĐŋĐžŅĐēĐžĐģҌĐē҃ Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŋĐĩŅ€ĐĩдаĐģи `HTMLResponse` в `response_class`, **FastAPI** ĐąŅƒĐ´ĐĩŅ‚ СĐŊĐ°Ņ‚ŅŒ, ĐēаĐē СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž в OpenAPI и иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐēаĐē HTML ҁ `text/html`: + + + +## Đ”ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ { #available-responses } + +НиĐļĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊŅ‹ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ ĐēĐģĐ°ŅŅŅ‹ ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛. + +ĐŖŅ‡Ņ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `Response`, Ņ‡Ņ‚ĐžĐąŅ‹ вĐĩŅ€ĐŊŅƒŅ‚ŅŒ Ņ‡Ņ‚Đž ŅƒĐŗĐžĐ´ĐŊĐž Đĩ҉ґ, иĐģи даĐļĐĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đš ĐŋОдĐēĐģĐ°ŅŅ. + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐŗĐģи ĐąŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.responses import HTMLResponse`. + +**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚Đĩ ĐļĐĩ `starlette.responses` ĐēаĐē `fastapi.responses` Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ° ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. Но йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐēĐģĐ°ŅŅĐžĐ˛ ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‚ ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž иС Starlette. + +/// + +### `Response` { #response } + +Đ‘Đ°ĐˇĐžĐ˛Ņ‹Đš ĐēĐģĐ°ŅŅ `Response`, ĐžŅ‚ ĐŊĐĩĐŗĐž ĐŊĐ°ŅĐģĐĩĐ´ŅƒŅŽŅ‚ŅŅ Đ˛ŅĐĩ ĐžŅŅ‚Đ°ĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ. + +Đ•ĐŗĐž ĐŧĐžĐļĐŊĐž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +ОĐŊ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ: + +- `content` — `str` иĐģи `bytes`. +- `status_code` — ҆ĐĩĐģĐžĐĩ Ņ‡Đ¸ŅĐģĐž, HTTP ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд. +- `headers` — ҁĐģĐžĐ˛Đ°Ņ€ŅŒ ŅŅ‚Ņ€ĐžĐē. +- `media_type` — ŅŅ‚Ņ€ĐžĐēа, ĐˇĐ°Đ´Đ°ŅŽŅ‰Đ°Ņ Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, `"text/html"`. + +FastAPI (Ņ„Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи Starlette) Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ ĐˇĐ°ĐŗĐžĐģОвОĐē Content-Length. ĐĸаĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ дОйавĐģĐĩĐŊ ĐˇĐ°ĐŗĐžĐģОвОĐē Content-Type, ĐžŅĐŊОваĐŊĐŊŅ‹Đš ĐŊа `media_type` и ҁ дОйавĐģĐĩĐŊиĐĩĐŧ charset Đ´ĐģŅ Ņ‚ĐĩĐēŅŅ‚ĐžĐ˛Ņ‹Ņ… Ņ‚Đ¸ĐŋОв. + +{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} + +### `HTMLResponse` { #htmlresponse } + +ĐŸŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Ņ‚ĐĩĐēҁ҂ иĐģи ĐąĐ°ĐšŅ‚Ņ‹ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ HTML-ĐžŅ‚Đ˛ĐĩŅ‚, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ. + +### `PlainTextResponse` { #plaintextresponse } + +ĐŸŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Ņ‚ĐĩĐēҁ҂ иĐģи ĐąĐ°ĐšŅ‚Ņ‹ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚ в видĐĩ ĐŋŅ€ĐžŅŅ‚ĐžĐŗĐž Ņ‚ĐĩĐēŅŅ‚Đ°. + +{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} + +### `JSONResponse` { #jsonresponse } + +ĐŸŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ даĐŊĐŊŅ‹Đĩ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚, ĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ĐēаĐē `application/json`. + +Đ­Ņ‚Đž ĐžŅ‚Đ˛ĐĩŅ‚ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đš в **FastAPI**, ĐēаĐē ĐąŅ‹ĐģĐž ҁĐēаСаĐŊĐž Đ˛Ņ‹ŅˆĐĩ. + +### `ORJSONResponse` { #orjsonresponse } + +Đ‘Ņ‹ŅŅ‚Ņ€Đ°Ņ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐ°Ņ Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ JSON-ĐžŅ‚Đ˛ĐĩŅ‚Đ° ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `orjson`, ĐēаĐē ĐąŅ‹ĐģĐž ҁĐēаСаĐŊĐž Đ˛Ņ‹ŅˆĐĩ. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐĸŅ€ĐĩĐąŅƒĐĩŅ‚ŅŅ ŅƒŅŅ‚Đ°ĐŊОвĐēа `orjson`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐēĐžĐŧаĐŊдОК `pip install orjson`. + +/// + +### `UJSONResponse` { #ujsonresponse } + +АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐ°Ņ Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ JSON-ĐžŅ‚Đ˛ĐĩŅ‚Đ° ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `ujson`. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐĸŅ€ĐĩĐąŅƒĐĩŅ‚ŅŅ ŅƒŅŅ‚Đ°ĐŊОвĐēа `ujson`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐēĐžĐŧаĐŊдОК `pip install ujson`. + +/// + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +`ujson` ĐŧĐĩĐŊĐĩĐĩ аĐēĐēŅƒŅ€Đ°Ņ‚ĐĩĐŊ, ҇ĐĩĐŧ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊĐ°Ņ Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ Python, в ĐžĐąŅ€Đ°ĐąĐžŅ‚ĐēĐĩ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐēŅ€Đ°ĐšĐŊĐ¸Ņ… ҁĐģŅƒŅ‡Đ°Đĩв. + +/// + +{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *} + +/// tip | ХОвĐĩŅ‚ + +ВозĐŧĐžĐļĐŊĐž, `ORJSONResponse` ĐžĐēаĐļĐĩŅ‚ŅŅ йОĐģĐĩĐĩ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐŧ. + +/// + +### `RedirectResponse` { #redirectresponse } + +Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ HTTP-Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚. По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд 307 (Temporary Redirect — Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐĩ ĐŋĐĩŅ€ĐĩĐŊаĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ). + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ вĐĩŅ€ĐŊŅƒŅ‚ŅŒ `RedirectResponse` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ: + +{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *} + +--- + +ИĐģи ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂ҀĐĩ `response_class`: + +{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *} + +Đ•ŅĐģи Đ˛Ņ‹ ŅĐ´ĐĩĐģаĐĩŅ‚Đĩ Ņ‚Đ°Đē, Ņ‚Đž ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ URL ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС ŅĐ˛ĐžĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸. + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ Đ´ĐģŅ `RedirectResponse`, Ņ‚Đž ĐĩŅŅ‚ŅŒ `307`. + +--- + +ĐĸаĐēĐļĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `status_code` в ŅĐžŅ‡ĐĩŅ‚Đ°ĐŊии ҁ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐŧ `response_class`: + +{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} + +### `StreamingResponse` { #streamingresponse } + +ĐŸŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ иĐģи ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€/Đ¸Ņ‚ĐĩŅ€Đ°Ņ‚ĐžŅ€ и ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚ĐĩĐģĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŋĐžŅ‚ĐžĐēОвО. + +{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} + +#### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `StreamingResponse` ҁ Ņ„Đ°ĐšĐģĐžĐŋОдОйĐŊŅ‹Đŧи ĐžĐąŅŠĐĩĐēŅ‚Đ°Đŧи { #using-streamingresponse-with-file-like-objects } + +Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ Ņ„Đ°ĐšĐģĐžĐŋОдОйĐŊŅ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐąŅŠĐĩĐēŅ‚, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧŅ‹Đš `open()`), Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ Đ´ĐģŅ Đ¸Ņ‚ĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋĐž ŅŅ‚ĐžĐŧ҃ Ņ„Đ°ĐšĐģĐžĐŋОдОйĐŊĐžĐŧ҃ ĐžĐąŅŠĐĩĐēŅ‚Ņƒ. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ваĐŧ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ҁĐŊĐ°Ņ‡Đ°Đģа Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ Đ˛ŅŅ‘ в ĐŋаĐŧŅŅ‚ŅŒ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ в `StreamingResponse` и вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐĩĐŗĐž. + +Đ­Ņ‚Đž вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ĐŧĐŊĐžĐŗĐ¸Đĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ОйĐģĐ°Ņ‡ĐŊŅ‹Đŧ Ņ…Ņ€Đ°ĐŊиĐģĐ¸Ņ‰ĐĩĐŧ, ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи видĐĩĐž и Ņ‚.Đ´. + +{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *} + +1. Đ­Ņ‚Đž Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€. ОĐŊа ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ÂĢŅ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐŧÂģ, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ ĐžĐŋĐĩŅ€Đ°Ņ‚ĐžŅ€(Ņ‹) `yield` вĐŊŅƒŅ‚Ņ€Đ¸. +2. Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐąĐģĐžĐē `with`, ĐŧŅ‹ ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩĐŧ, Ņ‡Ņ‚Đž Ņ„Đ°ĐšĐģĐžĐŋОдОйĐŊŅ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ ĐąŅƒĐ´ĐĩŅ‚ СаĐēҀҋ҂ ĐŋĐžŅĐģĐĩ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Đ°. ĐĸĐž ĐĩŅŅ‚ŅŒ ĐŋĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž, ĐēаĐē ĐžĐŊа СаĐēĐžĐŊŅ‡Đ¸Ņ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đē҃ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. +3. Đ­Ņ‚ĐžŅ‚ `yield from` ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Đ¸Ņ‚ĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ ĐŋĐž ĐžĐąŅŠĐĩĐēŅ‚Ņƒ ҁ иĐŧĐĩĐŊĐĩĐŧ `file_like`. И ĐˇĐ°Ņ‚ĐĩĐŧ, Đ´ĐģŅ ĐēаĐļдОК Đ¸Ņ‚ĐĩŅ€Đ°Ņ†Đ¸Đ¸, ĐžŅ‚Đ´Đ°Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ Ņ‡Đ°ŅŅ‚ŅŒ ĐēаĐē Đ¸ŅŅ…ĐžĐ´ŅŅ‰ŅƒŅŽ иС ŅŅ‚ĐžĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Đ° (`iterfile`). + + ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ŅŅ‚Đž Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€, ĐēĐžŅ‚ĐžŅ€Đ°Ņ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ Ņ€Đ°ĐąĐžŅ‚Ņƒ ĐŋĐž ÂĢĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸Âģ ҇ĐĩĐŧ҃-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐžĐŧ҃. + + ДĐĩĐģĐ°Ņ ŅŅ‚Đž Ņ‚Đ°ĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ ĐĩŅ‘ в ĐąĐģĐžĐē `with` и Ņ‚ĐĩĐŧ ŅĐ°ĐŧŅ‹Đŧ ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Ņ„Đ°ĐšĐģĐžĐŋОдОйĐŊŅ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ ĐąŅƒĐ´ĐĩŅ‚ СаĐēҀҋ҂ ĐŋĐžŅĐģĐĩ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ. + +/// tip | ХОвĐĩŅ‚ + +ЗаĐŧĐĩŅ‚ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž СдĐĩҁҌ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đš `open()`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŊĐĩ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ `async` и `await`, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸ ĐžĐąŅ‹Ņ‡ĐŊОК `def`. + +/// + +### `FileResponse` { #fileresponse } + +ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ Ņ„Đ°ĐšĐģ ĐēаĐē ĐžŅ‚Đ˛ĐĩŅ‚. + +ДĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ŅĐēСĐĩĐŧĐŋĐģŅŅ€Đ° ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ иĐŊОК ĐŊĐ°ĐąĐžŅ€ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ҇ĐĩĐŧ Đ´Ņ€ŅƒĐŗĐ¸Đĩ Ņ‚Đ¸ĐŋŅ‹ ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛: + +- `path` — ĐŋŅƒŅ‚ŅŒ Đē Ņ„Đ°ĐšĐģ҃, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊ. +- `headers` — ĐģŅŽĐąŅ‹Đĩ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи Đ´ĐģŅ вĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ, в видĐĩ ҁĐģĐžĐ˛Đ°Ņ€Ņ. +- `media_type` — ŅŅ‚Ņ€ĐžĐēа, ĐˇĐ°Đ´Đ°ŅŽŅ‰Đ°Ņ Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž. Đ•ŅĐģи ĐŊĐĩ СадаĐŊ, Đ´ĐģŅ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ Ņ‚Đ¸Đŋа ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐž иĐŧŅ Ņ„Đ°ĐšĐģа иĐģи ĐŋŅƒŅ‚ŅŒ. +- `filename` — ĐĩҁĐģи СадаĐŊ, ĐąŅƒĐ´ĐĩŅ‚ вĐēĐģŅŽŅ‡Ņ‘ĐŊ в ĐˇĐ°ĐŗĐžĐģОвОĐē ĐžŅ‚Đ˛ĐĩŅ‚Đ° `Content-Disposition`. + +ФаКĐģĐžĐ˛Ņ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ ĐąŅƒĐ´ŅƒŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи `Content-Length`, `Last-Modified` и `ETag`. + +{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *} + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_class`: + +{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *} + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ĐŋŅƒŅ‚ŅŒ Đē Ņ„Đ°ĐšĐģ҃ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС ŅĐ˛ĐžĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸. + +## ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° { #custom-response-class } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đš ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ°, ҃ĐŊĐ°ŅĐģĐĩĐ´ĐžĐ˛Đ°Đ˛ŅˆĐ¸ŅŅŒ ĐžŅ‚ `Response`, и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐžĐļиĐŧ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `orjson`, ĐŊĐž ҁ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đŧи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐŧи ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ŅŅ вО Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊĐžĐŧ ĐēĐģĐ°ŅŅĐĩ `ORJSONResponse`. + +ĐĄĐēаĐļĐĩĐŧ, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐģŅŅ ĐžŅ‚Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš JSON ҁ ĐžŅ‚ŅŅ‚ŅƒĐŋаĐŧи, Ņ‚Đž ĐĩŅŅ‚ŅŒ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ†Đ¸ŅŽ orjson `orjson.OPT_INDENT_2`. + +Đ’Ņ‹ ĐŧĐžĐŗĐģи ĐąŅ‹ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ `CustomORJSONResponse`. ГĐģавĐŊĐžĐĩ, Ņ‡Ņ‚Đž ваĐŧ ĐŊ҃ĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ — Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŧĐĩŅ‚ĐžĐ´ `Response.render(content)`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ ĐēаĐē `bytes`: + +{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *} + +ĐĸĐĩĐŋĐĩŅ€ŅŒ вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ: + +```json +{"message": "Hello World"} +``` + +...ŅŅ‚ĐžŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚ вĐĩŅ€ĐŊґ҂: + +```json +{ + "message": "Hello World" +} +``` + +Đ Đ°ĐˇŅƒĐŧĐĩĐĩŅ‚ŅŅ, Đ˛Ņ‹ ĐŊавĐĩŅ€ĐŊŅĐēа ĐŊĐ°ĐšĐ´Ņ‘Ņ‚Đĩ ĐŗĐžŅ€Đ°ĐˇĐ´Đž йОĐģĐĩĐĩ ĐŋĐžĐģĐĩСĐŊŅ‹Đĩ ҁĐŋĐžŅĐžĐąŅ‹ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ ŅŅ‚Đ¸Đŧ, ҇ĐĩĐŧ ĐŋŅ€ĐžŅŅ‚Đž Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ JSON. 😉 + +## КĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ { #default-response-class } + +ĐŸŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ŅĐēСĐĩĐŧĐŋĐģŅŅ€Đ° ĐēĐģĐ°ŅŅĐ° **FastAPI** иĐģи `APIRouter` Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ, ĐēаĐēОК ĐēĐģĐ°ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅŅ‚Đž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚, — `default_response_class`. + +В ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ĐŊиĐļĐĩ **FastAPI** ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `ORJSONResponse` ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ вО Đ˛ŅĐĩŅ… ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŅ… ĐŋŅƒŅ‚Đ¸ вĐŧĐĩŅŅ‚Đž `JSONResponse`. + +{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *} + +/// tip | ХОвĐĩŅ‚ + +Đ’Ņ‹ ĐŋĐž-ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ `response_class` в ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŅ… ĐŋŅƒŅ‚Đ¸, ĐēаĐē и Ņ€Đ°ĐŊҌ҈Đĩ. + +/// + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ { #additional-documentation } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž и ĐŧĐŊĐžĐŗĐ¸Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ Đ´ĐĩŅ‚Đ°Đģи в OpenAPI ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `responses`: [ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ в OpenAPI](additional-responses.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/dataclasses.md b/docs/ru/docs/advanced/dataclasses.md new file mode 100644 index 000000000..816f74404 --- /dev/null +++ b/docs/ru/docs/advanced/dataclasses.md @@ -0,0 +1,95 @@ +# Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ dataclasses { #using-dataclasses } + +FastAPI ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊ ĐŋОвĐĩҀ҅ **Pydantic**, и Ņ ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°Đģ ваĐŧ, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Pydantic-ĐŧОдĐĩĐģи Đ´ĐģŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ HTTP-СаĐŋŅ€ĐžŅĐžĐ˛ и HTTP-ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛. + +Но FastAPI Ņ‚Đ°ĐēĐļĐĩ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `dataclasses` Ņ‚ĐĩĐŧ ĐļĐĩ ҁĐŋĐžŅĐžĐąĐžĐŧ: + +{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *} + +Đ­Ņ‚Đž ĐŋĐž-ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ŅŅ ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ **Pydantic**, Ņ‚Đ°Đē ĐēаĐē в ĐŊŅ‘Đŧ ĐĩŅŅ‚ŅŒ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊĐ°Ņ ĐŋОддĐĩŅ€ĐļĐēа `dataclasses`. + +ĐĸаĐē Ņ‡Ņ‚Đž даĐļĐĩ ĐĩҁĐģи в ĐēОдĐĩ Đ˛Ņ‹ŅˆĐĩ Pydantic ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ŅĐ˛ĐŊĐž, FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Pydantic, Ņ‡Ņ‚ĐžĐąŅ‹ ĐēĐžĐŊвĐĩŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ dataclasses в ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đš Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ dataclasses ĐžŅ‚ Pydantic. + +И, ĐēĐžĐŊĐĩ҇ĐŊĐž, ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ Ņ‚Đĩ ĐļĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸: + +- ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ +- ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ +- Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ даĐŊĐŊҋ҅ и Ņ‚.Đ´. + +Đ­Ņ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Ņ‚Đ°Đē ĐļĐĩ, ĐēаĐē ҁ Pydantic-ĐŧОдĐĩĐģŅĐŧи. И ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ ĐŋОд ĐēаĐŋĐžŅ‚ĐžĐŧ ŅŅ‚Đž Đ´ĐžŅŅ‚Đ¸ĐŗĐ°ĐĩŅ‚ŅŅ Ņ‚ĐĩĐŧ ĐļĐĩ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Pydantic. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ПоĐŧĐŊĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž dataclasses ĐŊĐĩ ҃ĐŧĐĩŅŽŅ‚ Đ˛ŅĐĩĐŗĐž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž ҃ĐŧĐĩŅŽŅ‚ Pydantic-ĐŧОдĐĩĐģи. + +ĐŸĐžŅŅ‚ĐžĐŧ҃ ваĐŧ Đ˛ŅŅ‘ Đĩ҉ґ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Pydantic-ĐŧОдĐĩĐģи. + +Но ĐĩҁĐģи ҃ Đ˛Đ°Ņ ҃ĐļĐĩ ĐĩŅŅ‚ŅŒ ĐŊĐ°ĐąĐžŅ€ dataclasses, ŅŅ‚Đž ĐŋĐžĐģĐĩСĐŊŅ‹Đš ĐŋŅ€Đ¸Ņ‘Đŧ — СадĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… Đ´ĐģŅ вĐĩĐą-API ĐŊа FastAPI. 🤓 + +/// + +## Dataclasses в `response_model` { #dataclasses-in-response-model } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `dataclasses` в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂ҀĐĩ `response_model`: + +{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *} + +Đ­Ņ‚ĐžŅ‚ dataclass ĐąŅƒĐ´ĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊ в Pydantic dataclass. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐĩĐŗĐž ҁ҅ĐĩĐŧа ĐŋĐžŅĐ˛Đ¸Ņ‚ŅŅ в иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API: + + + +## Dataclasses вО вĐģĐžĐļĐĩĐŊĐŊҋ҅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ°Ņ… даĐŊĐŊҋ҅ { #dataclasses-in-nested-data-structures } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ `dataclasses` ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đĩ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņ‹ даĐŊĐŊҋ҅. + +В ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ваĐŧ Đ˛ŅŅ‘ ĐļĐĩ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ вĐĩŅ€ŅĐ¸ŅŽ `dataclasses` иС Pydantic. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ҃ Đ˛Đ°Ņ вОСĐŊиĐēĐ°ŅŽŅ‚ ĐžŅˆĐ¸ĐąĐēи ҁ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩĐŧОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš API. + +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžŅŅ‚Đž СаĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ `dataclasses` ĐŊа `pydantic.dataclasses`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧОК СаĐŧĐĩĐŊОК (drop-in replacement): + +{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *} + +1. ĐœŅ‹ ĐŋĐž-ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐĩĐŧ `field` иС ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊҋ҅ `dataclasses`. + +2. `pydantic.dataclasses` — ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐ°Ņ СаĐŧĐĩĐŊа (drop-in replacement) Đ´ĐģŅ `dataclasses`. + +3. Dataclass `Author` ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ ҁĐŋĐ¸ŅĐžĐē dataclass `Item`. + +4. Dataclass `Author` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂ҀĐĩ `response_model`. + +5. Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв вĐŧĐĩҁ҂Đĩ ҁ dataclasses в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ°. + + В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž ҁĐŋĐ¸ŅĐžĐē dataclass `Item`. + +6. ЗдĐĩҁҌ ĐŧŅ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧ ҁĐģĐžĐ˛Đ°Ņ€ŅŒ, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš `items`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ҁĐŋĐ¸ŅĐēĐžĐŧ dataclass. + + FastAPI ĐŋĐž-ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ ҁĐŋĐžŅĐžĐąĐĩĐŊ ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ даĐŊĐŊŅ‹Đĩ в JSON. + +7. ЗдĐĩҁҌ `response_model` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŽ Ņ‚Đ¸Đŋа — ҁĐŋĐ¸ŅĐžĐē dataclass `Author`. + + ĐĄĐŊОва, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ `dataclasses` ŅĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đŧи аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв. + +8. ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž ŅŅ‚Đ° *Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸* Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš `def` вĐŧĐĩŅŅ‚Đž `async def`. + + КаĐē и Đ˛ŅĐĩĐŗĐ´Đ° в FastAPI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžŅ‡ĐĩŅ‚Đ°Ņ‚ŅŒ `def` и `async def` ĐŋĐž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸. + + Đ•ŅĐģи Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐžŅĐ˛ĐĩĐļĐ¸Ņ‚ŅŒ в ĐŋаĐŧŅŅ‚Đ¸, ĐēĐžĐŗĐ´Đ° Ņ‡Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ, ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Ņ€Đ°ĐˇĐ´ĐĩĐģ _"НĐĩŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи?"_ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŋŅ€Đž [`async` и `await`](../async.md#in-a-hurry){.internal-link target=_blank}. + +9. Đ­Ņ‚Đ° *Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸* Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐŊĐĩ dataclasses (Ņ…ĐžŅ‚Ņ ĐŧĐžĐŗĐģа ĐąŅ‹), а ҁĐŋĐ¸ŅĐžĐē ҁĐģĐžĐ˛Đ°Ņ€ĐĩĐš ҁ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐŧи даĐŊĐŊŅ‹Đŧи. + + FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response_model` (в ĐēĐžŅ‚ĐžŅ€ĐžĐŧ СадаĐŊŅ‹ dataclasses), Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°Ņ‚ŅŒ HTTP-ĐžŅ‚Đ˛ĐĩŅ‚. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ `dataclasses` ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛ĐžĐŧ ҁĐŋĐžŅĐžĐąĐžĐ˛, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ„ĐžŅ€ĐŧĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁĐģĐžĐļĐŊŅ‹Đĩ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņ‹ даĐŊĐŊҋ҅. + +ĐĄĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ĐŋĐžĐ´ŅĐēаСĐēи в ĐēОдĐĩ Đ˛Ņ‹ŅˆĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ йОĐģĐĩĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ Đ´ĐĩŅ‚Đ°Đģи. + +## ĐŖĐˇĐŊĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ { #learn-more } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ `dataclasses` ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи Pydantic-ĐŧОдĐĩĐģŅĐŧи, ĐŊĐ°ŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ŅŒŅŅ ĐžŅ‚ ĐŊĐ¸Ņ…, вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ Đ¸Ņ… в ŅĐ˛ĐžĐ¸ ĐŧОдĐĩĐģи и Ņ‚.Đ´. + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ, ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Pydantic Đž dataclasses. + +## ВĐĩŅ€ŅĐ¸Ņ { #version } + +Đ”ĐžŅŅ‚ŅƒĐŋĐŊĐž ĐŊĐ°Ņ‡Đ¸ĐŊĐ°Ņ ҁ вĐĩŅ€ŅĐ¸Đ¸ FastAPI `0.67.0`. 🔖 diff --git a/docs/ru/docs/advanced/events.md b/docs/ru/docs/advanced/events.md new file mode 100644 index 000000000..6e1b49035 --- /dev/null +++ b/docs/ru/docs/advanced/events.md @@ -0,0 +1,165 @@ +# ĐĄĐžĐąŅ‹Ņ‚Đ¸Ņ lifespan { #lifespan-events } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģĐžĐŗĐ¸Đē҃ (ĐēОд), ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐ°Ņ‡ĐŊĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒŅŅ. Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ŅŅ‚ĐžŅ‚ ĐēОд ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊ ОдиĐŊ Ņ€Đ°Đˇ, ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ ĐēаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐ°Ņ‡ĐŊĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ HTTP-СаĐŋŅ€ĐžŅŅ‹. + +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģĐžĐŗĐ¸Đē҃ (ĐēОд), ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ, ĐēĐžĐŗĐ´Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ СавĐĩŅ€ŅˆĐ°ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Ņƒ. В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐēОд ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊ ОдиĐŊ Ņ€Đ°Đˇ, ĐŋĐžŅĐģĐĩ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи, вОСĐŧĐžĐļĐŊĐž, ĐŧĐŊĐžĐŗĐ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛. + +ĐŸĐžŅĐēĐžĐģҌĐē҃ ŅŅ‚ĐžŅ‚ ĐēОд Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ Đ´Đž Ņ‚ĐžĐŗĐž, ĐēаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚ ĐŋŅ€Đ¸ĐŊиĐŧĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹, и ŅŅ€Đ°ĐˇŅƒ ĐŋĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž, ĐēаĐē ĐžĐŊĐž СаĐēаĐŊŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ Đ¸Ņ… ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ, ĐžĐŊ ĐžŅ…Đ˛Đ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ вĐĩҁҌ lifespan (ĐļиСĐŊĐĩĐŊĐŊŅ‹Đš Ņ†Đ¸ĐēĐģ) ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ (ҁĐģОвО ÂĢlifespanÂģ ŅŅ‚Đ°ĐŊĐĩŅ‚ ваĐļĐŊŅ‹Đŧ ҇ĐĩŅ€ĐĩС ҁĐĩĐē҃ĐŊĐ´Ņƒ 😉). + +Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžŅ‡ĐĩĐŊҌ ĐŋĐžĐģĐĩСĐŊĐž Đ´ĐģŅ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊ҃ĐļĐŊŅ‹ Đ´ĐģŅ Đ˛ŅĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ€Đ°ĐˇĐ´ĐĩĐģŅŅŽŅ‚ŅŅ ĐŧĐĩĐļĐ´Ņƒ СаĐŋŅ€ĐžŅĐ°Đŧи и/иĐģи ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊ҃ĐļĐŊĐž ĐˇĐ°Ņ‚ĐĩĐŧ ĐžŅ‡Đ¸ŅŅ‚Đ¸Ņ‚ŅŒ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đŋ҃Đģ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊиК Đē йаСĐĩ даĐŊĐŊҋ҅ иĐģи ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐžĐąŅ‰ĐĩĐš ĐŧОдĐĩĐģи ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ. + +## Đ’Đ°Ņ€Đ¸Đ°ĐŊŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ { #use-case } + +ĐĐ°Ņ‡ĐŊĐĩĐŧ ҁ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚Đ° Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ, а ĐˇĐ°Ņ‚ĐĩĐŧ ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē ŅŅ‚Đž Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ. + +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧОдĐĩĐģĐĩĐš ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи СаĐŋŅ€ĐžŅĐžĐ˛. 🤖 + +Đ­Ņ‚Đ¸ ĐļĐĩ ĐŧОдĐĩĐģи Ņ€Đ°ĐˇĐ´ĐĩĐģŅŅŽŅ‚ŅŅ ĐŧĐĩĐļĐ´Ņƒ СаĐŋŅ€ĐžŅĐ°Đŧи, Ņ‚Đž ĐĩŅŅ‚ŅŒ ŅŅ‚Đž ĐŊĐĩ ОдĐŊа ĐŧОдĐĩĐģҌ ĐŊа СаĐŋŅ€ĐžŅ, ĐŊĐĩ ОдĐŊа ĐŊа ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и Ņ‚.Đŋ. + +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŧОдĐĩĐģи ĐŧĐžĐļĐĩŅ‚ СаĐŊиĐŧĐ°Ņ‚ŅŒ дОвОĐģҌĐŊĐž ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐĩĐš ĐŊ҃ĐļĐŊĐž ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ ĐŧĐŊĐžĐŗĐž даĐŊĐŊҋ҅ ҁ Đ´Đ¸ŅĐēа. ĐŸĐžŅŅ‚ĐžĐŧ҃ Đ˛Ņ‹ ĐŊĐĩ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°. + +Đ’Ņ‹ ĐŧĐžĐŗĐģи ĐąŅ‹ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŒ ĐĩŅ‘ ĐŊа вĐĩҀ҅ĐŊĐĩĐŧ ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐŧĐžĐ´ŅƒĐģŅ/Ņ„Đ°ĐšĐģа, ĐŊĐž ŅŅ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐģĐž ĐąŅ‹, Ņ‡Ņ‚Đž ĐŧОдĐĩĐģҌ ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩŅ‚ŅŅ даĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐŋŅ€ĐžŅŅ‚ĐžĐš Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиК Ņ‚Đĩҁ҂; Ņ‚ĐžĐŗĐ´Đ° ŅŅ‚ĐžŅ‚ Ņ‚Đĩҁ҂ ĐąŅƒĐ´ĐĩŅ‚ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đŧ, Ņ‚Đ°Đē ĐēаĐē ĐĩĐŧ҃ ĐŋŅ€Đ¸Đ´ĐĩŅ‚ŅŅ ĐļĐ´Đ°Ņ‚ŅŒ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи ĐŧОдĐĩĐģи ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧОК Ņ‡Đ°ŅŅ‚Đ¸ ĐēОда. + +ИĐŧĐĩĐŊĐŊĐž ŅŅ‚Đž ĐŧŅ‹ и Ņ€ĐĩŅˆĐ¸Đŧ: Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ĐˇĐ°ĐŗŅ€ŅƒĐļĐ°Ņ‚ŅŒ ĐŧОдĐĩĐģҌ ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŊĐ°Ņ‡ĐŊŅ‘Ņ‚ŅŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа СаĐŋŅ€ĐžŅĐžĐ˛, ĐŊĐž Ņ‚ĐžĐģҌĐēĐž ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐ°Ņ‡ĐŊĐĩŅ‚ ĐŋŅ€Đ¸ĐŊиĐŧĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹, а ĐŊĐĩ вО Đ˛Ņ€ĐĩĐŧŅ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи ĐēОда. + +## Lifespan { #lifespan } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģĐžĐŗĐ¸Đē҃ Đ´ĐģŅ startup и shutdown, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `lifespan` ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `FastAPI` и ÂĢĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°Âģ (҇ĐĩŅ€ĐĩС ҁĐĩĐē҃ĐŊĐ´Ņƒ ĐŋĐžĐēаĐļ҃ Ņ‡Ņ‚Đž ŅŅ‚Đž). + +ĐĐ°Ņ‡ĐŊĐĩĐŧ ҁ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°, а ĐˇĐ°Ņ‚ĐĩĐŧ Ņ€Đ°ĐˇĐąĐĩҀґĐŧ ĐĩĐŗĐž ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ. + +ĐœŅ‹ ŅĐžĐˇĐ´Đ°Ņ‘Đŧ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ `lifespan()` ҁ `yield` ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž Ņ‚Đ°Đē: + +{* ../../docs_src/events/tutorial003.py hl[16,19] *} + +ЗдĐĩҁҌ ĐŧŅ‹ ŅĐ¸Đŧ҃ĐģĐ¸Ņ€ŅƒĐĩĐŧ Đ´ĐžŅ€ĐžĐŗŅƒŅŽ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ startup ĐŋĐž ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēĐĩ ĐŧОдĐĩĐģи, ĐŋĐžĐŧĐĩŅ‰Đ°Ņ (Ņ„Đ¸ĐēŅ‚Đ¸Đ˛ĐŊŅƒŅŽ) Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ ĐŧОдĐĩĐģи в ҁĐģĐžĐ˛Đ°Ņ€ŅŒ ҁ ĐŧОдĐĩĐģŅĐŧи ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ Đ´Đž `yield`. Đ­Ņ‚ĐžŅ‚ ĐēОд ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊ Đ´Đž Ņ‚ĐžĐŗĐž, ĐēаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐ°Ņ‡ĐŊĐĩŅ‚ ĐŋŅ€Đ¸ĐŊиĐŧĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹, вО Đ˛Ņ€ĐĩĐŧŅ startup. + +А ĐˇĐ°Ņ‚ĐĩĐŧ ŅŅ€Đ°ĐˇŅƒ ĐŋĐžŅĐģĐĩ `yield` ĐŧŅ‹ Đ˛Ņ‹ĐŗŅ€ŅƒĐļаĐĩĐŧ ĐŧОдĐĩĐģҌ. Đ­Ņ‚ĐžŅ‚ ĐēОд ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊ ĐŋĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž, ĐēаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ СаĐēĐžĐŊŅ‡Đ¸Ņ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹, ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŋĐĩŅ€ĐĩĐ´ shutdown. Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžŅĐ˛ĐžĐąĐžĐ´Đ¸Ņ‚ŅŒ Ņ€ĐĩŅŅƒŅ€ŅŅ‹, Ņ‚Đ°ĐēиĐĩ ĐēаĐē ĐŋаĐŧŅŅ‚ŅŒ иĐģи GPU. + +/// tip | ХОвĐĩŅ‚ + +`shutdown` ĐŋŅ€ĐžĐ¸ĐˇĐžĐšĐ´Ņ‘Ņ‚, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐžŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. + +ВозĐŧĐžĐļĐŊĐž, ваĐŧ ĐŊ҃ĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŊĐžĐ˛ŅƒŅŽ вĐĩŅ€ŅĐ¸ŅŽ, иĐģи Đ˛Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž ŅƒŅŅ‚Đ°Đģи ĐžŅ‚ ĐŊĐĩĐŗĐž. 🤷 + +/// + +### Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ lifespan { #lifespan-function } + +ПĐĩŅ€Đ˛ĐžĐĩ, ĐŊа Ņ‡Ņ‚Đž ŅŅ‚ĐžĐ¸Ņ‚ ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒ вĐŊиĐŧаĐŊиĐĩ, — ĐŧŅ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩĐŧ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ ҁ `yield`. Đ­Ņ‚Đž ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ҁ `yield`. + +{* ../../docs_src/events/tutorial003.py hl[14:19] *} + +ПĐĩŅ€Đ˛Đ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, Đ´Đž `yield`, ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊа Đ´Đž СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. + +А Ņ‡Đ°ŅŅ‚ŅŒ ĐŋĐžŅĐģĐĩ `yield` ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊа ĐŋĐžŅĐģĐĩ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. + +### ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° { #async-context-manager } + +Đ•ŅĐģи ĐŋŅ€Đ¸ŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒŅŅ, Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ Đ´ĐĩĐēĐžŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊа `@asynccontextmanager`. + +Đ­Ņ‚Đž ĐŋŅ€ĐĩĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ в ÂĢĐ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°Âģ. + +{* ../../docs_src/events/tutorial003.py hl[1,13] *} + +МĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° в Python — ŅŅ‚Đž Ņ‚Đž, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в ĐžĐŋĐĩŅ€Đ°Ņ‚ĐžŅ€Đĩ `with`. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, `open()` ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐē ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°: + +```Python +with open("file.txt") as file: + file.read() +``` + +В ĐŋĐžŅĐģĐĩĐ´ĐŊĐ¸Ņ… вĐĩŅ€ŅĐ¸ŅŅ… Python ĐĩŅŅ‚ŅŒ Ņ‚Đ°ĐēĐļĐĩ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°. Đ•ĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ҁ `async with`: + +```Python +async with lifespan(app): + await do_stuff() +``` + +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚Đĩ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° иĐģи Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°, ĐēаĐē Đ˛Ņ‹ŅˆĐĩ, ĐžĐŊ ĐŋĐĩŅ€ĐĩĐ´ Đ˛Ņ…ĐžĐ´ĐžĐŧ в ĐąĐģĐžĐē `with` Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ ĐēОд Đ´Đž `yield`, а ĐŋĐžŅĐģĐĩ Đ˛Ņ‹Ņ…ĐžĐ´Đ° иС ĐąĐģĐžĐēа `with` Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ ĐēОд ĐŋĐžŅĐģĐĩ `yield`. + +В ĐŊĐ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ Đ˛Ņ‹ŅˆĐĩ ĐŧŅ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ĐĩĐŗĐž ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, а ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Đŧ ĐĩĐŗĐž в FastAPI, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ ĐĩĐŗĐž ŅĐ°Đŧ. + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `lifespan` ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `FastAPI` ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐĩĐŧ҃ ĐŊĐ°Ņˆ ĐŊĐžĐ˛Ņ‹Đš Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° `lifespan`. + +{* ../../docs_src/events/tutorial003.py hl[22] *} + +## АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅ‹Đĩ ŅĐžĐąŅ‹Ņ‚Đ¸Ņ (ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐ¸Đĩ) { #alternative-events-deprecated } + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩĐŧŅ‹Đš ҁĐŋĐžŅĐžĐą ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ startup и shutdown — Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `lifespan` ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `FastAPI`, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ. Đ•ŅĐģи Đ˛Ņ‹ ҃ĐēаĐļĐĩŅ‚Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `lifespan`, ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ŅĐžĐąŅ‹Ņ‚Đ¸Đš `startup` и `shutdown` йОĐģҌ҈Đĩ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒŅŅ ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚. Либо Đ˛ŅŅ‘ ҇ĐĩŅ€ĐĩС `lifespan`, ĐģийО Đ˛ŅŅ‘ ҇ĐĩŅ€ĐĩС ŅĐžĐąŅ‹Ņ‚Đ¸Ņ — ĐŊĐĩ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž. + +Đ­Ņ‚Ņƒ Ņ‡Đ°ŅŅ‚ŅŒ, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ. + +/// + +Đ•ŅŅ‚ŅŒ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅ‹Đš ҁĐŋĐžŅĐžĐą ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģĐžĐŗĐ¸Đē҃, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ вО Đ˛Ņ€ĐĩĐŧŅ startup и вО Đ˛Ņ€ĐĩĐŧŅ shutdown. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ŅĐžĐąŅ‹Ņ‚Đ¸Đš (Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸), ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ Đ´Đž ŅŅ‚Đ°Ņ€Ņ‚Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ иĐģи ĐŋŅ€Đ¸ ĐĩĐŗĐž СавĐĩŅ€ŅˆĐĩĐŊии. + +Đ­Ņ‚Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ҁ `async def` иĐģи ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def`. + +### ĐĄĐžĐąŅ‹Ņ‚Đ¸Đĩ `startup` { #startup-event } + +Đ§Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŊ҃ĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Đ´Đž ŅŅ‚Đ°Ņ€Ņ‚Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐžĐąŅŠŅĐ˛Đ¸Ņ‚Đĩ ĐĩŅ‘ ĐēаĐē ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ŅĐžĐąŅ‹Ņ‚Đ¸Ņ `"startup"`: + +{* ../../docs_src/events/tutorial001.py hl[8] *} + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ŅĐžĐąŅ‹Ņ‚Đ¸Ņ `startup` иĐŊĐ¸Ņ†Đ¸Đ°ĐģĐ¸ĐˇĐ¸Ņ€ŅƒĐĩŅ‚ ÂĢĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅Âģ items (ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž `dict`) ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đŧи СĐŊĐ°Ņ‡ĐĩĐŊĐ¸ŅĐŧи. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ йОĐģĐĩĐĩ ОдĐŊĐžĐŗĐž ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ŅĐžĐąŅ‹Ņ‚Đ¸Ņ. + +И Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐĩ ĐŊĐ°Ņ‡ĐŊĐĩŅ‚ ĐŋŅ€Đ¸ĐŊиĐŧĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹, ĐŋĐžĐēа Đ˛ŅĐĩ ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ŅĐžĐąŅ‹Ņ‚Đ¸Ņ `startup` ĐŊĐĩ СавĐĩŅ€ŅˆĐ°Ņ‚ŅŅ. + +### ĐĄĐžĐąŅ‹Ņ‚Đ¸Đĩ `shutdown` { #shutdown-event } + +Đ§Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŊ҃ĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ СавĐĩŅ€ŅˆĐĩĐŊии Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐžĐąŅŠŅĐ˛Đ¸Ņ‚Đĩ ĐĩŅ‘ ĐēаĐē ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ŅĐžĐąŅ‹Ņ‚Đ¸Ņ `"shutdown"`: + +{* ../../docs_src/events/tutorial002.py hl[6] *} + +ЗдĐĩҁҌ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ŅĐžĐąŅ‹Ņ‚Đ¸Ņ `shutdown` СаĐŋĐ¸ŅˆĐĩŅ‚ ŅŅ‚Ņ€ĐžĐē҃ Ņ‚ĐĩĐēŅŅ‚Đ° `"Application shutdown"` в Ņ„Đ°ĐšĐģ `log.txt`. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ `open()` ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `mode="a"` ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚ ÂĢдОйавĐģĐĩĐŊиĐĩÂģ (append), Ņ‚Đž ĐĩŅŅ‚ŅŒ ŅŅ‚Ņ€ĐžĐēа ĐąŅƒĐ´ĐĩŅ‚ дОйавĐģĐĩĐŊа в ĐēĐžĐŊĐĩ҆ Ņ„Đ°ĐšĐģа, ĐąĐĩС ĐŋĐĩŅ€ĐĩСаĐŋĐ¸ŅĐ¸ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐŗĐž ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž. + +/// + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž в ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅƒŅŽ Python-Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ `open()`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ŅƒĐĩŅ‚ ҁ Ņ„Đ°ĐšĐģĐžĐŧ. + +ĐĸĐž ĐĩŅŅ‚ŅŒ ŅŅ‚Đž I/O (ввОд/Đ˛Ņ‹Đ˛ĐžĐ´), ҂ҀĐĩĐąŅƒŅŽŅ‰Đ¸Đš ÂĢĐžĐļидаĐŊĐ¸ŅÂģ СаĐŋĐ¸ŅĐ¸ ĐŊа Đ´Đ¸ŅĐē. + +Но `open()` ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ `async` и `await`. + +ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐŧŅ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ŅĐžĐąŅ‹Ņ‚Đ¸Ņ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def` вĐŧĐĩŅŅ‚Đž `async def`. + +/// + +### `startup` и `shutdown` вĐŧĐĩҁ҂Đĩ { #startup-and-shutdown-together } + +ĐĄ Đ˛Ņ‹ŅĐžĐēОК вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ ĐģĐžĐŗĐ¸Đēа Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž startup и shutdown ŅĐ˛ŅĐˇĐ°ĐŊа: Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Ņ…ĐžŅ‚ĐĩŅ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ, а ĐˇĐ°Ņ‚ĐĩĐŧ СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŒ, ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ€ĐĩŅŅƒŅ€Ņ, а ĐˇĐ°Ņ‚ĐĩĐŧ ĐžŅĐ˛ĐžĐąĐžĐ´Đ¸Ņ‚ŅŒ ĐĩĐŗĐž и Ņ‚.Đ´. + +ДĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž в ĐžŅ‚Đ´ĐĩĐģҌĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ…, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐĩ Ņ€Đ°ĐˇĐ´ĐĩĐģŅŅŽŅ‚ ĐžĐąŅ‰ŅƒŅŽ ĐģĐžĐŗĐ¸Đē҃ иĐģи ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ, ҁĐģĐžĐļĐŊĐĩĐĩ, Ņ‚Đ°Đē ĐēаĐē ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ Ņ…Ņ€Đ°ĐŊĐ¸Ņ‚ŅŒ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ в ĐŗĐģОйаĐģҌĐŊҋ҅ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ иĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžŅ…ĐžĐļиĐĩ ĐŋŅ€Đ¸Ņ‘ĐŧŅ‹. + +ĐŸĐžŅŅ‚ĐžĐŧ҃ Ņ‚ĐĩĐŋĐĩŅ€ŅŒ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `lifespan`, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ. + +## ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи { #technical-details } + +НĐĩĐŧĐŊĐžĐŗĐž Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēĐ¸Ņ… ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚ĐĩĐš Đ´ĐģŅ ĐģŅŽĐąĐžĐŋҋ҂ĐŊҋ҅ ҃ĐŧĐŊиĐēОв. 🤓 + +Под ĐēаĐŋĐžŅ‚ĐžĐŧ, в ASGI-Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸, ŅŅ‚Đž Ņ‡Đ°ŅŅ‚ŅŒ ĐŸŅ€ĐžŅ‚ĐžĐēĐžĐģа Lifespan, и ĐžĐŊ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚ ŅĐžĐąŅ‹Ņ‚Đ¸Ņ `startup` и `shutdown`. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ йОĐģҌ҈Đĩ ĐŋŅ€Đž ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи `lifespan` в Starlette в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Starlette ĐŋĐž Lifespan. + +ВĐēĐģŅŽŅ‡Đ°Ņ Ņ‚Đž, ĐēаĐē Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ ŅĐžŅŅ‚ĐžŅĐŊиĐĩĐŧ lifespan, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в Đ´Ņ€ŅƒĐŗĐ¸Ņ… Ņ‡Đ°ŅŅ‚ŅŅ… Đ˛Đ°ŅˆĐĩĐŗĐž ĐēОда. + +/// + +## ПодĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ { #sub-applications } + +🚨 ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž ŅŅ‚Đ¸ ŅĐžĐąŅ‹Ņ‚Đ¸Ņ lifespan (startup и shutdown) ĐąŅƒĐ´ŅƒŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊŅ‹ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ĐžŅĐŊОвĐŊĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, а ĐŊĐĩ Đ´ĐģŅ [ПодĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — Mounts](sub-applications.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/generate-clients.md b/docs/ru/docs/advanced/generate-clients.md new file mode 100644 index 000000000..ee52412c6 --- /dev/null +++ b/docs/ru/docs/advanced/generate-clients.md @@ -0,0 +1,208 @@ +# ГĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ SDK { #generating-sdks } + +ĐŸĐžŅĐēĐžĐģҌĐē҃ **FastAPI** ĐžŅĐŊОваĐŊ ĐŊа ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ **OpenAPI**, ĐĩĐŗĐž API ĐŧĐžĐļĐŊĐž ĐžĐŋĐ¸ŅĐ°Ņ‚ŅŒ в ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊĐžĐŧ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ, ĐŋĐžĐŊŅŅ‚ĐŊĐžĐŧ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Ņƒ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. + +Đ­Ņ‚Đž ҃ĐŋŅ€ĐžŅ‰Đ°ĐĩŅ‚ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸ŅŽ аĐēŅ‚ŅƒĐ°ĐģҌĐŊОК **Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸**, ĐēĐģиĐĩĐŊ҂ҁĐēĐ¸Ņ… йийĐģĐ¸ĐžŅ‚ĐĩĐē (**SDKs**) ĐŊа Ņ€Đ°ĐˇĐŊҋ҅ ŅĐˇŅ‹ĐēĐ°Ņ…, а Ņ‚Đ°ĐēĐļĐĩ **Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ** иĐģи **Đ˛ĐžŅ€ĐēŅ„ĐģĐžŅƒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ°Ņ†Đ¸Đ¸**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžŅŅ‚Đ°ŅŽŅ‚ŅŅ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đŧи ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐēОдОĐŧ. + +В ŅŅ‚ĐžĐŧ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đĩ Đ˛Ņ‹ ŅƒĐˇĐŊаĐĩŅ‚Đĩ, ĐēаĐē ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ **TypeScript SDK** Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ĐąŅĐēĐĩĐŊда ĐŊа FastAPI. + +## ГĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Ņ‹ SDK ҁ ĐžŅ‚ĐēҀҋ҂ҋĐŧ Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đŧ ĐēОдОĐŧ { #open-source-sdk-generators } + +ГибĐēиК Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ — OpenAPI Generator, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ **ĐŧĐŊĐžĐŗĐ¸Đĩ ŅĐˇŅ‹Đēи ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ** и ҃ĐŧĐĩĐĩŅ‚ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ SDK иС Đ˛Đ°ŅˆĐĩĐš ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ OpenAPI. + +ДĐģŅ **TypeScript‑ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛** Hey API — ҁĐŋĐĩŅ†Đ¸Đ°ĐģĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ Ņ€Đĩ҈ĐĩĐŊиĐĩ, ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ŅŽŅ‰ĐĩĐĩ ĐžĐŋŅ‚Đ¸ĐŧаĐģҌĐŊŅ‹Đš ĐžĐŋҋ҂ Đ´ĐģŅ ŅĐēĐžŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ TypeScript. + +БоĐģҌ҈Đĩ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛ SDK ĐŧĐžĐļĐŊĐž ĐŊĐ°ĐšŅ‚Đ¸ ĐŊа OpenAPI.Tools. + +/// tip | ХОвĐĩŅ‚ + +FastAPI Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ **OpenAPI 3.1**, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐģŅŽĐąĐžĐš Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ Đ´ĐžĐģĐļĐĩĐŊ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ вĐĩŅ€ŅĐ¸ŅŽ. + +/// + +## ГĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Ņ‹ SDK ĐžŅ‚ ҁĐŋĐžĐŊŅĐžŅ€ĐžĐ˛ FastAPI { #sdk-generators-from-fastapi-sponsors } + +В ŅŅ‚ĐžĐŧ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģĐĩĐŊŅ‹ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ ҁ **вĐĩĐŊŅ‡ŅƒŅ€ĐŊОК ĐŋОддĐĩŅ€ĐļĐēОК** и **ĐŋОддĐĩŅ€ĐļĐēОК ĐēĐžĐŧĐŋаĐŊиК** ĐžŅ‚ ĐēĐžĐŧĐŋаĐŊиК, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐŋĐžĐŊŅĐ¸Ņ€ŅƒŅŽŅ‚ FastAPI. Đ­Ņ‚Đ¸ ĐŋŅ€ĐžĐ´ŅƒĐē҂ҋ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ **Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸** и **иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸** ŅĐ˛ĐĩҀ҅ Đ˛Ņ‹ŅĐžĐēĐžĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩĐŧҋ҅ SDK. + +БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ✨ [**ҁĐŋĐžĐŊŅĐžŅ€ŅŅ‚Đ˛Ņƒ FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ ŅŅ‚Đ¸ ĐēĐžĐŧĐŋаĐŊии ĐŋĐžĐŧĐžĐŗĐ°ŅŽŅ‚ ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°Ņ‚ŅŒ, Ņ‡Ņ‚ĐžĐąŅ‹ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē и ĐĩĐŗĐž **ŅĐēĐžŅĐ¸ŅŅ‚ĐĩĐŧа** ĐžŅŅ‚Đ°Đ˛Đ°ĐģĐ¸ŅŅŒ ĐˇĐ´ĐžŅ€ĐžĐ˛Ņ‹Đŧи и **ŅƒŅŅ‚ĐžĐšŅ‡Đ¸Đ˛Ņ‹Đŧи**. + +Đ˜Ņ… ҁĐŋĐžĐŊŅĐžŅ€ŅŅ‚Đ˛Đž Ņ‚Đ°ĐēĐļĐĩ Đ´ĐĩĐŧĐžĐŊŅŅ‚Ņ€Đ¸Ņ€ŅƒĐĩŅ‚ ҁĐĩŅ€ŅŒŅ‘ĐˇĐŊŅƒŅŽ ĐŋŅ€Đ¸Đ˛ĐĩŅ€ĐļĐĩĐŊĐŊĐžŅŅ‚ŅŒ **ŅĐžĐžĐąŅ‰ĐĩŅŅ‚Đ˛Ņƒ** FastAPI (ваĐŧ), ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ, Ņ‡Ņ‚Đž иĐŧ ваĐļĐŊĐž ĐŊĐĩ Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅ‚ŅŒ **ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ**, ĐŊĐž и ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ **ĐŊĐ°Đ´Ņ‘ĐļĐŊŅ‹Đš и ĐŋŅ€ĐžŅ†Đ˛ĐĩŅ‚Đ°ŅŽŅ‰Đ¸Đš ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē** FastAPI. 🙇 + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ: + +* Speakeasy +* Stainless +* liblab + +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ иС ŅŅ‚Đ¸Ņ… Ņ€Đĩ҈ĐĩĐŊиК Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ open source иĐģи иĐŧĐĩŅ‚ŅŒ ĐąĐĩҁĐŋĐģĐ°Ņ‚ĐŊŅ‹Đĩ Ņ‚Đ°Ņ€Đ¸Ņ„Ņ‹, Ņ‚Đ°Đē Ņ‡Ņ‚Đž Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… ĐąĐĩС Ņ„Đ¸ĐŊаĐŊŅĐžĐ˛Ņ‹Ņ… ĐˇĐ°Ņ‚Ņ€Đ°Ņ‚. Đ”Ņ€ŅƒĐŗĐ¸Đĩ ĐēĐžĐŧĐŧĐĩҀ҇ĐĩҁĐēиĐĩ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Ņ‹ SDK Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹ и Đ¸Ņ… ĐŧĐžĐļĐŊĐž ĐŊĐ°ĐšŅ‚Đ¸ ĐžĐŊĐģаКĐŊ. 🤓 + +## ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ TypeScript SDK { #create-a-typescript-sdk } + +ĐĐ°Ņ‡ĐŊŅ‘Đŧ ҁ ĐŋŅ€ĐžŅŅ‚ĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI: + +{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *} + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ (ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸)* ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅŽŅ‚ ĐŧОдĐĩĐģи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžĐŊи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ Đ´ĐģŅ ĐŋĐžĐģĐĩСĐŊОК ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи СаĐŋŅ€ĐžŅĐ° и ĐŋĐžĐģĐĩСĐŊОК ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи ĐžŅ‚Đ˛ĐĩŅ‚Đ°, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŧОдĐĩĐģĐĩĐš `Item` и `ResponseMessage`. + +### ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API { #api-docs } + +Đ•ŅĐģи ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ ĐŊа `/docs`, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ **ҁ҅ĐĩĐŧŅ‹** даĐŊĐŊҋ҅, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩĐŧҋ҅ в СаĐŋŅ€ĐžŅĐ°Ņ… и ĐŋŅ€Đ¸ĐŊиĐŧаĐĩĐŧҋ҅ в ĐžŅ‚Đ˛ĐĩŅ‚Đ°Ņ…: + + + +Đ’Ņ‹ Đ˛Đ¸Đ´Đ¸Ņ‚Đĩ ŅŅ‚Đ¸ ҁ҅ĐĩĐŧŅ‹, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐžĐŊи ĐąŅ‹Đģи ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊŅ‹ ҁ ĐŧОдĐĩĐģŅĐŧи в ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии. + +Đ­Ņ‚Đ° иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Đ´ĐžŅŅ‚ŅƒĐŋĐŊа в **ҁ҅ĐĩĐŧĐĩ OpenAPI** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ и ĐˇĐ°Ņ‚ĐĩĐŧ ĐžŅ‚ĐžĐąŅ€Đ°ĐļаĐĩŅ‚ŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API. + +Đĸа ĐļĐĩ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ иС ĐŧОдĐĩĐģĐĩĐš, вĐēĐģŅŽŅ‡Ņ‘ĐŊĐŊĐ°Ņ в OpenAPI, ĐŧĐžĐļĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ´ĐģŅ **ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐēĐģиĐĩĐŊ҂ҁĐēĐžĐŗĐž ĐēОда**. + +### Hey API { #hey-api } + +КаĐē Ņ‚ĐžĐģҌĐēĐž ҃ ĐŊĐ°Ņ ĐĩŅŅ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI ҁ ĐŧОдĐĩĐģŅĐŧи, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Hey API Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ TypeScript‑ĐēĐģиĐĩĐŊŅ‚Đ°. ХаĐŧŅ‹Đš ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đš ҁĐŋĐžŅĐžĐą ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž — ҇ĐĩŅ€ĐĩС npx. + +```sh +npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client +``` + +Đ­Ņ‚Đž ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ TypeScript SDK в `./src/client`. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ, ĐēаĐē ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ `@hey-api/openapi-ts` и ĐŋĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ Đž ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŧ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Đĩ ĐŊа Đ¸Ņ… ŅĐ°ĐšŅ‚Đĩ. + +### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ SDK { #using-the-sdk } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēĐģиĐĩĐŊ҂ҁĐēиК ĐēОд. Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē, ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ Đ´ĐģŅ ĐŧĐĩŅ‚ĐžĐ´oв: + + + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ Đ´ĐģŅ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩĐŧОК ĐŋĐžĐģĐĩСĐŊОК ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи: + + + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ ĐŊа Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ Đ´ĐģŅ `name` и `price`, ŅŅ‚Đž ĐąŅ‹ĐģĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐž в ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии FastAPI, в ĐŧОдĐĩĐģи `Item`. + +/// + +Đ’Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐžŅˆĐ¸ĐąĐēи ĐŋŅ€ŅĐŧĐž в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ Đ´ĐģŅ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩĐŧҋ҅ даĐŊĐŊҋ҅: + + + +ĐžĐąŅŠĐĩĐēŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚Đ° Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ: + + + +## ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI ҁ Ņ‚ĐĩĐŗĐ°Đŧи { #fastapi-app-with-tags } + +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI ĐąŅƒĐ´ĐĩŅ‚ йОĐģҌ҈Đĩ, и Đ˛Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐąŅƒĐ´ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐĩĐŗĐ¸, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ€Đ°ĐˇĐ´ĐĩĐģŅŅ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ ĐŗŅ€ŅƒĐŋĐŋŅ‹ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ€Đ°ĐˇĐ´ĐĩĐģ Đ´ĐģŅ **items** и Đ´Ņ€ŅƒĐŗĐžĐš Ņ€Đ°ĐˇĐ´ĐĩĐģ Đ´ĐģŅ **users**, и ĐžĐŊи ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩĐŊŅ‹ Ņ‚ĐĩĐŗĐ°Đŧи: + +{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *} + +### ГĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ TypeScript‑ĐēĐģиĐĩĐŊŅ‚Đ° ҁ Ņ‚ĐĩĐŗĐ°Đŧи { #generate-a-typescript-client-with-tags } + +Đ•ŅĐģи Đ˛Ņ‹ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚Đĩ ĐēĐģиĐĩĐŊŅ‚ Đ´ĐģŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ‚ĐĩĐŗĐžĐ˛, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐēĐģиĐĩĐŊ҂ҁĐēиК ĐēОд Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‘ĐŊ ĐŋĐž Ņ‚ĐĩĐŗĐ°Đŧ. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ иĐŧĐĩŅ‚ŅŒ Đ˛ŅŅ‘ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž ҃ĐŋĐžŅ€ŅĐ´ĐžŅ‡ĐĩĐŊĐŊŅ‹Đŧ и ŅĐŗŅ€ŅƒĐŋĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đŧ в ĐēĐģиĐĩĐŊ҂ҁĐēĐžĐŧ ĐēОдĐĩ: + + + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ: + +* `ItemsService` +* `UsersService` + +### ИĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ ĐēĐģиĐĩĐŊŅ‚Đ° { #client-method-names } + +ĐĄĐĩĐšŅ‡Đ°Ņ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ Đ˛Ņ€ĐžĐ´Đĩ `createItemItemsPost` Đ˛Ņ‹ĐŗĐģŅĐ´ŅŅ‚ ĐŊĐĩ ĐžŅ‡ĐĩĐŊҌ аĐēĐēŅƒŅ€Đ°Ņ‚ĐŊĐž: + +```TypeScript +ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) +``` + +...ŅŅ‚Đž ĐŋĐžŅ‚ĐžĐŧ҃, Ņ‡Ņ‚Đž ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ ĐēĐģиĐĩĐŊŅ‚Đ° Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиК **ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸** OpenAPI Đ´ĐģŅ ĐēаĐļдОК *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +OpenAPI ҂ҀĐĩĐąŅƒĐĩŅ‚, Ņ‡Ņ‚ĐžĐąŅ‹ ĐēаĐļĐ´Ņ‹Đš ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐąŅ‹Đģ ҃ĐŊиĐēаĐģĐĩĐŊ ҁҀĐĩди Đ˛ŅĐĩŅ… *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*, ĐŋĐžŅŅ‚ĐžĐŧ҃ FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ **иĐŧŅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸**, **ĐŋŅƒŅ‚ŅŒ** и **HTTP‑ĐŧĐĩŅ‚ĐžĐ´/ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ** Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ŅŅ‚ĐžĐŗĐž ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸, Ņ‚Đ°Đē ĐēаĐē Ņ‚Đ°ĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ĐŧĐžĐļĐŊĐž ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҃ĐŊиĐēаĐģҌĐŊĐžŅŅ‚ŅŒ ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš. + +Но даĐģĐĩĐĩ Ņ ĐŋĐžĐēаĐļ҃, ĐēаĐē ŅŅ‚Đž ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚ŅŒ. 🤓 + +## ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš и ĐģŅƒŅ‡ŅˆĐ¸Đĩ иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ { #custom-operation-ids-and-better-method-names } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ **иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ** ҁĐŋĐžŅĐžĐą **ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸** ŅŅ‚Đ¸Ņ… ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ Đ¸Ņ… ĐŋŅ€ĐžŅ‰Đĩ, а иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ в ĐēĐģиĐĩĐŊŅ‚Đ°Ņ… — **йОĐģĐĩĐĩ ĐŋŅ€ĐžŅŅ‚Ņ‹Đŧи**. + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ваĐŧ ĐŊ҃ĐļĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ОйĐĩҁĐŋĐĩŅ‡Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐēаĐļĐ´Ņ‹Đš ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐąŅ‹Đģ **҃ĐŊиĐēаĐģҌĐŊŅ‹Đŧ** Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁĐŋĐžŅĐžĐąĐžĐŧ. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ҃ ĐēаĐļдОК *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* ĐĩŅŅ‚ŅŒ Ņ‚ĐĩĐŗ, и ĐˇĐ°Ņ‚ĐĩĐŧ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŊа ĐžŅĐŊОвĐĩ **Ņ‚ĐĩĐŗĐ°** и **иĐŧĐĩĐŊи** *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* (иĐŧĐĩĐŊи Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸). + +### ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ҃ĐŊиĐēаĐģҌĐŊĐžĐŗĐž ID { #custom-generate-unique-id-function } + +FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ **҃ĐŊиĐēаĐģҌĐŊŅ‹Đš ID** Đ´ĐģŅ ĐēаĐļдОК *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋŅ€Đ¸ĐŧĐĩĐŊŅĐĩŅ‚ŅŅ Đ´ĐģŅ **ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸**, а Ņ‚Đ°ĐēĐļĐĩ Đ´ĐģŅ иĐŧŅ‘ĐŊ ĐģŅŽĐąŅ‹Ņ… ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… ĐŧОдĐĩĐģĐĩĐš СаĐŋŅ€ĐžŅĐžĐ˛ иĐģи ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐ°ŅŅ‚ĐžĐŧĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ. ОĐŊа ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ `APIRoute` и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ŅŅ‚Ņ€ĐžĐē҃. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, СдĐĩҁҌ ĐąĐĩŅ€Ņ‘Ņ‚ŅŅ ĐŋĐĩŅ€Đ˛Ņ‹Đš Ņ‚ĐĩĐŗ (ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž ҃ Đ˛Đ°Ņ ОдиĐŊ Ņ‚ĐĩĐŗ) и иĐŧŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* (иĐŧŅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸). + +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ в **FastAPI** ҇ĐĩŅ€ĐĩС ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `generate_unique_id_function`: + +{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *} + +### ГĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ TypeScript‑ĐēĐģиĐĩĐŊŅ‚Đ° ҁ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐŧи ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš { #generate-a-typescript-client-with-custom-operation-ids } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐĩҁĐģи ҁĐŊОва ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐēĐģиĐĩĐŊŅ‚, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ ҃ĐģŅƒŅ‡ŅˆĐ¸ĐģĐ¸ŅŅŒ: + + + +КаĐē Đ˛Đ¸Đ´Đ¸Ņ‚Đĩ, Ņ‚ĐĩĐŋĐĩŅ€ŅŒ иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ Ņ‚ĐĩĐŗ, а ĐˇĐ°Ņ‚ĐĩĐŧ иĐŧŅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸; йОĐģҌ҈Đĩ ĐžĐŊи ĐŊĐĩ вĐēĐģŅŽŅ‡Đ°ŅŽŅ‚ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ иС URL‑ĐŋŅƒŅ‚Đ¸ и HTTP‑оĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸. + +### ĐŸŅ€ĐĩĐ´ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ OpenAPI Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Đ° ĐēĐģиĐĩĐŊŅ‚Đ° { #preprocess-the-openapi-specification-for-the-client-generator } + +ĐĄĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŧ ĐēОдĐĩ Đ˛ŅŅ‘ Đĩ҉ґ ĐĩŅŅ‚ŅŒ **Đ´ŅƒĐąĐģĐ¸Ņ€ŅƒŅŽŅ‰Đ°ŅŅŅ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ**. + +ĐœŅ‹ ҃ĐļĐĩ СĐŊаĐĩĐŧ, Ņ‡Ņ‚Đž ŅŅ‚ĐžŅ‚ ĐŧĐĩŅ‚ĐžĐ´ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē **items**, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ŅŅ‚Đž ҁĐģОвО ĐĩŅŅ‚ŅŒ в `ItemsService` (Đ˛ĐˇŅŅ‚Đž иС Ņ‚ĐĩĐŗĐ°), ĐŊĐž ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ иĐŧŅ Ņ‚ĐĩĐŗĐ° Đ˛ŅŅ‘ Đĩ҉ґ дОйавĐģĐĩĐŊĐž ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ Đē иĐŧĐĩĐŊи ĐŧĐĩŅ‚ĐžĐ´Đ°. 😕 + +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž ĐŧŅ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Đŧ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ŅŅ‚Đž в OpenAPI в ҆ĐĩĐģĐžĐŧ, Ņ‚Đ°Đē ĐēаĐē ŅŅ‚Đž ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚, Ņ‡Ņ‚Đž ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐąŅƒĐ´ŅƒŅ‚ **҃ĐŊиĐēаĐģҌĐŊŅ‹**. + +Но Đ´ĐģŅ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž ĐēĐģиĐĩĐŊŅ‚Đ° ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ **ĐŧĐžĐ´Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ** ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš OpenAPI ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŋĐĩŅ€ĐĩĐ´ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸ĐĩĐš ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ йОĐģĐĩĐĩ ĐŋŅ€Đ¸ŅŅ‚ĐŊŅ‹Đŧи и **Ņ‡Đ¸ŅŅ‚Ņ‹Đŧи**. + +ĐœŅ‹ ĐŧĐžĐļĐĩĐŧ ҁĐēĐ°Ņ‡Đ°Ņ‚ŅŒ OpenAPI JSON в Ņ„Đ°ĐšĐģ `openapi.json`, а ĐˇĐ°Ņ‚ĐĩĐŧ **ŅƒĐąŅ€Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅâ€‘Ņ‚ĐĩĐŗ** Ņ‚Đ°ĐēиĐŧ ҁĐēŅ€Đ¸ĐŋŅ‚ĐžĐŧ: + +{* ../../docs_src/generate_clients/tutorial004.py *} + +//// tab | Node.js + +```Javascript +{!> ../../docs_src/generate_clients/tutorial004.js!} +``` + +//// + +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ID ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐąŅƒĐ´ŅƒŅ‚ ĐŋĐĩŅ€ĐĩиĐŧĐĩĐŊОваĐŊŅ‹ ҁ ҇ĐĩĐŗĐžâ€‘Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ `items-get_items` ĐŋŅ€ĐžŅŅ‚Đž в `get_items`, и ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ ĐēĐģиĐĩĐŊŅ‚Đ° ҁĐŧĐžĐļĐĩŅ‚ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ йОĐģĐĩĐĩ ĐŋŅ€ĐžŅŅ‚Ņ‹Đĩ иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛. + +### ГĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ TypeScript‑ĐēĐģиĐĩĐŊŅ‚Đ° ҁ ĐŋŅ€ĐĩĐ´ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐŊĐŊŅ‹Đŧ OpenAPI { #generate-a-typescript-client-with-the-preprocessed-openapi } + +ĐĸаĐē ĐēаĐē ĐēĐžĐŊĐĩ҇ĐŊŅ‹Đš Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ Ņ‚ĐĩĐŋĐĩŅ€ŅŒ в Ņ„Đ°ĐšĐģĐĩ `openapi.json`, ĐŊ҃ĐļĐŊĐž ОйĐŊĐžĐ˛Đ¸Ņ‚ŅŒ Đ˛Ņ…ĐžĐ´ĐŊĐžĐĩ Ņ€Đ°ŅĐŋĐžĐģĐžĐļĐĩĐŊиĐĩ: + +```sh +npx @hey-api/openapi-ts -i ./openapi.json -o src/client +``` + +ĐŸĐžŅĐģĐĩ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŊĐžĐ˛ĐžĐŗĐž ĐēĐģиĐĩĐŊŅ‚Đ° ҃ Đ˛Đ°Ņ ĐąŅƒĐ´ŅƒŅ‚ **Ņ‡Đ¸ŅŅ‚Ņ‹Đĩ иĐŧĐĩĐŊа ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛**, ŅĐž Đ˛ŅĐĩĐŧ **Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩĐŧ**, **ĐžŅˆĐ¸ĐąĐēаĐŧи ĐŋŅ€ŅĐŧĐž в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ** и Ņ‚.Đ´.: + + + +## ĐŸŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° { #benefits } + +ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ **Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ** Đ´ĐģŅ: + +* МĐĩŅ‚ĐžĐ´ĐžĐ˛. +* ДаĐŊĐŊҋ҅ СаĐŋŅ€ĐžŅĐ° — в Ņ‚ĐĩĐģĐĩ СаĐŋŅ€ĐžŅĐ°, query‑ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°Ņ… и Ņ‚.Đ´. +* ДаĐŊĐŊҋ҅ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +ĐŖ Đ˛Đ°Ņ Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ŅƒŅ‚ **ĐžŅˆĐ¸ĐąĐēи ĐŋŅ€ŅĐŧĐž в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ** Đ´ĐģŅ Đ˛ŅĐĩĐŗĐž. + +И ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ОйĐŊОвĐģŅĐĩŅ‚Đĩ ĐēОд ĐąŅĐēĐĩĐŊда и **ĐŋĐĩŅ€ĐĩĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚Đĩ** Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´, в ĐŊŅ‘Đŧ ĐŋĐžŅĐ˛ŅŅ‚ŅŅ ĐŊĐžĐ˛Ņ‹Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* ĐēаĐē ĐŧĐĩŅ‚ĐžĐ´Ņ‹, ŅŅ‚Đ°Ņ€Ņ‹Đĩ ĐąŅƒĐ´ŅƒŅ‚ ŅƒĐ´Đ°ĐģĐĩĐŊŅ‹, а ĐģŅŽĐąŅ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ĐžŅ‚Ņ€Đ°ĐˇŅŅ‚ŅŅ в ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŧ ĐēОдĐĩ. 🤓 + +Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐĩҁĐģи Ņ‡Ņ‚Đžâ€‘Ņ‚Đž иСĐŧĐĩĐŊиĐģĐžŅŅŒ, ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ **ĐžŅ‚Ņ€Đ°ĐļĐĩĐŊĐž** в ĐēĐģиĐĩĐŊ҂ҁĐēĐžĐŧ ĐēОдĐĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи. И ĐĩҁĐģи Đ˛Ņ‹ **ŅĐžĐąĐĩҀґ҂Đĩ** ĐēĐģиĐĩĐŊŅ‚, ĐžĐŊ СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŅ ҁ ĐžŅˆĐ¸ĐąĐēОК, ĐĩҁĐģи ĐŗĐ´Đĩâ€‘Ņ‚Đž ĐĩŅŅ‚ŅŒ **ĐŊĐĩŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đĩ** в Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ даĐŊĐŊҋ҅. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ˛Ņ‹ **ОйĐŊĐ°Ņ€ŅƒĐļĐ¸Ņ‚Đĩ ĐŧĐŊĐžĐŗĐ¸Đĩ ĐžŅˆĐ¸ĐąĐēи** ĐžŅ‡ĐĩĐŊҌ Ņ€Đ°ĐŊĐž в Ņ†Đ¸ĐēĐģĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи, вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž Ņ‡Ņ‚ĐžĐąŅ‹ ĐļĐ´Đ°Ņ‚ŅŒ, ĐēĐžĐŗĐ´Đ° ĐžŅˆĐ¸ĐąĐēи ĐŋŅ€ĐžŅĐ˛ŅŅ‚ŅŅ ҃ ĐēĐžĐŊĐĩ҇ĐŊҋ҅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ, и ĐˇĐ°Ņ‚ĐĩĐŧ ĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ ĐžŅ‚ĐģĐ°Đ´Đ¸Ņ‚ŅŒ, в ҇ґĐŧ ĐŋŅ€ĐžĐąĐģĐĩĐŧа. ✨ diff --git a/docs/ru/docs/advanced/index.md b/docs/ru/docs/advanced/index.md index b5cb733e7..c0a52c6c1 100644 --- a/docs/ru/docs/advanced/index.md +++ b/docs/ru/docs/advanced/index.md @@ -1,12 +1,12 @@ -# Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐžĐĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ +# Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐžĐĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ { #advanced-user-guide } -## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ { #additional-features } ĐžŅĐŊОвĐŊĐžĐĩ [ĐŖŅ‡ĐĩĐąĐŊиĐē - Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ](../tutorial/index.md){.internal-link target=_blank} Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋОСĐŊаĐēĐžĐŧĐ¸Ņ‚ŅŒ Đ˛Đ°Ņ ŅĐž Đ˛ŅĐĩĐŧи ĐžŅĐŊОвĐŊŅ‹Đŧи Ņ„ŅƒĐŊĐēŅ†Đ¸ŅĐŧи **FastAPI**. В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… Ņ€Đ°ĐˇĐ´ĐĩĐģĐ°Ņ… Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ Đ˛Đ°Ņ€Đ¸Đ°ĐŊ҂ҋ, ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ и Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸. -/// tip +/// tip | ХОвĐĩŅ‚ ĐĄĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‹ **ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž ŅĐ˛ĐģŅŅŽŅ‚ŅŅ "ĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Ņ‹Đŧи"**. @@ -14,7 +14,7 @@ /// -## ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ ĐŖŅ‡ĐĩĐąĐŊиĐē - Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ +## ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ ĐŖŅ‡ĐĩĐąĐŊиĐē - Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ { #read-the-tutorial-first } Đ’Ņ‹ Đ˛ŅĐĩ Đĩ҉Đĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Ņ„ŅƒĐŊĐēŅ†Đ¸Đš **FastAPI** ŅĐž СĐŊаĐŊĐ¸ŅĐŧи иС [ĐŖŅ‡ĐĩĐąĐŊиĐē - Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ](../tutorial/index.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/middleware.md b/docs/ru/docs/advanced/middleware.md new file mode 100644 index 000000000..28802fd57 --- /dev/null +++ b/docs/ru/docs/advanced/middleware.md @@ -0,0 +1,97 @@ +# Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐžĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ middleware { #advanced-middleware } + +В ĐžŅĐŊОвĐŊĐžĐŧ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đĩ Đ˛Ņ‹ Ņ‡Đ¸Ņ‚Đ°Đģи, ĐēаĐē Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ [ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐĩ middleware](../tutorial/middleware.md){.internal-link target=_blank} в Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. + +А ĐˇĐ°Ņ‚ĐĩĐŧ — ĐēаĐē Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ [CORS ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}. + +В ŅŅ‚ĐžĐŧ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ middleware. + +## ДобавĐģĐĩĐŊиĐĩ ASGI middleware { #adding-asgi-middlewares } + +ĐĸаĐē ĐēаĐē **FastAPI** ĐžŅĐŊОваĐŊ ĐŊа Starlette и Ņ€ĐĩаĐģĐ¸ĐˇŅƒĐĩŅ‚ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ŅŽ ASGI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐģŅŽĐąĐžĐĩ ASGI middleware. + +Middleware ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ŅĐ´ĐĩĐģаĐŊĐž ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊĐž Đ´ĐģŅ FastAPI иĐģи Starlette — Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊĐž ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ĐžĐ˛Đ°ĐģĐž ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ASGI. + +В ĐžĐąŅ‰ĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ASGI middleware — ŅŅ‚Đž ĐēĐģĐ°ŅŅŅ‹, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžĐļĐ¸Đ´Đ°ŅŽŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ASGI‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŋĐĩŅ€Đ˛Ņ‹Đŧ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ. + +ĐŸĐžŅŅ‚ĐžĐŧ҃ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Đē ŅŅ‚ĐžŅ€ĐžĐŊĐŊиĐŧ ASGI middleware, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Ņ‡Ņ‚Đžâ€‘Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ: + +```Python +from unicorn import UnicornMiddleware + +app = SomeASGIApp() + +new_app = UnicornMiddleware(app, some_config="rainbow") +``` + +Но FastAPI (Ņ‚ĐžŅ‡ĐŊĐĩĐĩ, Starlette) ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ йОĐģĐĩĐĩ ĐŋŅ€ĐžŅŅ‚ĐžĐš ҁĐŋĐžŅĐžĐą, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅƒŅŽ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đē҃ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐ¸Ņ… ĐžŅˆĐ¸ĐąĐžĐē ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅƒŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `app.add_middleware()` (ĐēаĐē в ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ҁ CORS). + +```Python +from fastapi import FastAPI +from unicorn import UnicornMiddleware + +app = FastAPI() + +app.add_middleware(UnicornMiddleware, some_config="rainbow") +``` + +`app.add_middleware()` ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ĐēĐģĐ°ŅŅ middleware в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŋĐĩŅ€Đ˛ĐžĐŗĐž Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚Đ° и ĐģŅŽĐąŅ‹Đĩ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐąŅƒĐ´ŅƒŅ‚ ĐŋĐĩŅ€ĐĩдаĐŊŅ‹ ŅŅ‚ĐžĐŧ҃ middleware. + +## Đ’ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đĩ middleware { #integrated-middlewares } + +**FastAPI** вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž middleware Đ´ĐģŅ Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅ‘ĐŊĐŊҋ҅ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đĩв. НиĐļĐĩ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē Đ¸Ņ… Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ. + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°Ņ… Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.middleware.something import SomethingMiddleware`. + +**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž middleware в `fastapi.middleware` Đ´ĐģŅ ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ° Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. Но йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ middleware ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС Starlette. + +/// + +## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware } + +Đ“Đ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚, Ņ‡Ņ‚Đž Đ˛ŅĐĩ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ СаĐŋŅ€ĐžŅŅ‹ Đ´ĐžĐģĐļĐŊŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐģийО `https`, ĐģийО `wss`. + +Đ›ŅŽĐąĐžĐš Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đš СаĐŋŅ€ĐžŅ ĐŋĐž `http` иĐģи `ws` ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐĩŅ€ĐĩĐŊаĐŋŅ€Đ°Đ˛ĐģĐĩĐŊ ĐŊа ĐąĐĩСОĐŋĐ°ŅĐŊŅƒŅŽ ҁ҅ĐĩĐŧ҃. + +{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *} + +## `TrustedHostMiddleware` { #trustedhostmiddleware } + +Đ“Đ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚, Ņ‡Ņ‚Đž вО Đ˛ŅĐĩŅ… Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐ°Ņ… ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ `Host`â€‘ĐˇĐ°ĐŗĐžĐģОвОĐē, Ņ‡Ņ‚ĐžĐąŅ‹ ĐˇĐ°Ņ‰Đ¸Ņ‚Đ¸Ņ‚ŅŒŅŅ ĐžŅ‚ Đ°Ņ‚Đ°Đē ĐŊа HTTPâ€‘ĐˇĐ°ĐŗĐžĐģОвОĐē Host. + +{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *} + +ПоддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ: + +- `allowed_hosts` — ҁĐŋĐ¸ŅĐžĐē Đ´ĐžĐŧĐĩĐŊĐŊҋ҅ иĐŧŅ‘ĐŊ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ Ņ€Đ°ĐˇŅ€ĐĩŅˆĐ¸Ņ‚ŅŒ ĐēаĐē иĐŧĐĩĐŊа Ņ…ĐžŅŅ‚ĐžĐ˛. ĐŸĐžĐ´ŅŅ‚Đ°ĐŊОвĐēи вида `*.example.com` ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ Đ´ĐģŅ ŅĐžĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐŋОддОĐŧĐĩĐŊОв. Đ§Ņ‚ĐžĐąŅ‹ Ņ€Đ°ĐˇŅ€ĐĩŅˆĐ¸Ņ‚ŅŒ ĐģŅŽĐąĐžĐš Ņ…ĐžŅŅ‚, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐģийО `allowed_hosts=["*"]`, ĐģийО ĐŊĐĩ дОйавĐģŅĐšŅ‚Đĩ ŅŅ‚Đž middleware. +- `www_redirect` — ĐĩҁĐģи ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐž в True, СаĐŋŅ€ĐžŅŅ‹ Đē ĐŊĐĩ‑www вĐĩŅ€ŅĐ¸ŅĐŧ Ņ€Đ°ĐˇŅ€ĐĩŅˆŅ‘ĐŊĐŊҋ҅ Ņ…ĐžŅŅ‚ĐžĐ˛ ĐąŅƒĐ´ŅƒŅ‚ ĐŋĐĩŅ€ĐĩĐŊаĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒŅŅ ĐŊа Đ¸Ņ… www‑аĐŊаĐģĐžĐŗĐ¸. По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ — `True`. + +Đ•ŅĐģи Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đš СаĐŋŅ€ĐžŅ ĐŊĐĩ ĐŋŅ€ĐžŅ…ĐžĐ´Đ¸Ņ‚ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ, ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊ ĐžŅ‚Đ˛ĐĩŅ‚ `400`. + +## `GZipMiddleware` { #gzipmiddleware } + +ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ GZipâ€‘ĐžŅ‚Đ˛Đĩ҂ҋ Đ´ĐģŅ ĐģŅŽĐąŅ‹Ņ… СаĐŋŅ€ĐžŅĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ вĐēĐģŅŽŅ‡Đ°ŅŽŅ‚ `"gzip"` в ĐˇĐ°ĐŗĐžĐģОвĐēĐĩ `Accept-Encoding`. + +Đ­Ņ‚Đž middleware ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đĩ, Ņ‚Đ°Đē и ĐŋĐžŅ‚ĐžĐēĐžĐ˛Ņ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ. + +{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *} + +ПоддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ: + +- `minimum_size` — ĐŊĐĩ ҁĐļиĐŧĐ°Ņ‚ŅŒ GZip‑оĐŧ ĐžŅ‚Đ˛Đĩ҂ҋ, Ņ€Đ°ĐˇĐŧĐĩŅ€ ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŧĐĩĐŊҌ҈Đĩ ŅŅ‚ĐžĐŗĐž ĐŧиĐŊиĐŧаĐģҌĐŊĐžĐŗĐž СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ в ĐąĐ°ĐšŅ‚Đ°Ņ…. По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ — `500`. +- `compresslevel` — ŅƒŅ€ĐžĐ˛ĐĩĐŊҌ GZipâ€‘ŅĐļĐ°Ņ‚Đ¸Ņ. ĐĻĐĩĐģĐžĐĩ Ņ‡Đ¸ŅĐģĐž ĐžŅ‚ 1 Đ´Đž 9. По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ — `9`. БоĐģĐĩĐĩ ĐŊиСĐēĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ — ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩĐĩ ҁĐļĐ°Ņ‚Đ¸Đĩ, ĐŊĐž йОĐģŅŒŅˆĐ¸Đš Ņ€Đ°ĐˇĐŧĐĩŅ€ Ņ„Đ°ĐšĐģа; йОĐģĐĩĐĩ Đ˛Ņ‹ŅĐžĐēĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ — йОĐģĐĩĐĩ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊĐžĐĩ ҁĐļĐ°Ņ‚Đ¸Đĩ, ĐŊĐž ĐŧĐĩĐŊŅŒŅˆĐ¸Đš Ņ€Đ°ĐˇĐŧĐĩŅ€ Ņ„Đ°ĐšĐģа. + +## Đ”Ņ€ŅƒĐŗĐ¸Đĩ middleware { #other-middlewares } + +ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŧĐŊĐžĐŗĐž Đ´Ņ€ŅƒĐŗĐ¸Ņ… ASGI middleware. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +- `ProxyHeadersMiddleware` ĐžŅ‚ Uvicorn +- MessagePack + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ middleware, ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŋĐž middleware в Starlette и ҁĐŋĐ¸ŅĐžĐē ASGI Awesome. diff --git a/docs/ru/docs/advanced/openapi-callbacks.md b/docs/ru/docs/advanced/openapi-callbacks.md new file mode 100644 index 000000000..faf58370b --- /dev/null +++ b/docs/ru/docs/advanced/openapi-callbacks.md @@ -0,0 +1,186 @@ +# ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đĩ Đ˛Ņ‹ĐˇĐžĐ˛Ņ‹ в OpenAPI { #openapi-callbacks } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ API ҁ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐĩĐš ĐŋŅƒŅ‚Đ¸* (ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ ĐŋŅƒŅ‚Đ¸), ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐąŅƒĐ´ĐĩŅ‚ иĐŊĐ¸Ņ†Đ¸Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ HTTP-СаĐŋŅ€ĐžŅ Đē *вĐŊĐĩ҈ĐŊĐĩĐŧ҃ API*, ŅĐžĐˇĐ´Đ°ĐŊĐŊĐžĐŧ҃ ĐēĐĩĐŧ-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐ¸Đŧ (ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž Ņ‚ĐĩĐŧ ĐļĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛Đ°Ņˆ API). + +ĐŸŅ€ĐžŅ†Đĩҁҁ, ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´ŅŅ‰Đ¸Đš, ĐēĐžĐŗĐ´Đ° Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ API ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ Đē *вĐŊĐĩ҈ĐŊĐĩĐŧ҃ API*, ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ ÂĢcallbackÂģ (ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đš Đ˛Ņ‹ĐˇĐžĐ˛). ĐŸŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐŊĐžĐĩ ОйĐĩҁĐŋĐĩ҇ĐĩĐŊиĐĩ, ĐŊаĐŋĐ¸ŅĐ°ĐŊĐŊĐžĐĩ вĐŊĐĩ҈ĐŊиĐŧ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ HTTP-СаĐŋŅ€ĐžŅ Đ˛Đ°ŅˆĐĩĐŧ҃ API, а ĐˇĐ°Ņ‚ĐĩĐŧ Đ˛Đ°Ņˆ API Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đš Đ˛Ņ‹ĐˇĐžĐ˛, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ HTTP-СаĐŋŅ€ĐžŅ вО *вĐŊĐĩ҈ĐŊиК API* (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Ņ‚ĐžĐļĐĩ ŅĐžĐˇĐ´Đ°Đģ Ņ‚ĐžŅ‚ ĐļĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē). + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ваĐŧ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ, ĐēаĐē Đ´ĐžĐģĐļĐŊĐž Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ ŅŅ‚Đž вĐŊĐĩ҈ĐŊĐĩĐĩ API: ĐēаĐēŅƒŅŽ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* ĐžĐŊĐž Đ´ĐžĐģĐļĐŊĐž иĐŧĐĩŅ‚ŅŒ, ĐēаĐēĐžĐĩ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ, ĐēаĐēОК ĐžŅ‚Đ˛ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ и Ņ‚.Đ´. + +## ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁ ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đŧи Đ˛Ņ‹ĐˇĐžĐ˛Đ°Đŧи { #an-app-with-callbacks } + +Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ŅŅ‚Đž ĐŊа ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ. + +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Ņ€Đ°ĐˇŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, ĐŋОСвОĐģŅŅŽŅ‰ĐĩĐĩ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ ҁ҇ĐĩŅ‚Đ°. + +Đ­Ņ‚Đ¸ ҁ҇ĐĩŅ‚Đ° ĐąŅƒĐ´ŅƒŅ‚ иĐŧĐĩŅ‚ŅŒ `id`, `title` (ĐŊĐĩĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš), `customer` и `total`. + +ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ Đ˛Đ°ŅˆĐĩĐŗĐž API (вĐŊĐĩ҈ĐŊиК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē) ŅĐžĐˇĐ´Đ°ŅŅ‚ ҁ҇ĐĩŅ‚ в Đ˛Đ°ŅˆĐĩĐŧ API ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ POST-СаĐŋŅ€ĐžŅĐ°. + +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Đ°Ņˆ API (ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐžĐļиĐŧ) ŅĐ´ĐĩĐģаĐĩŅ‚ ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐĩ: + +* ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ ҁ҇ĐĩŅ‚ ĐēĐģиĐĩĐŊŅ‚Ņƒ вĐŊĐĩ҈ĐŊĐĩĐŗĐž Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. +* ПоĐģŅƒŅ‡Đ¸Ņ‚ ĐžĐŋĐģĐ°Ņ‚Ņƒ. +* ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊиĐĩ ĐžĐąŅ€Đ°Ņ‚ĐŊĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅŽ API (вĐŊĐĩ҈ĐŊĐĩĐŧ҃ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē҃). + * Đ­Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ŅĐ´ĐĩĐģаĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐēОК POST-СаĐŋŅ€ĐžŅĐ° (иС *Đ˛Đ°ŅˆĐĩĐŗĐž API*) в *вĐŊĐĩ҈ĐŊиК API*, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐŊŅ‹Đš ŅŅ‚Đ¸Đŧ вĐŊĐĩ҈ĐŊиĐŧ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ (ŅŅ‚Đž и ĐĩŅŅ‚ŅŒ ÂĢcallbackÂģ). + +## ĐžĐąŅ‹Ņ‡ĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** { #the-normal-fastapi-app } + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ ĐžĐąŅ‹Ņ‡ĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ API Đ´Đž дОйавĐģĐĩĐŊĐ¸Ņ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ°. + +В ĐŊŅ‘Đŧ ĐąŅƒĐ´ĐĩŅ‚ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° `Invoice`, и query-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `callback_url`, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš URL Đ´ĐģŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ°. + +Đ­Ņ‚Đ° Ņ‡Đ°ŅŅ‚ŅŒ вĐŋĐžĐģĐŊĐĩ ĐžĐąŅ‹Ņ‡ĐŊа, йОĐģŅŒŅˆĐ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ ĐēОда ваĐŧ ҃ĐļĐĩ СĐŊаĐēĐžĐŧа: + +{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *} + +/// tip | ХОвĐĩŅ‚ + +Query-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `callback_url` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Ņ‚Đ¸Đŋ Pydantic Url. + +/// + +ЕдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ ĐŊОвОĐĩ — ŅŅ‚Đž `callbacks=invoices_callback_router.routes` в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚Đ° *Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đ° ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. ДаĐģĐĩĐĩ Ņ€Đ°ĐˇĐąĐĩҀґĐŧŅŅ, Ņ‡Ņ‚Đž ŅŅ‚Đž Ņ‚Đ°ĐēĐžĐĩ. + +## ДоĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° { #documenting-the-callback } + +Đ ĐĩаĐģҌĐŊŅ‹Đš ĐēОд ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° ĐąŅƒĐ´ĐĩŅ‚ ŅĐ¸ĐģҌĐŊĐž ĐˇĐ°Đ˛Đ¸ŅĐĩŅ‚ŅŒ ĐžŅ‚ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ API. + +И, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ СаĐŧĐĩŅ‚ĐŊĐž ĐžŅ‚ĐģĐ¸Ņ‡Đ°Ņ‚ŅŒŅŅ ĐžŅ‚ ОдĐŊĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ Đē Đ´Ņ€ŅƒĐŗĐžĐŧ҃. + +Đ­Ņ‚Đž ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐąŅƒĐēваĐģҌĐŊĐž ОдĐŊа-двĐĩ ŅŅ‚Ņ€ĐžĐēи ĐēОда, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +```Python +callback_url = "https://example.com/api/v1/invoices/events/" +httpx.post(callback_url, json={"description": "Invoice paid", "paid": True}) +``` + +Но, вОСĐŧĐžĐļĐŊĐž, ŅĐ°ĐŧĐ°Ņ ваĐļĐŊĐ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° — ŅŅ‚Đž ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ Đ˛Đ°ŅˆĐĩĐŗĐž API (вĐŊĐĩ҈ĐŊиК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē) ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž Ņ€ĐĩаĐģĐ¸ĐˇŅƒĐĩŅ‚ *вĐŊĐĩ҈ĐŊиК API* в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đ¸ ҁ даĐŊĐŊŅ‹Đŧи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ *Đ˛Đ°Ņˆ API* ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ в Ņ‚ĐĩĐģĐĩ СаĐŋŅ€ĐžŅĐ° ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° и Ņ‚.Đŋ. + +ĐŸĐžŅŅ‚ĐžĐŧ҃ даĐģĐĩĐĩ ĐŧŅ‹ дОйавиĐŧ ĐēОд, Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ŅƒŅŽŅ‰Đ¸Đš, ĐēаĐē Đ´ĐžĐģĐļĐĩĐŊ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ ŅŅ‚ĐžŅ‚ *вĐŊĐĩ҈ĐŊиК API*, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đš Đ˛Ņ‹ĐˇĐžĐ˛ ĐžŅ‚ *Đ˛Đ°ŅˆĐĩĐŗĐž API*. + +Đ­Ņ‚Đ° Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ ĐžŅ‚ĐžĐąŅ€Đ°ĐˇĐ¸Ņ‚ŅŅ в Swagger UI ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ `/docs` в Đ˛Đ°ŅˆĐĩĐŧ API и ĐŋОСвОĐģĐ¸Ņ‚ вĐŊĐĩ҈ĐŊиĐŧ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧ ĐŋĐžĐŊŅŅ‚ŅŒ, ĐēаĐē ĐŋĐžŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ *вĐŊĐĩ҈ĐŊиК API*. + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ŅĐ°Đŧ ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đš Đ˛Ņ‹ĐˇĐžĐ˛ ĐŊĐĩ Ņ€ĐĩаĐģĐ¸ĐˇŅƒĐĩŅ‚ŅŅ (ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ˛ŅĐĩĐŗĐž ОдĐŊа ŅŅ‚Ņ€ĐžĐēа ĐēОда), Ņ€ĐĩаĐģĐ¸ĐˇŅƒĐĩŅ‚ŅŅ Ņ‚ĐžĐģҌĐēĐž Ņ‡Đ°ŅŅ‚ŅŒ ҁ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš. + +/// tip | ХОвĐĩŅ‚ + +ХаĐŧ ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đš Đ˛Ņ‹ĐˇĐžĐ˛ — ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ HTTP-СаĐŋŅ€ĐžŅ. + +Đ ĐĩаĐģĐ¸ĐˇŅƒŅ ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đš Đ˛Ņ‹ĐˇĐžĐ˛, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, HTTPX иĐģи Requests. + +/// + +## НаĐŋĐ¸ŅˆĐ¸Ņ‚Đĩ ĐēОд Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° { #write-the-callback-documentation-code } + +Đ­Ņ‚ĐžŅ‚ ĐēОд ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ в Đ˛Đ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии, ĐžĐŊ ĐŊ҃ĐļĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ *Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ* Ņ‚ĐžĐŗĐž, ĐēаĐē Đ´ĐžĐģĐļĐĩĐŊ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ *вĐŊĐĩ҈ĐŊиК API*. + +Но Đ˛Ņ‹ ҃ĐļĐĩ СĐŊаĐĩŅ‚Đĩ, ĐēаĐē ĐģĐĩĐŗĐēĐž ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Đ´ĐģŅ API ҁ **FastAPI**. + +ĐœŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Ņ‚Đĩ ĐļĐĩ СĐŊаĐŊĐ¸Ņ, Ņ‡Ņ‚ĐžĐąŅ‹ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ, ĐēаĐē Đ´ĐžĐģĐļĐĩĐŊ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ *вĐŊĐĩ҈ĐŊиК API*... ŅĐžĐˇĐ´Đ°Đ˛ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ вĐŊĐĩ҈ĐŊиК API Đ´ĐžĐģĐļĐĩĐŊ Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ (Ņ‚Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ°Ņˆ API ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ). + +/// tip | ХОвĐĩŅ‚ + +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŋĐ¸ŅˆĐĩŅ‚Đĩ ĐēОд Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ°, ĐŋĐžĐģĐĩСĐŊĐž ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž Đ˛Ņ‹ — Ņ‚ĐžŅ‚ ŅĐ°ĐŧŅ‹Đš *вĐŊĐĩ҈ĐŊиК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē*. И Ņ‡Ņ‚Đž Đ˛Ņ‹ ҁĐĩĐšŅ‡Đ°Ņ Ņ€ĐĩаĐģĐ¸ĐˇŅƒĐĩŅ‚Đĩ *вĐŊĐĩ҈ĐŊиК API*, а ĐŊĐĩ *ŅĐ˛ĐžĐš API*. + +Đ’Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐĩ ĐŋŅ€Đ¸ĐŊŅŅ‚Đ¸Đĩ ŅŅ‚ĐžĐš Ņ‚ĐžŅ‡Đēи ĐˇŅ€ĐĩĐŊĐ¸Ņ (вĐŊĐĩ҈ĐŊĐĩĐŗĐž Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа) ĐŋĐžĐŧĐžĐļĐĩŅ‚ иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐž ĐŋĐžĐŊŅŅ‚ŅŒ, ĐēŅƒĐ´Đ° ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ, ĐēаĐēŅƒŅŽ Pydantic-ĐŧОдĐĩĐģҌ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐģŅ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ°, Đ´ĐģŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° и Ņ‚.Đ´. вО *вĐŊĐĩ҈ĐŊĐĩĐŧ API*. + +/// + +### ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ `APIRouter` Đ´ĐģŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° { #create-a-callback-apirouter } + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŊĐžĐ˛Ņ‹Đš `APIRouter`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ОдиĐŊ иĐģи ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐžĐąŅ€Đ°Ņ‚ĐŊҋ҅ Đ˛Ņ‹ĐˇĐžĐ˛ĐžĐ˛. + +{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *} + +### ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° { #create-the-callback-path-operation } + +Đ§Ņ‚ĐžĐąŅ‹ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ°, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ Ņ‚ĐžŅ‚ ĐļĐĩ `APIRouter`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Đģи Đ˛Ņ‹ŅˆĐĩ. + +ОĐŊа Đ´ĐžĐģĐļĐŊа Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸* FastAPI: + +* ВĐĩŅ€ĐžŅŅ‚ĐŊĐž, в ĐŊĐĩĐš Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊиĐĩ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ°, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `body: InvoiceEvent`. +* А Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊиĐĩ ĐŧОдĐĩĐģи ĐžŅ‚Đ˛ĐĩŅ‚Đ°, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `response_model=InvoiceEventReceived`. + +{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *} + +Đ•ŅŅ‚ŅŒ 2 ĐžŅĐŊОвĐŊҋ҅ ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Ņ ĐžŅ‚ ĐžĐąŅ‹Ņ‡ĐŊОК *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*: + +* Ей ĐŊĐĩ ĐŊ҃ĐļĐĩĐŊ Ņ€ĐĩаĐģҌĐŊŅ‹Đš ĐēОд, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊиĐēĐžĐŗĐ´Đ° ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ. ОĐŊа Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ *вĐŊĐĩ҈ĐŊĐĩĐŗĐž API*. ĐŸĐžŅŅ‚ĐžĐŧ҃ в Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Đž `pass`. +* *ĐŸŅƒŅ‚ŅŒ* ĐŧĐžĐļĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Đ˛Ņ‹Ņ€Đ°ĐļĐĩĐŊиĐĩ OpenAPI 3 (ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ĐŊиĐļĐĩ), ĐŗĐ´Đĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ҁ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°Đŧи и Ņ‡Đ°ŅŅ‚Đ¸ Đ¸ŅŅ…ĐžĐ´ĐŊĐžĐŗĐž HTTP-СаĐŋŅ€ĐžŅĐ°, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊĐžĐŗĐž *Đ˛Đ°ŅˆĐĩĐŧ҃ API*. + +### Đ’Ņ‹Ņ€Đ°ĐļĐĩĐŊиĐĩ ĐŋŅƒŅ‚Đ¸ Đ´ĐģŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° { #the-callback-path-expression } + +*ĐŸŅƒŅ‚ŅŒ* ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° ĐŧĐžĐļĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Đ˛Ņ‹Ņ€Đ°ĐļĐĩĐŊиĐĩ OpenAPI 3, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŧĐžĐļĐĩŅ‚ вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ Ņ‡Đ°ŅŅ‚Đ¸ Đ¸ŅŅ…ĐžĐ´ĐŊĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊĐžĐŗĐž *Đ˛Đ°ŅˆĐĩĐŧ҃ API*. + +В ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž `str`: + +```Python +"{$callback_url}/invoices/{$request.body.id}" +``` + +Đ˜Ņ‚Đ°Đē, ĐĩҁĐģи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ Đ˛Đ°ŅˆĐĩĐŗĐž API (вĐŊĐĩ҈ĐŊиК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē) ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ HTTP-СаĐŋŅ€ĐžŅ Đ˛Đ°ŅˆĐĩĐŧ҃ API ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃: + +``` +https://yourapi.com/invoices/?callback_url=https://www.external.org/events +``` + +ҁ Ņ‚ĐĩĐģĐžĐŧ JSON: + +```JSON +{ + "id": "2expen51ve", + "customer": "Mr. Richie Rich", + "total": "9999" +} +``` + +Ņ‚Đž *Đ˛Đ°Ņˆ API* ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ҁ҇ґ҂ и, в ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ĐŋОСĐļĐĩ, ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ СаĐŋŅ€ĐžŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° ĐŊа `callback_url` (*вĐŊĐĩ҈ĐŊиК API*): + +``` +https://www.external.org/events/invoices/2expen51ve +``` + +ҁ Ņ‚ĐĩĐģĐžĐŧ JSON ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž Ņ‚Đ°ĐēĐžĐŗĐž вида: + +```JSON +{ + "description": "Payment celebration", + "paid": true +} +``` + +и ĐąŅƒĐ´ĐĩŅ‚ ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ ĐžŅ‚ *вĐŊĐĩ҈ĐŊĐĩĐŗĐž API* ĐžŅ‚Đ˛ĐĩŅ‚ ҁ Ņ‚ĐĩĐģĐžĐŧ JSON вида: + +```JSON +{ + "ok": true +} +``` + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đš URL ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ URL, ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đš ĐēаĐē query-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ в `callback_url` (`https://www.external.org/events`), а Ņ‚Đ°ĐēĐļĐĩ `id` ŅŅ‡Ņ‘Ņ‚Đ° иС Ņ‚ĐĩĐģа JSON (`2expen51ve`). + +/// + +### ПодĐēĐģŅŽŅ‡Đ¸Ņ‚Đĩ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ‚ĐžŅ€ ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° { #add-the-callback-router } + +К ŅŅ‚ĐžĐŧ҃ ĐŧĐžĐŧĐĩĐŊŅ‚Ņƒ ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* ĐžĐąŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° (Ņ‚Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ *вĐŊĐĩ҈ĐŊиК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē* Đ´ĐžĐģĐļĐĩĐŊ Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ вО *вĐŊĐĩ҈ĐŊĐĩĐŧ API*) в ŅĐžĐˇĐ´Đ°ĐŊĐŊĐžĐŧ Đ˛Ņ‹ŅˆĐĩ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ‚ĐžŅ€Đĩ ĐžĐąŅ€Đ°Ņ‚ĐŊҋ҅ Đ˛Ņ‹ĐˇĐžĐ˛ĐžĐ˛. + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `callbacks` в *Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ Đ˛Đ°ŅˆĐĩĐŗĐž API*, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `.routes` (ŅŅ‚Đž, ĐŋĐž ŅŅƒŅ‚Đ¸, ĐŋŅ€ĐžŅŅ‚Đž `list` ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚ĐžĐ˛/*ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*) иС ŅŅ‚ĐžĐŗĐž ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ‚ĐžŅ€Đ° ĐžĐąŅ€Đ°Ņ‚ĐŊҋ҅ Đ˛Ņ‹ĐˇĐžĐ˛ĐžĐ˛: + +{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *} + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚Đĩ ĐŊĐĩ ŅĐ°Đŧ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ‚ĐžŅ€ (`invoices_callback_router`) в `callback=`, а ĐĩĐŗĐž Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `.routes`, Ņ‚Đž ĐĩŅŅ‚ŅŒ `invoices_callback_router.routes`. + +/// + +### ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ { #check-the-docs } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ и ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:8000/docs. + +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, вĐēĐģŅŽŅ‡Đ°ŅŽŅ‰ŅƒŅŽ Ņ€Đ°ĐˇĐ´ĐĩĐģ ÂĢCallbacksÂģ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚, ĐēаĐē Đ´ĐžĐģĐļĐĩĐŊ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ *вĐŊĐĩ҈ĐŊиК API*: + + diff --git a/docs/ru/docs/advanced/openapi-webhooks.md b/docs/ru/docs/advanced/openapi-webhooks.md new file mode 100644 index 000000000..d38cf315f --- /dev/null +++ b/docs/ru/docs/advanced/openapi-webhooks.md @@ -0,0 +1,55 @@ +# ВĐĩĐąŅ…ŅƒĐēи OpenAPI { #openapi-webhooks } + +Đ‘Ņ‹Đ˛Đ°ŅŽŅ‚ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐžĐžĐąŅ‰Đ¸Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ Đ˛Đ°ŅˆĐĩĐŗĐž API, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ (ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Đ˛ HTTP-СаĐŋŅ€ĐžŅ) ҁ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đŧи даĐŊĐŊŅ‹Đŧи, ĐžĐąŅ‹Ņ‡ĐŊĐž Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐ¸Ņ‚ŅŒ Đž ĐēаĐēĐžĐŧ-Ņ‚Đž ŅĐžĐąŅ‹Ņ‚Đ¸Đ¸. + +Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž вĐŧĐĩŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°, ĐēĐžĐŗĐ´Đ° ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģи ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‚ СаĐŋŅ€ĐžŅŅ‹ Đ˛Đ°ŅˆĐĩĐŧ҃ API, Đ˛Đ°Ņˆ API (иĐģи Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ) ĐŧĐžĐļĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ в Đ¸Ņ… ŅĐ¸ŅŅ‚ĐĩĐŧ҃ (в Đ¸Ņ… API, Đ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ). + +ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ вĐĩĐąŅ…ŅƒĐēĐžĐŧ. + +## Đ¨Đ°ĐŗĐ¸ вĐĩĐąŅ…ŅƒĐēОв { #webhooks-steps } + +ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŋŅ€ĐžŅ†Đĩҁҁ Ņ‚Đ°ĐēОв: Đ˛Ņ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚Đĩ в ŅĐ˛ĐžĐĩĐŧ ĐēОдĐĩ, ĐēаĐēĐžĐĩ ŅĐžĐžĐąŅ‰ĐĩĐŊиĐĩ Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ, Ņ‚Đž ĐĩŅŅ‚ŅŒ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ°. + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚Đĩ, в ĐēаĐēиĐĩ ĐŧĐžĐŧĐĩĐŊ҂ҋ (ĐŋŅ€Đ¸ ĐēаĐēĐ¸Ņ… ŅĐžĐąŅ‹Ņ‚Đ¸ŅŅ…) Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ ŅŅ‚Đ¸ СаĐŋŅ€ĐžŅŅ‹. + +А Đ˛Đ°ŅˆĐ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģи ĐēаĐēиĐŧ-Ņ‚Đž ĐžĐąŅ€Đ°ĐˇĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в вĐĩб‑ĐŋаĐŊĐĩĐģи) ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ URL-Đ°Đ´Ņ€Đĩҁ, ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ´ĐžĐģĐļĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ ŅŅ‚Đ¸ СаĐŋŅ€ĐžŅŅ‹. + +Đ’ŅŅ ĐģĐžĐŗĐ¸Đēа Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ URL-Đ°Đ´Ņ€ĐĩŅĐžĐ˛ Đ´ĐģŅ вĐĩĐąŅ…ŅƒĐēОв и ĐēОд, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€ĐĩаĐģҌĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ ŅŅ‚Đ¸ СаĐŋŅ€ĐžŅŅ‹, ҆ĐĩĐģиĐēĐžĐŧ ĐŊа Đ˛Đ°ŅˆĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊĐĩ. Đ’Ņ‹ ĐŋĐ¸ŅˆĐĩŅ‚Đĩ ŅŅ‚Đž Ņ‚Đ°Đē, ĐēаĐē ваĐŧ ĐŊ҃ĐļĐŊĐž, в ŅĐ˛ĐžĐĩĐŧ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐŧ ĐēОдĐĩ. + +## ДоĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ вĐĩĐąŅ…ŅƒĐēОв ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ FastAPI и OpenAPI { #documenting-webhooks-with-fastapi-and-openapi } + +ĐĄ FastAPI, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ OpenAPI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ иĐŧĐĩĐŊа ŅŅ‚Đ¸Ņ… вĐĩĐąŅ…ŅƒĐēОв, Ņ‚Đ¸ĐŋŅ‹ HTTP-ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `POST`, `PUT` и Ņ‚.Đ´.), а Ņ‚Đ°ĐēĐļĐĩ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ. + +Đ­Ņ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž ҃ĐŋŅ€ĐžŅŅ‚Đ¸Ņ‚ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ Đ¸Ņ… API Đ´ĐģŅ ĐŋŅ€Đ¸ĐĩĐŧа Đ˛Đ°ŅˆĐ¸Ņ… вĐĩĐąŅ…ŅƒĐē-СаĐŋŅ€ĐžŅĐžĐ˛; вОСĐŧĐžĐļĐŊĐž, ĐžĐŊи даĐļĐĩ ҁĐŧĐžĐŗŅƒŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Ņ‡Đ°ŅŅ‚ŅŒ ĐēОда ŅĐ˛ĐžĐĩĐŗĐž API. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ВĐĩĐąŅ…ŅƒĐēи Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹ в OpenAPI 3.1.0 и Đ˛Ņ‹ŅˆĐĩ, ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ в FastAPI `0.99.0` и ĐŊОвĐĩĐĩ. + +/// + +## ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁ вĐĩĐąŅ…ŅƒĐēаĐŧи { #an-app-with-webhooks } + +ĐŸŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŊа **FastAPI** ĐĩŅŅ‚ŅŒ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `webhooks`, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ вĐĩĐąŅ…ŅƒĐēи Ņ‚Đ°Đē ĐļĐĩ, ĐēаĐē Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ (ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸), ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ҁ `@app.webhooks.post()`. + +{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *} + +ОĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐŊŅ‹Đĩ ваĐŧи вĐĩĐąŅ…ŅƒĐēи ĐŋĐžĐŋĐ°Đ´ŅƒŅ‚ в ҁ҅ĐĩĐŧ҃ **OpenAPI** и в Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиК **иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸**. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐžĐąŅŠĐĩĐēŅ‚ `app.webhooks` ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ — ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš `APIRouter`, Ņ‚ĐžŅ‚ ĐļĐĩ Ņ‚Đ¸Đŋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐŋŅ€Đ¸ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋĐž ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧ Ņ„Đ°ĐšĐģаĐŧ. + +/// + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ: в ҁĐģŅƒŅ‡Đ°Đĩ ҁ вĐĩĐąŅ…ŅƒĐēаĐŧи Đ˛Ņ‹ ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ ĐŊĐĩ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ ĐŋŅƒŅ‚ŅŒ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `/items/`), ĐŋĐĩŅ€ĐĩдаваĐĩĐŧŅ‹Đš Ņ‚ŅƒĐ´Đ° Ņ‚ĐĩĐēҁ҂ — ŅŅ‚Đž ĐģĐ¸ŅˆŅŒ идĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžŅ€ вĐĩĐąŅ…ŅƒĐēа (иĐŧŅ ŅĐžĐąŅ‹Ņ‚Đ¸Ņ). НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в `@app.webhooks.post("new-subscription")` иĐŧŅ вĐĩĐąŅ…ŅƒĐēа — `new-subscription`. + +Đ­Ņ‚Đž ŅĐ˛ŅĐˇĐ°ĐŊĐž ҁ Ņ‚ĐĩĐŧ, Ņ‡Ņ‚Đž ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚ŅŅ: Ņ„Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēиК URL‑ĐŋŅƒŅ‚ŅŒ, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ ĐžĐŊи Ņ…ĐžŅ‚ŅŅ‚ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ вĐĩĐąŅ…ŅƒĐēа, Đ˛Đ°ŅˆĐ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģи ҃ĐēаĐļŅƒŅ‚ ĐēаĐēиĐŧ-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в вĐĩб‑ĐŋаĐŊĐĩĐģи). + +### ĐŸĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ { #check-the-docs } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ и ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ ĐŋĐž ҁҁҋĐģĐēĐĩ http://127.0.0.1:8000/docs. + +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐĩŅŅ‚ŅŒ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸, а Ņ‚Đ°ĐēĐļĐĩ ĐŋĐžŅĐ˛Đ¸ĐģĐ¸ŅŅŒ вĐĩĐąŅ…ŅƒĐēи: + + diff --git a/docs/ru/docs/advanced/path-operation-advanced-configuration.md b/docs/ru/docs/advanced/path-operation-advanced-configuration.md new file mode 100644 index 000000000..fcb3cd47f --- /dev/null +++ b/docs/ru/docs/advanced/path-operation-advanced-configuration.md @@ -0,0 +1,204 @@ +# Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐ°Ņ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸ { #path-operation-advanced-configuration } + +## OpenAPI operationId { #openapi-operationid } + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ•ŅĐģи Đ˛Ņ‹ ĐŊĐĩ ÂĢŅĐēҁĐŋĐĩҀ҂Âģ ĐŋĐž OpenAPI, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ŅŅ‚Đž ваĐŧ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž. + +/// + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ OpenAPI `operationId`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ в Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `operation_id`. + +ĐŅƒĐļĐŊĐž ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž ĐžĐŊ ҃ĐŊиĐēаĐģĐĩĐŊ Đ´ĐģŅ ĐēаĐļдОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸. + +{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} + +### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ иĐŧĐĩĐŊи Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸ ĐēаĐē operationId { #using-the-path-operation-function-name-as-the-operationid } + +Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ иĐŧĐĩĐŊа Ņ„ŅƒĐŊĐēŅ†Đ¸Đš Đ˛Đ°ŅˆĐ¸Ņ… API в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ `operationId`, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐšŅ‚Đ¸ ĐŋĐž Đ˛ŅĐĩĐŧ иС ĐŊĐ¸Ņ… и ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ `operation_id` ĐēаĐļдОК *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Đ¸Ņ… `APIRoute.name`. + +ДĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐŋĐžŅĐģĐĩ дОйавĐģĐĩĐŊĐ¸Ņ Đ˛ŅĐĩŅ… *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*. + +{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *} + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи Đ˛Ņ‹ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ `app.openapi()` Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ, ОйĐŊĐžĐ˛Đ¸Ņ‚Đĩ `operationId` Đ´Đž ŅŅ‚ĐžĐŗĐž. + +/// + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ•ŅĐģи Đ˛Ņ‹ Đ´ĐĩĐģаĐĩŅ‚Đĩ ŅŅ‚Đž, ŅƒĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž ĐēаĐļĐ´Đ°Ņ иС Đ˛Đ°ŅˆĐ¸Ņ… *Ņ„ŅƒĐŊĐēŅ†Đ¸Đš-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв ĐŋŅƒŅ‚Đ¸* иĐŧĐĩĐĩŅ‚ ҃ĐŊиĐēаĐģҌĐŊĐžĐĩ иĐŧŅ. + +ДаĐļĐĩ ĐĩҁĐģи ĐžĐŊи ĐŊĐ°Ņ…ĐžĐ´ŅŅ‚ŅŅ в Ņ€Đ°ĐˇĐŊҋ҅ ĐŧĐžĐ´ŅƒĐģŅŅ… (Ņ„Đ°ĐšĐģĐ°Ņ… Python). + +/// + +## Đ˜ŅĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ иС OpenAPI { #exclude-from-openapi } + +Đ§Ņ‚ĐžĐąŅ‹ Đ¸ŅĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* иС ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩĐŧОК ҁ҅ĐĩĐŧŅ‹ OpenAPI (а СĐŊĐ°Ņ‡Đ¸Ņ‚, и иС Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸), Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `include_in_schema` и ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ ĐĩĐŗĐž в `False`: + +{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} + +## Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐžĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ иС docstring { #advanced-description-from-docstring } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡Đ¸Ņ‚ŅŒ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ŅŅ‚Ņ€ĐžĐē иС docstring *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸*, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ Đ´ĐģŅ OpenAPI. + +ДобавĐģĐĩĐŊиĐĩ `\f` (ŅĐēŅ€Đ°ĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž ŅĐ¸ĐŧвОĐģа ÂĢform feedÂģ) ĐˇĐ°ŅŅ‚Đ°Đ˛Đ¸Ņ‚ **FastAPI** ĐžĐąŅ€ĐĩĐˇĐ°Ņ‚ŅŒ Ņ‚ĐĩĐēҁ҂, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đš Đ´ĐģŅ OpenAPI, в ŅŅ‚ĐžĐš Ņ‚ĐžŅ‡ĐēĐĩ. + +Đ­Ņ‚Đ° Ņ‡Đ°ŅŅ‚ŅŒ ĐŊĐĩ ĐŋĐžĐŋĐ°Đ´Ņ‘Ņ‚ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, ĐŊĐž Đ´Ņ€ŅƒĐŗĐ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Sphinx) ҁĐŧĐžĐŗŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅŅ‚Đ°ĐģҌĐŊĐžĐĩ. + +{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *} + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ { #additional-responses } + +Đ’Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ҃ĐļĐĩ видĐĩĐģи, ĐēаĐē ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ `response_model` и `status_code` Đ´ĐģŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +Đ­Ņ‚Đž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ Ой ĐžŅĐŊОвĐŊĐžĐŧ ĐžŅ‚Đ˛ĐĩŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +ĐĸаĐēĐļĐĩ ĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ ҁ Đ¸Ņ… ĐŧОдĐĩĐģŅĐŧи, ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдаĐŧи и Ņ‚.Đ´. + +В Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐĩŅŅ‚ŅŒ ҆ĐĩĐģĐ°Ņ ĐŗĐģава Ой ŅŅ‚ĐžĐŧ — [ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ в OpenAPI](additional-responses.md){.internal-link target=_blank}. + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ даĐŊĐŊŅ‹Đĩ OpenAPI { #openapi-extra } + +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* в ŅĐ˛ĐžŅ‘Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии, **FastAPI** Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đĩ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ Ой ŅŅ‚ĐžĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ вĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ в ҁ҅ĐĩĐŧ҃ OpenAPI. + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +В ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ OpenAPI ŅŅ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ ĐžĐąŅŠĐĩĐēŅ‚ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸. + +/// + +ОĐŊ ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ Đ˛ŅŅŽ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Ой *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. + +ĐĸаĐŧ ĐĩŅŅ‚ŅŒ `tags`, `parameters`, `requestBody`, `responses` и Ņ‚.Đ´. + +Đ­Ņ‚Đ° ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ OpenAPI, ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊĐ°Ņ Đ´ĐģŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи **FastAPI**, ĐŊĐž Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐĩŅ‘ Ņ€Đ°ŅŅˆĐ¸Ņ€Đ¸Ņ‚ŅŒ. + +/// tip | ХОвĐĩŅ‚ + +Đ­Ņ‚Đž ĐŊиСĐēĐžŅƒŅ€ĐžĐ˛ĐŊĐĩĐ˛Đ°Ņ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐ¸Ņ. + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž ĐģĐ¸ŅˆŅŒ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ, ŅƒĐ´ĐžĐąĐŊĐĩĐĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž ҇ĐĩŅ€ĐĩС [ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ в OpenAPI](additional-responses.md){.internal-link target=_blank}. + +/// + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Ņ€Đ°ŅŅˆĐ¸Ņ€Đ¸Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI Đ´ĐģŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `openapi_extra`. + +### Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐ¸Ņ OpenAPI { #openapi-extensions } + +`openapi_extra` ĐŧĐžĐļĐĩŅ‚ ĐŋŅ€Đ¸ĐŗĐžĐ´Đ¸Ņ‚ŅŒŅŅ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ [Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐ¸Ņ OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): + +{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *} + +Đ•ŅĐģи Đ˛Ņ‹ ĐžŅ‚ĐēŅ€ĐžĐĩŅ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API, Đ˛Đ°ŅˆĐĩ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ ĐŋĐžŅĐ˛Đ¸Ņ‚ŅŅ вĐŊĐ¸ĐˇŅƒ ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņ‹ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊОК *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + + + +И ĐĩҁĐģи Đ˛Ņ‹ ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ĐŊа Đ¸Ņ‚ĐžĐŗĐžĐ˛Ņ‹Đš OpenAPI (ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ `/openapi.json` Đ˛Đ°ŅˆĐĩĐŗĐž API), Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ŅĐ˛ĐžŅ‘ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ в ŅĐžŅŅ‚Đ°Đ˛Đĩ ĐžĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*: + +```JSON hl_lines="22" +{ + "openapi": "3.1.0", + "info": { + "title": "FastAPI", + "version": "0.1.0" + }, + "paths": { + "/items/": { + "get": { + "summary": "Read Items", + "operationId": "read_items_items__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "x-aperture-labs-portal": "blue" + } + } + } +} +``` + +### ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ°Ņ ҁ҅ĐĩĐŧа OpenAPI Đ´ĐģŅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ { #custom-openapi-path-operation-schema } + +ĐĄĐģĐžĐ˛Đ°Ņ€ŅŒ в `openapi_extra` ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅŠĐĩдиĐŊŅ‘ĐŊ ҁ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊОК ҁ҅ĐĩĐŧОК OpenAPI Đ´ĐģŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ даĐŊĐŊŅ‹Đĩ Đē Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊОК ҁ҅ĐĩĐŧĐĩ. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ и ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ ŅĐ˛ĐžĐ¸Đŧ ĐēОдОĐŧ, ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ FastAPI и Pydantic, ĐŊĐž ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐžĐŋĐ¸ŅĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ в ҁ҅ĐĩĐŧĐĩ OpenAPI. + +Đ­Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `openapi_extra`: + +{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *} + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ĐŧŅ‹ ĐŊĐĩ ĐžĐąŅŠŅĐ˛ĐģŅĐģи ĐŊиĐēаĐēŅƒŅŽ Pydantic-ĐŧОдĐĩĐģҌ. ФаĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° даĐļĐĩ ĐŊĐĩ Ņ€Đ°ŅĐŋĐ°Ņ€ŅĐĩĐŊĐž ĐēаĐē JSON, ĐžĐŊĐž Ņ‡Đ¸Ņ‚Đ°ĐĩŅ‚ŅŅ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ĐēаĐē `bytes`, а Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `magic_data_reader()` ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚Đ˛ĐĩŅ‡Đ°Ņ‚ŅŒ Са ĐĩĐŗĐž ĐŋĐ°Ņ€ŅĐ¸ĐŊĐŗ ĐēаĐēиĐŧ-Ņ‚Đž ҁĐŋĐžŅĐžĐąĐžĐŧ. + +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐžĐļидаĐĩĐŧŅƒŅŽ ҁ҅ĐĩĐŧ҃ Đ´ĐģŅ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ°. + +### ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž в OpenAPI { #custom-openapi-content-type } + +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ‚ĐžŅ‚ ĐļĐĩ ĐŋŅ€Đ¸Ņ‘Đŧ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Pydantic-ĐŧОдĐĩĐģŅŒŅŽ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ JSON Schema, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐˇĐ°Ņ‚ĐĩĐŧ ĐąŅƒĐ´ĐĩŅ‚ вĐēĐģŅŽŅ‡ĐĩĐŊа в ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК Ņ€Đ°ĐˇĐ´ĐĩĐģ ҁ҅ĐĩĐŧŅ‹ OpenAPI Đ´ĐģŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +И Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž, даĐļĐĩ ĐĩҁĐģи Ņ‚Đ¸Đŋ даĐŊĐŊҋ҅ в СаĐŋŅ€ĐžŅĐĩ — ĐŊĐĩ JSON. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии ĐŧŅ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ FastAPI Đ´ĐģŅ иСвĐģĐĩ҇ĐĩĐŊĐ¸Ņ JSON Schema иС ĐŧОдĐĩĐģĐĩĐš Pydantic, Ņ€Đ°Đ˛ĐŊĐž ĐēаĐē и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ JSON. ĐœŅ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ Ņ‚Đ¸Đŋ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž СаĐŋŅ€ĐžŅĐ° ĐēаĐē YAML, а ĐŊĐĩ JSON: + +//// tab | Pydantic v2 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *} + +//// + +//// tab | Pydantic v1 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *} + +//// + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В Pydantic вĐĩŅ€ŅĐ¸Đ¸ 1 ĐŧĐĩŅ‚ĐžĐ´ Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ JSON Schema ĐŧОдĐĩĐģи ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐģŅŅ `Item.schema()`, в Pydantic вĐĩŅ€ŅĐ¸Đ¸ 2 ĐŧĐĩŅ‚ĐžĐ´ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ `Item.model_json_schema()`. + +/// + +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, Ņ…ĐžŅ‚Ņ ĐŧŅ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐŧŅ‹ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Pydantic-ĐŧОдĐĩĐģҌ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ JSON Schema Đ´ĐģŅ даĐŊĐŊҋ҅, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧŅ‹ Ņ…ĐžŅ‚Đ¸Đŧ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ в YAML. + +Đ—Đ°Ņ‚ĐĩĐŧ ĐŧŅ‹ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩĐŧ ҁ СаĐŋŅ€ĐžŅĐžĐŧ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ и иСвĐģĐĩĐēаĐĩĐŧ Ņ‚ĐĩĐģĐž ĐēаĐē `bytes`. Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž FastAPI даĐļĐĩ ĐŊĐĩ ĐŋĐžĐŋŅ‹Ņ‚Đ°ĐĩŅ‚ŅŅ Ņ€Đ°ŅĐŋĐ°Ņ€ŅĐ¸Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊŅƒŅŽ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐē҃ СаĐŋŅ€ĐžŅĐ° ĐēаĐē JSON. + +А ĐˇĐ°Ņ‚ĐĩĐŧ в ĐŊĐ°ŅˆĐĩĐŧ ĐēОдĐĩ ĐŧŅ‹ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ĐŋĐ°Ņ€ŅĐ¸Đŧ ŅŅ‚ĐžŅ‚ YAML и ҁĐŊОва Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Ņ‚Ņƒ ĐļĐĩ Pydantic-ĐŧОдĐĩĐģҌ Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ YAML-ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž: + +//// tab | Pydantic v2 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *} + +//// + +//// tab | Pydantic v1 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *} + +//// + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В Pydantic вĐĩŅ€ŅĐ¸Đ¸ 1 ĐŧĐĩŅ‚ĐžĐ´ Đ´ĐģŅ ĐŋĐ°Ņ€ŅĐ¸ĐŊĐŗĐ° и ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ ĐžĐąŅŠĐĩĐēŅ‚Đ° ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐģŅŅ `Item.parse_obj()`, в Pydantic вĐĩŅ€ŅĐ¸Đ¸ 2 ĐŧĐĩŅ‚ĐžĐ´ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ `Item.model_validate()`. + +/// + +/// tip | ХОвĐĩŅ‚ + +ЗдĐĩҁҌ ĐŧŅ‹ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Ņ‚Ņƒ ĐļĐĩ Pydantic-ĐŧОдĐĩĐģҌ. + +Но аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž ĐŧŅ‹ ĐŧĐžĐŗĐģи ĐąŅ‹ ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ даĐŊĐŊŅ‹Đĩ и ĐēаĐēиĐŧ-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁĐŋĐžŅĐžĐąĐžĐŧ. + +/// diff --git a/docs/ru/docs/advanced/response-change-status-code.md b/docs/ru/docs/advanced/response-change-status-code.md index 37dade99f..e9e1c9470 100644 --- a/docs/ru/docs/advanced/response-change-status-code.md +++ b/docs/ru/docs/advanced/response-change-status-code.md @@ -1,22 +1,22 @@ -# Response - ИСĐŧĐĩĐŊĐĩĐŊиĐĩ cŅ‚Đ°Ņ‚ŅƒŅ ĐēОда +# Response - ИСĐŧĐĩĐŊĐĩĐŊиĐĩ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОда { #response-change-status-code } -Đ’Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ҃ĐļĐĩ Ņ‡Đ¸Ņ‚Đ°Đģи Đž Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ [ĐĄĐžŅŅ‚ĐžŅĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ](../tutorial/response-status-code.md){.internal-link target=_blank}. +Đ’Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ҃ĐļĐĩ Ņ‡Đ¸Ņ‚Đ°Đģи Đž Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ [ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ](../tutorial/response-status-code.md){.internal-link target=_blank}. -Но в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ваĐŧ ĐŊ҃ĐļĐŊĐž вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐēОд ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ, ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš ĐžŅ‚ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊĐžĐŗĐž ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. +Но в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐŊ҃ĐļĐŊĐž вĐĩŅ€ĐŊŅƒŅ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд, ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš ĐžŅ‚ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. -## ĐŸŅ€Đ¸ĐŧĐĩŅ€ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ +## ĐŸŅ€Đ¸ĐŧĐĩŅ€ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ { #use-case } -НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ HTTP ĐēОд ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ "OK" `200` ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ HTTP ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ÂĢOKÂģ `200`. -Но ĐĩҁĐģи даĐŊĐŊŅ‹Đĩ ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģи, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Đ¸Ņ… и вĐĩŅ€ĐŊŅƒŅ‚ŅŒ HTTP ĐēОд ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ "CREATED" `201`. +Но ĐĩҁĐģи даĐŊĐŊŅ‹Đĩ ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģи, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Đ¸Ņ… и вĐĩŅ€ĐŊŅƒŅ‚ŅŒ HTTP ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд ÂĢCREATEDÂģ `201`. ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ Đ˛Ņ‹ Đ˛ŅŅ‘ Đĩ҉ґ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Ņ‹Đ˛Đ°Ņ‚ŅŒ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧŅ‹Đĩ даĐŊĐŊŅ‹Đĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `response_model`. ДĐģŅ Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°Đĩв Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `Response`. -## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `Response` +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `Response` { #use-a-response-parameter } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `Response` в Đ˛Đ°ŅˆĐĩĐš *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* (Ņ‚Đ°Đē ĐļĐĩ ĐēаĐē Đ´ĐģŅ cookies и headers). +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `Response` в Đ˛Đ°ŅˆĐĩĐš *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* (ĐēаĐē и Đ´ĐģŅ cookies и HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēОв). И ĐˇĐ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ `status_code` в ŅŅ‚ĐžĐŧ *Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŧ* ĐžĐąŅŠĐĩĐēŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. @@ -26,6 +26,6 @@ И ĐĩҁĐģи Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛Đ¸Đģи `response_model`, ĐžĐŊ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ´ĐģŅ Ņ„Đ¸ĐģŅŒŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ и ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ°. -**FastAPI** ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ *Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš* ĐžŅ‚Đ˛ĐĩŅ‚ Đ´ĐģŅ иСвĐģĐĩ҇ĐĩĐŊĐ¸Ņ ĐēОда ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ (а Ņ‚Đ°ĐēĐļĐĩ cookies и headers) и ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ Đ¸Ņ… в Ņ„Đ¸ĐŊаĐģҌĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ ваĐŧи СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ĐģŅŽĐąŅ‹Đŧ `response_model`. +**FastAPI** ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ *Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš* ĐžŅ‚Đ˛ĐĩŅ‚ Đ´ĐģŅ иСвĐģĐĩ҇ĐĩĐŊĐ¸Ņ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОда (а Ņ‚Đ°ĐēĐļĐĩ cookies и HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēОв) и ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ Đ¸Ņ… в Ņ„Đ¸ĐŊаĐģҌĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ ваĐŧи СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ĐģŅŽĐąŅ‹Đŧ `response_model`. -Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `Response` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… и ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐēОд ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ в ĐŊĐ¸Ņ…. Но ĐŋĐžĐŧĐŊĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐĩ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ĐŋŅ€Đ¸ĐžŅ€Đ¸Ņ‚ĐĩŅ‚. +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `Response` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… и ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ в ĐŊĐ¸Ņ… ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд. Но ĐŋĐžĐŧĐŊĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐĩ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ĐŋŅ€Đ¸ĐžŅ€Đ¸Ņ‚ĐĩŅ‚. diff --git a/docs/ru/docs/advanced/response-cookies.md b/docs/ru/docs/advanced/response-cookies.md index e04ff577c..3aa32b9bb 100644 --- a/docs/ru/docs/advanced/response-cookies.md +++ b/docs/ru/docs/advanced/response-cookies.md @@ -1,9 +1,8 @@ +# Cookies в ĐžŅ‚Đ˛ĐĩŅ‚Đĩ { #response-cookies } -# Cookies в ĐžŅ‚Đ˛ĐĩŅ‚Đĩ +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `Response` { #use-a-response-parameter } -## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `Response` - -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `Response` в Đ˛Đ°ŅˆĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ŅĐŊĐ´ĐŋОиĐŊŅ‚Đ°. +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `Response` в Đ˛Đ°ŅˆĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸. Đ—Đ°Ņ‚ĐĩĐŧ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ cookies в ŅŅ‚ĐžĐŧ Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŧ ĐžĐąŅŠĐĩĐēŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. @@ -13,36 +12,40 @@ Đ•ŅĐģи Đ˛Ņ‹ ҃ĐēаСаĐģи `response_model`, ĐžĐŊ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ´ĐģŅ Ņ„Đ¸ĐģŅŒŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ и ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ°. -**FastAPI** иСвĐģĐĩ҇ĐĩŅ‚ cookies (а Ņ‚Đ°ĐēĐļĐĩ ĐˇĐ°ĐŗĐžĐģОвĐēи и ĐēĐžĐ´Ņ‹ ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ) иС Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° и вĐēĐģŅŽŅ‡Đ¸Ņ‚ Đ¸Ņ… в ĐžĐēĐžĐŊŅ‡Đ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš Đ˛Đ°ŅˆĐĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ҇ĐĩŅ€ĐĩС `response_model`. +**FastAPI** иСвĐģĐĩ҇ĐĩŅ‚ cookies (а Ņ‚Đ°ĐēĐļĐĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи и ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд) иС Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŗĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ° и вĐēĐģŅŽŅ‡Đ¸Ņ‚ Đ¸Ņ… в ĐžĐēĐžĐŊŅ‡Đ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐžŅ‚Đ˛ĐĩŅ‚, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš Đ˛Đ°ŅˆĐĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ҇ĐĩŅ€ĐĩС `response_model`. -Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа Response в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ cookies (и ĐˇĐ°ĐŗĐžĐģОвĐēи) Ņ‚Đ°Đŧ. +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `Response` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ cookies (и HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи) Ņ‚Đ°Đŧ. -## Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊиĐĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ +## Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊиĐĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ { #return-a-response-directly } -Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ cookies, ĐĩҁĐģи Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ. +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ Cookies, ĐĩҁĐģи Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ. -ДĐģŅ ŅŅ‚ĐžĐŗĐž ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `Response`, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ](response-directly.md){.target=_blank}. +ДĐģŅ ŅŅ‚ĐžĐŗĐž ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `Response`, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ](response-directly.md){.internal-link target=_blank}. Đ—Đ°Ņ‚ĐĩĐŧ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ cookies и вĐĩŅ€ĐŊĐ¸Ņ‚Đĩ ŅŅ‚ĐžŅ‚ ĐžĐąŅŠĐĩĐēŅ‚: {* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} -/// tip | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ -ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž ĐĩҁĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, вĐŧĐĩŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `Response`, **FastAPI** ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ ĐĩĐŗĐž ĐąĐĩС Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊОК ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи. +/// tip | ХОвĐĩŅ‚ -ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐ¸ даĐŊĐŊŅ‹Đĩ иĐŧĐĩŅŽŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đš Ņ‚Đ¸Đŋ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐŊи Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹ ҁ JSON, ĐĩҁĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ `JSONResponse`. +ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž ĐĩҁĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, вĐŧĐĩŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `Response`, FastAPI вĐĩŅ€ĐŊґ҂ ĐĩĐŗĐž ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐ¸ даĐŊĐŊŅ‹Đĩ иĐŧĐĩŅŽŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đš Ņ‚Đ¸Đŋ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐŊи Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹ ҁ JSON, ĐĩҁĐģи Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `JSONResponse`. ĐĸаĐēĐļĐĩ ŅƒĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŊĐĩ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚Đĩ даĐŊĐŊŅ‹Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Đģи ĐąŅ‹Ņ‚ŅŒ ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊŅ‹ ҇ĐĩŅ€ĐĩС `response_model`. + /// -### ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ +### ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ { #more-info } /// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.responses import Response` иĐģи `from starlette.responses import JSONResponse`. **FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ `fastapi.responses`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅĐ˛ĐģŅŅŽŅ‚ŅŅ Ņ‚ĐĩĐŧи ĐļĐĩ ĐžĐąŅŠĐĩĐēŅ‚Đ°Đŧи, Ņ‡Ņ‚Đž и `starlette.responses`, ĐŋŅ€ĐžŅŅ‚Đž Đ´ĐģŅ ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ°. ОдĐŊаĐēĐž йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ Ņ‚Đ¸ĐŋОв ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ ĐŋĐžŅŅ‚ŅƒĐŋаĐĩŅ‚ ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž иС **Starlette**. -ДĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°ĐŗĐžĐģОвĐēОв и cookies `Response` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Ņ‡Đ°ŅŅ‚Đž, ĐŋĐžŅŅ‚ĐžĐŧ҃ **FastAPI** Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐĩĐŗĐž ҇ĐĩŅ€ĐĩС `fastapi.responses`. +И Ņ‚Đ°Đē ĐēаĐē `Response` Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēОв и cookies, **FastAPI** Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐĩĐŗĐž ĐēаĐē `fastapi.Response`. + /// Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Đ˛ŅĐĩ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ и ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи, ОСĐŊаĐēĐžĐŧŅŒŅ‚ĐĩҁҌ ҁ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš Starlette. diff --git a/docs/ru/docs/advanced/response-directly.md b/docs/ru/docs/advanced/response-directly.md index ee83d22b1..febd40ed4 100644 --- a/docs/ru/docs/advanced/response-directly.md +++ b/docs/ru/docs/advanced/response-directly.md @@ -1,4 +1,4 @@ -# Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ +# Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ { #return-a-response-directly } ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚Đĩ **FastAPI** *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸*, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ иС ĐŊĐĩŅ‘ ĐģŅŽĐąŅ‹Đĩ даĐŊĐŊŅ‹Đĩ: `dict`, `list`, Pydantic-ĐŧОдĐĩĐģҌ, ĐŧОдĐĩĐģҌ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ и Ņ‚.Đ´. @@ -8,9 +8,9 @@ Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ `JSONResponse` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС Đ˛Đ°ŅˆĐ¸Ņ… *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*. -Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊĐž, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ĐŊ҃ĐļĐŊĐž вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ ĐˇĐ°ĐŗĐžĐģОвĐēи иĐģи Đē҃Đēи. +Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊĐž, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ĐŊ҃ĐļĐŊĐž вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи иĐģи cookie. -## Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ `Response` +## Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ `Response` { #return-a-response } На ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ĐģŅŽĐąĐžĐš ĐžĐąŅŠĐĩĐēŅ‚ `Response` иĐģи ĐĩĐŗĐž ĐŋОдĐēĐģĐ°ŅŅ. @@ -26,7 +26,7 @@ Đ­Ņ‚Đž Đ´Đ°Ņ‘Ņ‚ ваĐŧ йОĐģŅŒŅˆŅƒŅŽ ĐŗĐ¸ĐąĐēĐžŅŅ‚ŅŒ. Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ĐģŅŽĐąŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹ даĐŊĐŊҋ҅, ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐģŅŽĐąŅ‹Đĩ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ иĐģи ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅ и Ņ‚.Đ´. -## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `jsonable_encoder` в `Response` +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `jsonable_encoder` в `Response` { #using-the-jsonable-encoder-in-a-response } ĐŸĐžŅĐēĐžĐģҌĐē҃ **FastAPI** ĐŊĐĩ иСĐŧĐĩĐŊŅĐĩŅ‚ ĐžĐąŅŠĐĩĐēŅ‚ `Response`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ, Đ˛Ņ‹ Đ´ĐžĐģĐļĐŊŅ‹ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž ĐĩĐŗĐž ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ ĐŗĐžŅ‚ĐžĐ˛Đž Đē ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐēĐĩ. @@ -44,7 +44,7 @@ /// -## Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž `Response` +## Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž `Response` { #returning-a-custom-response } ĐŸŅ€Đ¸ĐŧĐĩŅ€ Đ˛Ņ‹ŅˆĐĩ ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ Đ˛ŅĐĩ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Ņ‡Đ°ŅŅ‚Đ¸, ĐŊĐž ĐžĐŊ ĐŋĐžĐēа ĐŊĐĩ ĐžŅ‡ĐĩĐŊҌ ĐŋĐžĐģĐĩСĐĩĐŊ, Ņ‚Đ°Đē ĐēаĐē Đ˛Ņ‹ ĐŧĐžĐŗĐģи ĐąŅ‹ ĐŋŅ€ĐžŅŅ‚Đž вĐĩŅ€ĐŊŅƒŅ‚ŅŒ `item` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, и **FastAPI** ĐŋĐžĐŧĐĩŅŅ‚Đ¸Đģ ĐąŅ‹ ĐĩĐŗĐž в `JSONResponse`, ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°Đ˛ в `dict` и Ņ‚.Đ´. Đ’ŅŅ‘ ŅŅ‚Đž ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. @@ -56,7 +56,7 @@ {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} -## ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊĐ¸Ņ +## ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊĐ¸Ņ { #notes } ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐĩĐŗĐž даĐŊĐŊŅ‹Đĩ ĐŊĐĩ ваĐģĐ¸Đ´Đ¸Ņ€ŅƒŅŽŅ‚ŅŅ, ĐŊĐĩ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒŅŽŅ‚ŅŅ (ĐŊĐĩ ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇŅƒŅŽŅ‚ŅŅ) и ĐŊĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ŅƒŅŽŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи. diff --git a/docs/ru/docs/advanced/response-headers.md b/docs/ru/docs/advanced/response-headers.md new file mode 100644 index 000000000..81e52cb69 --- /dev/null +++ b/docs/ru/docs/advanced/response-headers.md @@ -0,0 +1,41 @@ +# HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи ĐžŅ‚Đ˛ĐĩŅ‚Đ° { #response-headers } + +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `Response` { #use-a-response-parameter } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `Response` в Đ˛Đ°ŅˆĐĩĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸ (ĐēаĐē ĐŧĐžĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ и Đ´ĐģŅ cookie). + +А ĐˇĐ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи в ŅŅ‚ĐžĐŧ *Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŧ* ĐžĐąŅŠĐĩĐēŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. + +{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *} + +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ вĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐģŅŽĐąĐžĐš ĐŊ҃ĐļĐŊŅ‹Đš ĐžĐąŅŠĐĩĐēŅ‚, ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐž (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `dict`, ĐŧОдĐĩĐģҌ иС ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ и Ņ‚.Đ´.). + +И, ĐĩҁĐģи Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛Đ¸Đģи `response_model`, ĐžĐŊ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ Đ´ĐģŅ Ņ„Đ¸ĐģŅŒŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ и ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊĐŊĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ°. + +**FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ŅŅ‚ĐžŅ‚ *Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš* ĐžŅ‚Đ˛ĐĩŅ‚, Ņ‡Ņ‚ĐžĐąŅ‹ иСвĐģĐĩŅ‡ŅŒ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи (а Ņ‚Đ°ĐēĐļĐĩ cookie и ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОд) и ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ Đ¸Ņ… в Ņ„Đ¸ĐŊаĐģҌĐŊŅ‹Đš HTTP-ĐžŅ‚Đ˛ĐĩŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊĐŊĐžĐĩ ваĐŧи СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐžŅ‚Ņ„Đ¸ĐģŅŒŅ‚Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ŅĐžĐŗĐģĐ°ŅĐŊĐž `response_model`. + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `Response` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ в ĐŊĐ¸Ņ… ĐˇĐ°ĐŗĐžĐģОвĐēи (и cookie). + +## ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ { #return-a-response-directly } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи, ĐēĐžĐŗĐ´Đ° Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ `Response` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž в [ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ Response ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ](response-directly.md){.internal-link target=_blank}, и ĐŋĐĩŅ€ĐĩĐ´Đ°ĐšŅ‚Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐēаĐē Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ: + +{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *} + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.responses import Response` иĐģи `from starlette.responses import JSONResponse`. + +**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚Đĩ ĐļĐĩ ŅĐ°ĐŧŅ‹Đĩ `starlette.responses` ĐēаĐē `fastapi.responses` — Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ° ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. Но йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐēĐģĐ°ŅŅĐžĐ˛ ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ ĐŋĐžŅŅ‚ŅƒĐŋĐ°ŅŽŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС Starlette. + +И ĐŋĐžŅĐēĐžĐģҌĐē҃ `Response` Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°ĐŗĐžĐģОвĐēОв и cookie, **FastAPI** Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐĩĐŗĐž ĐēаĐē `fastapi.Response`. + +/// + +## ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи { #custom-headers } + +ПоĐŧĐŊĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ ĐŋŅ€ĐžĐŋŅ€Đ¸ĐĩŅ‚Đ°Ņ€ĐŊŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŧĐžĐļĐŊĐž дОйавĐģŅŅ‚ŅŒ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ `X-`. + +Но ĐĩҁĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ ĐˇĐ°ĐŗĐžĐģОвĐēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ĐēĐģиĐĩĐŊŅ‚Ņƒ в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đĩ, ваĐŧ ĐŊ҃ĐļĐŊĐž Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Đ¸Ņ… в ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи CORS (ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ҁĐŧ. в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `expose_headers`, ĐžĐŋĐ¸ŅĐ°ĐŊĐŊŅ‹Đš в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Starlette ĐŋĐž CORS. diff --git a/docs/ru/docs/advanced/security/http-basic-auth.md b/docs/ru/docs/advanced/security/http-basic-auth.md new file mode 100644 index 000000000..41e62d4bf --- /dev/null +++ b/docs/ru/docs/advanced/security/http-basic-auth.md @@ -0,0 +1,107 @@ +# HTTP Basic Auth { #http-basic-auth } + +ДĐģŅ ŅĐ°Đŧҋ҅ ĐŋŅ€ĐžŅŅ‚Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°Đĩв ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ HTTP Basic Auth. + +ĐŸŅ€Đ¸ HTTP Basic Auth ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐžĐļидаĐĩŅ‚ HTTP-ĐˇĐ°ĐŗĐžĐģОвОĐē, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģҌ. + +Đ•ŅĐģи ĐĩĐŗĐž ĐŊĐĩŅ‚, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ ĐžŅˆĐ¸ĐąĐēа HTTP 401 ÂĢUnauthorizedÂģ. + +ĐĸаĐēĐļĐĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ ĐˇĐ°ĐŗĐžĐģОвОĐē `WWW-Authenticate` ŅĐž СĐŊĐ°Ņ‡ĐĩĐŊиĐĩĐŧ `Basic` и ĐŊĐĩĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐŧ `realm`. + +Đ­Ņ‚Đž ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Ņƒ ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊĐžĐĩ ĐžĐēĐŊĐž СаĐŋŅ€ĐžŅĐ° иĐŧĐĩĐŊи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģŅ. + +Đ—Đ°Ņ‚ĐĩĐŧ, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ˛Đ˛ĐžĐ´Đ¸Ņ‚Đĩ ŅŅ‚Đ¸ даĐŊĐŊŅ‹Đĩ, ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ Đ¸Ņ… в ĐˇĐ°ĐŗĐžĐģОвĐēĐĩ. + +## ĐŸŅ€ĐžŅŅ‚ĐžĐš HTTP Basic Auth { #simple-http-basic-auth } + +* ИĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `HTTPBasic` и `HTTPBasicCredentials`. +* ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ÂĢҁ҅ĐĩĐŧ҃Âģ `security` ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `HTTPBasic`. +* Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ŅŅ‚Ņƒ `security` ĐēаĐē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ в Đ˛Đ°ŅˆĐĩĐš *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. +* ОĐŊа Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐžĐąŅŠĐĩĐēŅ‚ Ņ‚Đ¸Đŋа `HTTPBasicCredentials`: + * ОĐŊ ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊŅ‹Đĩ `username` и `password`. + +{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *} + +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ вĐŋĐĩŅ€Đ˛Ņ‹Đĩ ĐžŅ‚ĐēŅ€ĐžĐĩŅ‚Đĩ URL (иĐģи ĐŊаĐļĐŧґ҂Đĩ ĐēĐŊĐžĐŋĐē҃ ÂĢExecuteÂģ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸), ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ ввĐĩŅŅ‚Đ¸ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģҌ: + + + +## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа иĐŧĐĩĐŊи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ { #check-the-username } + +Đ’ĐžŅ‚ йОĐģĐĩĐĩ ĐŋĐžĐģĐŊŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€. + +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ, ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹ Đģи иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģҌ. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đš ĐŧĐžĐ´ŅƒĐģҌ Python `secrets` Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи иĐŧĐĩĐŊи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģŅ. + +`secrets.compare_digest()` Đ´ĐžĐģĐļĐĩĐŊ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ `bytes` иĐģи `str`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ Ņ‚ĐžĐģҌĐēĐž ŅĐ¸ĐŧвОĐģŅ‹ ASCII (аĐŊĐŗĐģĐ¸ĐšŅĐēиĐĩ ŅĐ¸ĐŧвОĐģŅ‹). Đ­Ņ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž ĐžĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ ŅĐ¸ĐŧвОĐģаĐŧи Đ˛Ņ€ĐžĐ´Đĩ `ÃĄ`, ĐēаĐē в `SebastiÃĄn`. + +Đ§Ņ‚ĐžĐąŅ‹ ŅŅ‚Đž ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ, ҁĐŊĐ°Ņ‡Đ°Đģа ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒĐĩĐŧ `username` и `password` в `bytes`, СаĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Đ°Đ˛ Đ¸Ņ… в UTF-8. + +Đ—Đ°Ņ‚ĐĩĐŧ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `secrets.compare_digest()`, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž `credentials.username` Ņ€Đ°Đ˛ĐĩĐŊ `"stanleyjobson"`, а `credentials.password` — `"swordfish"`. + +{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *} + +Đ­Ņ‚Đž ĐąŅ‹ĐģĐž ĐąŅ‹ ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа: + +```Python +if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"): + # ВĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐžŅˆĐ¸ĐąĐē҃ + ... +``` + +Но Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `secrets.compare_digest()`, Đ˛Ņ‹ ĐˇĐ°Ņ‰Đ¸Ņ‚Đ¸Ņ‚Đĩ ĐēОд ĐžŅ‚ Đ°Ņ‚Đ°Đē Ņ‚Đ¸Đŋа ÂĢŅ‚Đ°ĐšĐŧиĐŊĐŗĐžĐ˛Đ°Ņ Đ°Ņ‚Đ°ĐēаÂģ (Đ°Ņ‚Đ°Đēа ĐŋĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи). + +### ĐĸаКĐŧиĐŊĐŗĐžĐ˛Ņ‹Đĩ Đ°Ņ‚Đ°Đēи { #timing-attacks } + +Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ÂĢŅ‚Đ°ĐšĐŧиĐŊĐŗĐžĐ˛Đ°Ņ Đ°Ņ‚Đ°ĐēаÂģ? + +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž СĐģĐžŅƒĐŧŅ‹ŅˆĐģĐĩĐŊĐŊиĐēи ĐŋŅ‹Ņ‚Đ°ŅŽŅ‚ŅŅ ŅƒĐŗĐ°Đ´Đ°Ņ‚ŅŒ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģҌ. + +И ĐžĐŊи ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‚ СаĐŋŅ€ĐžŅ ҁ иĐŧĐĩĐŊĐĩĐŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ `johndoe` и ĐŋĐ°Ņ€ĐžĐģĐĩĐŧ `love123`. + +ĐĸĐžĐŗĐ´Đ° Python-ĐēОд в Đ˛Đ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии ĐąŅƒĐ´ĐĩŅ‚ ŅĐēвиваĐģĐĩĐŊŅ‚ĐĩĐŊ ҇ĐĩĐŧ҃-Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ: + +```Python +if "johndoe" == "stanleyjobson" and "love123" == "swordfish": + ... +``` + +Но в ĐŧĐžĐŧĐĩĐŊŅ‚, ĐēĐžĐŗĐ´Đ° Python ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ ĐŋĐĩŅ€Đ˛ŅƒŅŽ `j` в `johndoe` ҁ ĐŋĐĩŅ€Đ˛ĐžĐš `s` в `stanleyjobson`, ĐžĐŊ вĐĩŅ€ĐŊґ҂ `False`, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ҃ĐļĐĩ ŅŅĐŊĐž, Ņ‡Ņ‚Đž ŅŅ‚Ņ€ĐžĐēи ĐŊĐĩ ŅĐžĐ˛ĐŋĐ°Đ´Đ°ŅŽŅ‚, Ņ€ĐĩŅˆĐ¸Đ˛, Ņ‡Ņ‚Đž ÂĢĐŊĐĩŅ‚ ҁĐŧҋҁĐģа Ņ‚Ņ€Đ°Ņ‚Đ¸Ņ‚ŅŒ Ņ€ĐĩŅŅƒŅ€ŅŅ‹ ĐŊа ŅŅ€Đ°Đ˛ĐŊĐĩĐŊиĐĩ ĐžŅŅ‚Đ°ĐģҌĐŊҋ҅ ĐąŅƒĐēвÂģ. И Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Ņ‚ ÂĢНĐĩвĐĩŅ€ĐŊĐžĐĩ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ иĐģи ĐŋĐ°Ņ€ĐžĐģҌÂģ. + +Đ—Đ°Ņ‚ĐĩĐŧ СĐģĐžŅƒĐŧŅ‹ŅˆĐģĐĩĐŊĐŊиĐēи ĐŋĐžĐŋŅ€ĐžĐąŅƒŅŽŅ‚ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ `stanleyjobsox` и ĐŋĐ°Ņ€ĐžĐģҌ `love123`. + +И Đ˛Đ°Ņˆ ĐēОд ŅĐ´ĐĩĐģаĐĩŅ‚ Ņ‡Ņ‚Đž-Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ: + +```Python +if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": + ... +``` + +Python҃ ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ вĐĩҁҌ ĐžĐąŅ‰Đ¸Đš ĐŋŅ€ĐĩŅ„Đ¸Đēҁ `stanleyjobso` в `stanleyjobsox` и `stanleyjobson`, ĐŋŅ€ĐĩĐļĐ´Đĩ ҇ĐĩĐŧ ĐŋĐžĐŊŅŅ‚ŅŒ, Ņ‡Ņ‚Đž ŅŅ‚Ņ€ĐžĐēи ĐžŅ‚ĐģĐ¸Ņ‡Đ°ŅŽŅ‚ŅŅ. ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐŊа ĐžŅ‚Đ˛ĐĩŅ‚ ÂĢНĐĩвĐĩŅ€ĐŊĐžĐĩ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ иĐģи ĐŋĐ°Ņ€ĐžĐģҌÂģ ŅƒĐšĐ´Ņ‘Ņ‚ ĐŊа ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧиĐēŅ€ĐžŅĐĩĐē҃ĐŊĐ´ йОĐģҌ҈Đĩ. + +#### Đ’Ņ€ĐĩĐŧŅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚ СĐģĐžŅƒĐŧŅ‹ŅˆĐģĐĩĐŊĐŊиĐēаĐŧ { #the-time-to-answer-helps-the-attackers } + +ЗаĐŧĐĩŅ‡Đ°Ņ, Ņ‡Ņ‚Đž ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ŅĐģаĐģ ÂĢНĐĩвĐĩŅ€ĐŊĐžĐĩ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ иĐģи ĐŋĐ°Ņ€ĐžĐģҌÂģ ĐŊа ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧиĐēŅ€ĐžŅĐĩĐē҃ĐŊĐ´ ĐŋОСĐļĐĩ, СĐģĐžŅƒĐŧŅ‹ŅˆĐģĐĩĐŊĐŊиĐēи ĐŋОКĐŧŅƒŅ‚, Ņ‡Ņ‚Đž ĐēаĐēĐ°Ņ-Ņ‚Đž Ņ‡Đ°ŅŅ‚ŅŒ ĐąŅ‹Đģа ŅƒĐŗĐ°Đ´Đ°ĐŊа — ĐŊĐ°Ņ‡Đ°ĐģҌĐŊŅ‹Đĩ ĐąŅƒĐēĐ˛Ņ‹ вĐĩŅ€ĐŊŅ‹. + +ĐĸĐžĐŗĐ´Đ° ĐžĐŊи ĐŧĐžĐŗŅƒŅ‚ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ ҁĐŊОва, СĐŊĐ°Ņ, Ņ‡Ņ‚Đž ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐĩĐĩ Ņ‡Ņ‚Đž-Ņ‚Đž ĐąĐģиĐļĐĩ Đē `stanleyjobsox`, ҇ĐĩĐŧ Đē `johndoe`. + +#### ÂĢĐŸŅ€ĐžŅ„ĐĩŅŅĐ¸ĐžĐŊаĐģҌĐŊĐ°ŅÂģ Đ°Ņ‚Đ°Đēа { #a-professional-attack } + +КоĐŊĐĩ҇ĐŊĐž, СĐģĐžŅƒĐŧŅ‹ŅˆĐģĐĩĐŊĐŊиĐēи ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ Đ´ĐĩĐģĐ°Ņ‚ŅŒ Đ˛ŅŅ‘ ŅŅ‚Đž Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ — ĐžĐŊи ĐŊаĐŋĐ¸ŅˆŅƒŅ‚ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃, вОСĐŧĐžĐļĐŊĐž, ҁ Ņ‚Ņ‹ŅŅŅ‡Đ°Đŧи иĐģи ĐŧиĐģĐģиОĐŊаĐŧи ĐŋĐžĐŋŅ‹Ņ‚ĐžĐē в ҁĐĩĐē҃ĐŊĐ´Ņƒ. И ĐąŅƒĐ´ŅƒŅ‚ ĐŋĐžĐ´ĐąĐ¸Ņ€Đ°Ņ‚ŅŒ ĐŋĐž ОдĐŊОК Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊОК вĐĩŅ€ĐŊОК ĐąŅƒĐēвĐĩ Са Ņ€Đ°Đˇ. + +ĐĸаĐē Са ĐŧиĐŊŅƒŅ‚Ņ‹ иĐģи Ņ‡Đ°ŅŅ‹ ĐžĐŊи ҁĐŧĐžĐŗŅƒŅ‚ ŅƒĐŗĐ°Đ´Đ°Ņ‚ŅŒ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊŅ‹Đĩ иĐŧŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ и ĐŋĐ°Ņ€ĐžĐģҌ — ҁ ÂĢĐŋĐžĐŧĐžŅ‰ŅŒŅŽÂģ ĐŊĐ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐģĐ¸ŅˆŅŒ Đ˛Ņ€ĐĩĐŧŅ, ĐˇĐ°Ņ‚Ņ€Đ°Ņ‡ĐĩĐŊĐŊĐžĐĩ ĐŊа ĐžŅ‚Đ˛ĐĩŅ‚. + +#### Đ˜ŅĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest } + +Но в ĐŊĐ°ŅˆĐĩĐŧ ĐēОдĐĩ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ `secrets.compare_digest()`. + +ВĐēŅ€Đ°Ņ‚Ņ†Đĩ: ŅŅ€Đ°Đ˛ĐŊĐĩĐŊиĐĩ `stanleyjobsox` ҁ `stanleyjobson` СаКĐŧґ҂ ŅŅ‚ĐžĐģҌĐēĐž ĐļĐĩ Đ˛Ņ€ĐĩĐŧĐĩĐŊи, ҁĐēĐžĐģҌĐēĐž и ŅŅ€Đ°Đ˛ĐŊĐĩĐŊиĐĩ `johndoe` ҁ `stanleyjobson`. ĐĸĐž ĐļĐĩ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ и Đē ĐŋĐ°Ņ€ĐžĐģŅŽ. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `secrets.compare_digest()` в ĐēОдĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, Đ˛Ņ‹ ĐˇĐ°Ņ‰Đ¸Ņ‚Đ¸Ņ‚Đĩ ĐĩĐŗĐž ĐžŅ‚ Đ˛ŅĐĩĐŗĐž ŅŅ‚ĐžĐŗĐž ĐēĐģĐ°ŅŅĐ° Đ°Ņ‚Đ°Đē ĐŊа ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ. + +### Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‚ ĐžŅˆĐ¸ĐąĐēи { #return-the-error } + +ĐŸĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž ĐēаĐē ОйĐŊĐ°Ņ€ŅƒĐļĐĩĐŊĐž, Ņ‡Ņ‚Đž ŅƒŅ‡Ņ‘Ņ‚ĐŊŅ‹Đĩ даĐŊĐŊŅ‹Đĩ ĐŊĐĩĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹, вĐĩŅ€ĐŊĐ¸Ņ‚Đĩ `HTTPException` ŅĐž ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдОĐŧ ĐžŅ‚Đ˛ĐĩŅ‚Đ° 401 (Ņ‚ĐĩĐŧ ĐļĐĩ, Ņ‡Ņ‚Đž и ĐŋŅ€Đ¸ ĐžŅ‚ŅŅƒŅ‚ŅŅ‚Đ˛Đ¸Đ¸ ŅƒŅ‡Ņ‘Ņ‚ĐŊҋ҅ даĐŊĐŊҋ҅) и Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвОĐē `WWW-Authenticate`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ҁĐŊОва ĐŋĐžĐēаСаĐģ ĐžĐēĐŊĐž Đ˛Ņ…ĐžĐ´Đ°: + +{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *} diff --git a/docs/ru/docs/advanced/security/index.md b/docs/ru/docs/advanced/security/index.md new file mode 100644 index 000000000..912e4812a --- /dev/null +++ b/docs/ru/docs/advanced/security/index.md @@ -0,0 +1,19 @@ +# Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐ°Ņ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ { #advanced-security } + +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ { #additional-features } + +Đ•ŅŅ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒŅŽ ĐŋĐžĐŧиĐŧĐž Ņ‚ĐĩŅ…, Ņ‡Ņ‚Đž ĐžĐŋĐ¸ŅĐ°ĐŊŅ‹ в [ĐŖŅ‡ĐĩĐąĐŊиĐē — Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ: БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ](../../tutorial/security/index.md){.internal-link target=_blank}. + +/// tip | ХОвĐĩŅ‚ + +ĐĄĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‹ **ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž ŅĐ˛ĐģŅŅŽŅ‚ŅŅ ÂĢĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Ņ‹ĐŧиÂģ**. + +И вОСĐŧĐžĐļĐŊĐž, Ņ‡Ņ‚Đž Ņ€Đĩ҈ĐĩĐŊиĐĩ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚Đ° Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ в ОдĐŊĐžĐŧ иС ĐŊĐ¸Ņ…. + +/// + +## ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž { #read-the-tutorial-first } + +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… Ņ€Đ°ĐˇĐ´ĐĩĐģĐ°Ņ… ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚ŅŅ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ҃ĐļĐĩ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Đģи ĐžŅĐŊОвĐŊОК [ĐŖŅ‡ĐĩĐąĐŊиĐē — Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ: БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ](../../tutorial/security/index.md){.internal-link target=_blank}. + +Đ’ŅĐĩ ĐžĐŊи ĐžŅĐŊОваĐŊŅ‹ ĐŊа Ņ‚ĐĩŅ… ĐļĐĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅŅ…, ĐŊĐž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸. diff --git a/docs/ru/docs/advanced/security/oauth2-scopes.md b/docs/ru/docs/advanced/security/oauth2-scopes.md new file mode 100644 index 000000000..8788df199 --- /dev/null +++ b/docs/ru/docs/advanced/security/oauth2-scopes.md @@ -0,0 +1,274 @@ +# OAuth2 scopes { #oauth2-scopes } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ OAuth2 scopes (scope - ОйĐģĐ°ŅŅ‚ŅŒ, Ņ€Đ°ĐŧĐēи) ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ҁ **FastAPI** — ĐžĐŊи иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹ и Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ ĐąĐĩŅŅˆĐžĐ˛ĐŊĐž. + +Đ­Ņ‚Đž ĐŋОСвОĐģĐ¸Ņ‚ ваĐŧ иĐŧĐĩŅ‚ŅŒ йОĐģĐĩĐĩ Đ´ĐĩŅ‚Đ°ĐģҌĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊиК ĐŋĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Ņƒ OAuth2, иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅƒŅŽ в Đ˛Đ°ŅˆĐĩ OpenAPI‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ (и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API). + +OAuth2 ŅĐž scopes — ŅŅ‚Đž ĐŧĐĩŅ…Đ°ĐŊиСĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ĐŧĐŊĐžĐŗĐ¸Đĩ ĐēŅ€ŅƒĐŋĐŊŅ‹Đĩ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩҀҋ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸: Facebook, Google, GitHub, Microsoft, X (Twitter) и Ņ‚.Đ´. ОĐŊи ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅŽŅ‚ ĐĩĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊĐ¸Ņ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ и ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧ. + +КаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ÂĢĐ˛Ņ…ĐžĐ´Đ¸Ņ‚Đĩ ҇ĐĩŅ€ĐĩСÂģ Facebook, Google, GitHub, Microsoft, X (Twitter), ŅŅ‚Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ OAuth2 ŅĐž scopes. + +В ŅŅ‚ĐžĐŧ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ, ĐēаĐē ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ĐĩĐš и Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸ĐĩĐš ҁ Ņ‚ĐĩĐŧи ĐļĐĩ OAuth2 scopes в Đ˛Đ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии ĐŊа **FastAPI**. + +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ­Ņ‚Đž йОĐģĐĩĐĩ-ĐŧĐĩĐŊĐĩĐĩ ĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Ņ‹Đš Ņ€Đ°ĐˇĐ´ĐĩĐģ. Đ•ŅĐģи Đ˛Ņ‹ Ņ‚ĐžĐģҌĐēĐž ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚Đĩ, ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐĩĐŗĐž. + +ВаĐŧ ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž ĐŊ҃ĐļĐŊŅ‹ OAuth2 scopes — Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ŅŽ и Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸ŅŽ ĐŧĐžĐļĐŊĐž Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐģŅŽĐąŅ‹Đŧ ĐŊ҃ĐļĐŊŅ‹Đŧ ваĐŧ ҁĐŋĐžŅĐžĐąĐžĐŧ. + +Но OAuth2 ŅĐž scopes ĐŧĐžĐļĐŊĐž ĐēŅ€Đ°ŅĐ¸Đ˛Đž иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ в Đ˛Đ°Ņˆ API (҇ĐĩŅ€ĐĩС OpenAPI) и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API. + +ĐĸаĐē иĐģи иĐŊĐ°Ņ‡Đĩ, Đ˛Ņ‹ Đ˛ŅĐĩ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅ‚ŅŒ ŅŅ‚Đ¸ scopes иĐģи ĐēаĐēиĐĩ-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐ¸Đĩ ҂ҀĐĩйОваĐŊĐ¸Ņ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸/Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸, ĐēаĐē ваĐŧ ĐŊ҃ĐļĐŊĐž, в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ. + +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… OAuth2 ŅĐž scopes ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ¸ĐˇĐąŅ‹Ņ‚ĐžŅ‡ĐŊŅ‹Đŧ. + +Но ĐĩҁĐģи Đ˛Ņ‹ СĐŊаĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž ŅŅ‚Đž ĐŊ҃ĐļĐŊĐž, иĐģи ваĐŧ ĐŋŅ€ĐžŅŅ‚Đž иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐž — ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ°ĐšŅ‚Đĩ ҇҂ĐĩĐŊиĐĩ. + +/// + +## OAuth2 scopes и OpenAPI { #oauth2-scopes-and-openapi } + +ĐĄĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ OAuth2 ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚ ÂĢscopesÂģ ĐēаĐē ҁĐŋĐ¸ŅĐžĐē ŅŅ‚Ņ€ĐžĐē, Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ĐŋŅ€ĐžĐąĐĩĐģаĐŧи. + +ХОдĐĩŅ€ĐļиĐŧĐžĐĩ ĐēаĐļдОК Ņ‚Đ°ĐēОК ŅŅ‚Ņ€ĐžĐēи ĐŧĐžĐļĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ĐģŅŽĐąĐžĐš Ņ„ĐžŅ€ĐŧĐ°Ņ‚, ĐŊĐž ĐŊĐĩ Đ´ĐžĐģĐļĐŊĐž ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐĩĐģОв. + +Đ­Ņ‚Đ¸ scopes ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ ÂĢŅ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊĐ¸ŅÂģ. + +В OpenAPI (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API) ĐŧĐžĐļĐŊĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ÂĢҁ҅ĐĩĐŧŅ‹ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸Âģ (security schemes). + +ĐšĐžĐŗĐ´Đ° ОдĐŊа иС Ņ‚Đ°ĐēĐ¸Ņ… ҁ҅ĐĩĐŧ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ OAuth2, Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ scopes. + +КаĐļĐ´Ņ‹Đš ÂĢscopeÂģ — ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž ŅŅ‚Ņ€ĐžĐēа (ĐąĐĩС ĐŋŅ€ĐžĐąĐĩĐģОв). + +ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžĐŊи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ŅŅ Đ´ĐģŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊиК ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +- `users:read` иĐģи `users:write` — Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅ‘ĐŊĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ. +- `instagram_basic` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Facebook / Instagram. +- `https://www.googleapis.com/auth/drive` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Google. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В OAuth2 ÂĢscopeÂģ — ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž ŅŅ‚Ņ€ĐžĐēа, ĐžĐąŅŠŅĐ˛ĐģŅŅŽŅ‰Đ°Ņ ҂ҀĐĩĐąŅƒĐĩĐŧĐžĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐĩ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊиĐĩ. + +НĐĩваĐļĐŊĐž, ĐĩŅŅ‚ŅŒ Đģи Ņ‚Đ°Đŧ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ŅĐ¸ĐŧвОĐģŅ‹, Ņ‚Đ°ĐēиĐĩ ĐēаĐē `:`, иĐģи ŅŅ‚Đž URL. + +Đ­Ņ‚Đ¸ Đ´ĐĩŅ‚Đ°Đģи ĐˇĐ°Đ˛Đ¸ŅŅŅ‚ ĐžŅ‚ Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸. + +ДĐģŅ OAuth2 ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž ŅŅ‚Ņ€ĐžĐēи. + +/// + +## Đ’ĐˇĐŗĐģŅĐ´ иСдаĐģĐĩĐēа { #global-view } + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐąŅ‹ŅŅ‚Ņ€Đž ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, Ņ‡Ņ‚Đž иСĐŧĐĩĐŊиĐģĐžŅŅŒ ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ҁ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°Đŧи иС ĐžŅĐŊОвĐŊĐžĐŗĐž Ņ€Đ°ĐˇĐ´ĐĩĐģа **ĐŖŅ‡ĐĩĐąĐŊиĐē - Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ** — [OAuth2 ҁ ĐŋĐ°Ņ€ĐžĐģĐĩĐŧ (и Ņ…ĐĩŅˆĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩĐŧ), Bearer ҁ JWT-Ņ‚ĐžĐēĐĩĐŊаĐŧи](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. ĐĸĐĩĐŋĐĩŅ€ŅŒ — ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ OAuth2 scopes: + +{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *} + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ŅŅ‚Đ¸ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ŅˆĐ°Đŗ Са ŅˆĐ°ĐŗĐžĐŧ. + +## OAuth2 ҁ҅ĐĩĐŧа ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ { #oauth2-security-scheme } + +ПĐĩŅ€Đ˛ĐžĐĩ иСĐŧĐĩĐŊĐĩĐŊиĐĩ — ĐŧŅ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ҁ҅ĐĩĐŧ҃ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ OAuth2 ҁ Đ´Đ˛ŅƒĐŧŅ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đŧи scopes: `me` и `items`. + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `scopes` ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ `dict`, ĐŗĐ´Đĩ ĐēаĐļĐ´Ņ‹Đš scope — ŅŅ‚Đž ĐēĐģŅŽŅ‡, а ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ — СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ: + +{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *} + +ĐĸаĐē ĐēаĐē Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐŧŅ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ŅŅ‚Đ¸ scopes, ĐžĐŊи ĐŋĐžŅĐ˛ŅŅ‚ŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API ĐŋŅ€Đ¸ Đ˛Ņ…ĐžĐ´Đĩ/Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸. + +И Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ, ĐēаĐēиĐĩ scopes Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛Ņ‹Đ´Đ°Ņ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋ: `me` и `items`. + +Đ­Ņ‚Đž Ņ‚ĐžŅ‚ ĐļĐĩ ĐŧĐĩŅ…Đ°ĐŊиСĐŧ, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ´Đ°Ņ‘Ņ‚Đĩ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊĐ¸Ņ ĐŋŅ€Đ¸ Đ˛Ņ…ĐžĐ´Đĩ ҇ĐĩŅ€ĐĩС Facebook, Google, GitHub и Ņ‚.Đ´.: + + + +## JWT-Ņ‚ĐžĐēĐĩĐŊŅ‹ ŅĐž scopes { #jwt-token-with-scopes } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ иСĐŧĐĩĐŊĐ¸Ņ‚Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸, Đ˛Ņ‹Đ´Đ°ŅŽŅ‰ŅƒŅŽ Ņ‚ĐžĐēĐĩĐŊ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅˆĐĩĐŊĐŊŅ‹Đĩ scopes. + +ĐœŅ‹ Đ˛ŅŅ‘ Đĩ҉ґ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Ņ‚ĐžŅ‚ ĐļĐĩ `OAuth2PasswordRequestForm`. ОĐŊ вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž `scopes` ҁ `list` иС `str` — ĐēаĐļĐ´Ņ‹Đš scope, ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đš в СаĐŋŅ€ĐžŅĐĩ. + +И ĐŧŅ‹ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧ scopes ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ JWTâ€‘Ņ‚ĐžĐēĐĩĐŊа. + +/// danger | ОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ + +ДĐģŅ ĐŋŅ€ĐžŅŅ‚ĐžŅ‚Ņ‹ СдĐĩҁҌ ĐŧŅ‹ ĐŋŅ€ĐžŅŅ‚Đž дОйавĐģŅĐĩĐŧ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đĩ scopes ĐŋŅ€ŅĐŧĐž в Ņ‚ĐžĐēĐĩĐŊ. + +Но в Đ˛Đ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии, в ҆ĐĩĐģŅŅ… ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž Đ˛Ņ‹ дОйавĐģŅĐĩŅ‚Đĩ Ņ‚ĐžĐģҌĐēĐž Ņ‚Đĩ scopes, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŧĐžĐļĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ, иĐģи Ņ‚Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐˇĐ°Ņ€Đ°ĐŊĐĩĐĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģиĐģи. + +/// + +{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *} + +## ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊиĐĩ scopes в *ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐ°Ņ… ĐŋŅƒŅ‚ĐĩĐš* и ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… { #declare-scopes-in-path-operations-and-dependencies } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐžĐąŅŠŅĐ˛Đ¸Đŧ, Ņ‡Ņ‚Đž ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸ Đ´ĐģŅ `/users/me/items/` ҂ҀĐĩĐąŅƒĐĩŅ‚ scope `items`. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐĩĐŧ и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ `Security` иС `fastapi`. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `Security` Đ´ĐģŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš (ĐēаĐē `Depends`), ĐŊĐž `Security` Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `scopes` ŅĐž ҁĐŋĐ¸ŅĐēĐžĐŧ scopes (ŅŅ‚Ņ€ĐžĐē). + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŧŅ‹ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Đŧ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽâ€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_active_user` в `Security` (Ņ‚ĐžŅ‡ĐŊĐž Ņ‚Đ°Đē ĐļĐĩ, ĐēаĐē ŅĐ´ĐĩĐģаĐģи ĐąŅ‹ ҁ `Depends`). + +Но ĐŧŅ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Đŧ `list` scopes — в даĐŊĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ scope: `items` (Đ¸Ņ… ĐŧĐžĐŗĐģĐž ĐąŅ‹Ņ‚ŅŒ йОĐģҌ҈Đĩ). + +И Ņ„ŅƒĐŊĐēŅ†Đ¸Ņâ€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_active_user` Ņ‚ĐžĐļĐĩ ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŊĐĩ Ņ‚ĐžĐģҌĐēĐž ҇ĐĩŅ€ĐĩС `Depends`, ĐŊĐž и ҇ĐĩŅ€ĐĩС `Security`, ĐžĐąŅŠŅĐ˛ĐģŅŅ ŅĐ˛ĐžŅŽ ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ (`get_current_user`) и Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ҂ҀĐĩйОваĐŊĐ¸Ņ ĐŋĐž scopes. + +В даĐŊĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ scope `me` (Đ¸Ņ… Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐŗĐģĐž ĐąŅ‹Ņ‚ŅŒ йОĐģҌ҈Đĩ ОдĐŊĐžĐŗĐž). + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +ВаĐŧ ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž дОйавĐģŅŅ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ scopes в Ņ€Đ°ĐˇĐŊҋ҅ ĐŧĐĩŅŅ‚Đ°Ņ…. + +ĐœŅ‹ Đ´ĐĩĐģаĐĩĐŧ ŅŅ‚Đž СдĐĩҁҌ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒ, ĐēаĐē **FastAPI** ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ scopes, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ ĐŊа Ņ€Đ°ĐˇĐŊҋ҅ ŅƒŅ€ĐžĐ˛ĐŊŅŅ…. + +/// + +{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *} + +/// info | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +`Security` ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ĐŋОдĐēĐģĐ°ŅŅĐžĐŧ `Depends` и иĐŧĐĩĐĩŅ‚ Đ˛ŅĐĩĐŗĐž ОдиĐŊ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧŅ‹ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ĐŋОСĐļĐĩ. + +Но Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `Security` вĐŧĐĩŅŅ‚Đž `Depends`, **FastAPI** ĐąŅƒĐ´ĐĩŅ‚ СĐŊĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ security scopes, Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… вĐŊŅƒŅ‚Ņ€Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ API в OpenAPI. + +ОдĐŊаĐēĐž ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐĩŅ‚Đĩ `Query`, `Path`, `Depends`, `Security` и Đ´Ņ€ŅƒĐŗĐ¸Đĩ иС `fastapi`, ŅŅ‚Đž ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ŅŽŅ‰Đ¸Đĩ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊŅ‹Đĩ ĐēĐģĐ°ŅŅŅ‹. + +/// + +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `SecurityScopes` { #use-securityscopes } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ОйĐŊОвиĐŧ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_user`. + +ИĐŧĐĩĐŊĐŊĐž ĐĩŅ‘ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ Đ˛Ņ‹ŅˆĐĩ. + +ЗдĐĩҁҌ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Ņ‚Ņƒ ĐļĐĩ ҁ҅ĐĩĐŧ҃ OAuth2, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅƒŅŽ Ņ€Đ°ĐŊĐĩĐĩ, ĐžĐąŅŠŅĐ˛ĐģŅŅ ĐĩŅ‘ ĐēаĐē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ: `oauth2_scheme`. + +ĐŸĐžŅĐēĐžĐģҌĐē҃ ҃ ŅŅ‚ĐžĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸â€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŊĐĩŅ‚ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊҋ҅ ҂ҀĐĩйОваĐŊиК ĐŋĐž scopes, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `Depends` ҁ `oauth2_scheme` — ĐŊаĐŧ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `Security`, ĐĩҁĐģи ĐŊĐĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ security scopes. + +ĐœŅ‹ Ņ‚Đ°ĐēĐļĐĩ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ Ņ‚Đ¸Đŋа `SecurityScopes`, иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš иС `fastapi.security`. + +КĐģĐ°ŅŅ `SecurityScopes` ĐŋĐžŅ…ĐžĐļ ĐŊа `Request` (҇ĐĩŅ€ĐĩС `Request` ĐŧŅ‹ ĐŋĐžĐģŅƒŅ‡Đ°Đģи ŅĐ°Đŧ ĐžĐąŅŠĐĩĐēŅ‚ СаĐŋŅ€ĐžŅĐ°). + +{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *} + +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `scopes` { #use-the-scopes } + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `security_scopes` ĐąŅƒĐ´ĐĩŅ‚ Ņ‚Đ¸Đŋа `SecurityScopes`. + +ĐŖ ĐŊĐĩĐŗĐž ĐĩŅŅ‚ŅŒ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž `scopes` ŅĐž ҁĐŋĐ¸ŅĐēĐžĐŧ, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đŧ Đ˛ŅĐĩ scopes, ҂ҀĐĩĐąŅƒĐĩĐŧŅ‹Đĩ иĐŧ ŅĐ°ĐŧиĐŧ и Đ˛ŅĐĩĐŧи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰Đ¸Đŧи ĐĩĐŗĐž ĐēаĐē ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ. ĐĸĐž ĐĩŅŅ‚ŅŒ Đ˛ŅĐĩĐŧи ÂĢĐˇĐ°Đ˛Đ¸ŅŅŅ‰Đ¸ĐŧиÂģâ€Ļ ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐˇĐ˛ŅƒŅ‡Đ°Ņ‚ŅŒ СаĐŋŅƒŅ‚Đ°ĐŊĐŊĐž, ĐŊиĐļĐĩ ĐĩŅŅ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐĩ ĐžĐąŅŠŅŅĐŊĐĩĐŊиĐĩ. + +ĐžĐąŅŠĐĩĐēŅ‚ `security_scopes` (ĐēĐģĐ°ŅŅ `SecurityScopes`) Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `scope_str` — ŅŅ‚Đž ОдĐŊа ŅŅ‚Ņ€ĐžĐēа ҁ ŅŅ‚Đ¸Đŧи scopes, Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧи ĐŋŅ€ĐžĐąĐĩĐģаĐŧи (ĐŧŅ‹ ĐąŅƒĐ´ĐĩĐŧ ĐĩŅ‘ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ). + +ĐœŅ‹ ŅĐžĐˇĐ´Đ°Ņ‘Đŧ `HTTPException`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐĩĐŧ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ (`raise`) в ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ…. + +В ŅŅ‚ĐžĐŧ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊии ĐŧŅ‹ вĐēĐģŅŽŅ‡Đ°ĐĩĐŧ ҂ҀĐĩĐąŅƒĐĩĐŧŅ‹Đĩ scopes (ĐĩҁĐģи ĐĩŅŅ‚ŅŒ) в видĐĩ ŅŅ‚Ņ€ĐžĐēи, Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‘ĐŊĐŊОК ĐŋŅ€ĐžĐąĐĩĐģаĐŧи (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ `scope_str`). Đ­Ņ‚Ņƒ ŅŅ‚Ņ€ĐžĐē҃ ŅĐž scopes ĐŧŅ‹ ĐŋĐžĐŧĐĩŅ‰Đ°ĐĩĐŧ в HTTPâ€‘ĐˇĐ°ĐŗĐžĐģОвОĐē `WWW-Authenticate` (ŅŅ‚Đž Ņ‡Đ°ŅŅ‚ŅŒ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸). + +{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *} + +## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа `username` и Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đ° даĐŊĐŊҋ҅ { #verify-the-username-and-data-shape } + +ĐœŅ‹ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩĐŧ, Ņ‡Ņ‚Đž ĐŋĐžĐģŅƒŅ‡Đ¸Đģи `username`, и иСвĐģĐĩĐēаĐĩĐŧ scopes. + +Đ—Đ°Ņ‚ĐĩĐŧ ваĐģĐ¸Đ´Đ¸Ņ€ŅƒĐĩĐŧ ŅŅ‚Đ¸ даĐŊĐŊŅ‹Đĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Pydantic‑ĐŧОдĐĩĐģи (ĐŋĐĩŅ€ĐĩŅ…Đ˛Đ°Ņ‚Ņ‹Đ˛Đ°Ņ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ `ValidationError`), и ĐĩҁĐģи вОСĐŊиĐēаĐĩŅ‚ ĐžŅˆĐ¸ĐąĐēа ĐŋŅ€Đ¸ ҇҂ĐĩĐŊии JWTâ€‘Ņ‚ĐžĐēĐĩĐŊа иĐģи ĐŋŅ€Đ¸ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅ ҁ Pydantic, ĐŧŅ‹ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧ `HTTPException`, ŅĐžĐˇĐ´Đ°ĐŊĐŊĐžĐĩ Ņ€Đ°ĐŊĐĩĐĩ. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐŧŅ‹ ОйĐŊОвĐģŅĐĩĐŧ Pydantic‑ĐŧОдĐĩĐģҌ `TokenData`, дОйавĐģŅŅ ĐŊОвОĐĩ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž `scopes`. + +ВаĐģĐ¸Đ´Đ¸Ņ€ŅƒŅ даĐŊĐŊŅ‹Đĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Pydantic, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ŅƒĐ´ĐžŅŅ‚ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž ҃ ĐŊĐ°Ņ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, иĐŧĐĩĐŊĐŊĐž `list` иС `str` ŅĐž scopes и `str` ҁ `username`. + +А ĐŊĐĩ, ҁĐēаĐļĐĩĐŧ, `dict` иĐģи Ņ‡Ņ‚Đžâ€‘Ņ‚Đž Đĩ҉ґ — вĐĩĐ´ŅŒ ŅŅ‚Đž ĐŧĐžĐŗĐģĐž ĐąŅ‹ ĐŗĐ´Đĩâ€‘Ņ‚Đž ĐŋОСĐļĐĩ ҁĐģĐžĐŧĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ и ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ€Đ¸ŅĐē Đ´ĐģŅ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸. + +ĐœŅ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩĐŧ, Ņ‡Ņ‚Đž ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ ҁ Ņ‚Đ°ĐēиĐŧ иĐŧĐĩĐŊĐĩĐŧ, и ĐĩҁĐģи ĐŊĐĩŅ‚ — Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧ Ņ‚Đž ĐļĐĩ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ, ŅĐžĐˇĐ´Đ°ĐŊĐŊĐžĐĩ Ņ€Đ°ĐŊĐĩĐĩ. + +{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *} + +## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа `scopes` { #verify-the-scopes } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩĐŧ, Ņ‡Ņ‚Đž Đ˛ŅĐĩ ҂ҀĐĩĐąŅƒĐĩĐŧŅ‹Đĩ scopes — ŅŅ‚ĐžĐš ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒŅŽ и Đ˛ŅĐĩĐŧи ĐˇĐ°Đ˛Đ¸ŅŅŅ‰Đ¸Đŧи (вĐēĐģŅŽŅ‡Đ°Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸) — ĐŋŅ€Đ¸ŅŅƒŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‚ ҁҀĐĩди scopes, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐŊҋ҅ в ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊĐžĐŧ Ņ‚ĐžĐēĐĩĐŊĐĩ, иĐŊĐ°Ņ‡Đĩ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩĐŧ `HTTPException`. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ `security_scopes.scopes`, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš `list` ŅĐž Đ˛ŅĐĩĐŧи ŅŅ‚Đ¸Đŧи scopes ĐēаĐē `str`. + +{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *} + +## ДĐĩŅ€ĐĩвО ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš и scopes { #dependency-tree-and-scopes } + +Đ•Ņ‰Ņ‘ Ņ€Đ°Đˇ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ Đ´ĐĩŅ€ĐĩвО ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš и scopes. + +ĐĸаĐē ĐēаĐē ҃ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ `get_current_active_user` ĐĩŅŅ‚ŅŒ ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_user`, scope `"me"`, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đš в `get_current_active_user`, ĐąŅƒĐ´ĐĩŅ‚ вĐēĐģŅŽŅ‡Ņ‘ĐŊ в ҁĐŋĐ¸ŅĐžĐē ҂ҀĐĩĐąŅƒĐĩĐŧҋ҅ scopes в `security_scopes.scopes`, ĐŋĐĩŅ€ĐĩдаваĐĩĐŧŅ‹Đš в `get_current_user`. + +ХаĐŧа ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸ Ņ‚ĐžĐļĐĩ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚ scope — `"items"`, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐžĐŊ Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ в ҁĐŋĐ¸ŅĐēĐĩ `security_scopes.scopes`, ĐŋĐĩŅ€ĐĩдаваĐĩĐŧĐžĐŧ в `get_current_user`. + +ИĐĩŅ€Đ°Ņ€Ņ…Đ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš и scopes Đ˛Ņ‹ĐŗĐģŅĐ´Đ¸Ņ‚ Ņ‚Đ°Đē: + +- ОĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸ `read_own_items`: + - ЗаĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°ĐĩŅ‚ scopes `["items"]` ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒŅŽ: + - `get_current_active_user`: + - Đ¤ŅƒĐŊĐēŅ†Đ¸Ņâ€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_active_user`: + - ЗаĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°ĐĩŅ‚ scopes `["me"]` ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒŅŽ: + - `get_current_user`: + - Đ¤ŅƒĐŊĐēŅ†Đ¸Ņâ€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_user`: + - ĐĄĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊҋ҅ scopes ĐŊĐĩ СаĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°ĐĩŅ‚. + - ИĐŧĐĩĐĩŅ‚ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰ŅƒŅŽ `oauth2_scheme`. + - ИĐŧĐĩĐĩŅ‚ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `security_scopes` Ņ‚Đ¸Đŋа `SecurityScopes`: + - Đ­Ņ‚ĐžŅ‚ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `security_scopes` иĐŧĐĩĐĩŅ‚ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž `scopes` ҁ `list`, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đŧ Đ˛ŅĐĩ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ Đ˛Ņ‹ŅˆĐĩ scopes, Ņ‚Đž ĐĩŅŅ‚ŅŒ: + - `security_scopes.scopes` ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ `["me", "items"]` Đ´ĐģŅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ `read_own_items`. + - `security_scopes.scopes` ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ `["me"]` Đ´ĐģŅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ `read_users_me`, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐžĐŊ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ `get_current_active_user`. + - `security_scopes.scopes` ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ `[]` (ĐŊĐ¸Ņ‡ĐĩĐŗĐž) Đ´ĐģŅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ `read_system_status`, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž Ņ‚Đ°Đŧ ĐŊĐĩ ĐžĐąŅŠŅĐ˛ĐģŅĐģŅŅ `Security` ŅĐž `scopes`, и ĐĩĐŗĐž ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ `get_current_user` Ņ‚ĐžĐļĐĩ ĐŊĐĩ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚ `scopes`. + +/// tip | ХОвĐĩŅ‚ + +ВаĐļĐŊŅ‹Đš и ÂĢĐŧĐ°ĐŗĐ¸Ņ‡ĐĩҁĐēиКÂģ ĐŧĐžĐŧĐĩĐŊŅ‚ СдĐĩҁҌ в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž `get_current_user` ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đš ҁĐŋĐ¸ŅĐžĐē `scopes` Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Đ´ĐģŅ ĐēаĐļдОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸. + +Đ’ŅŅ‘ ŅŅ‚Đž ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ `scopes`, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊҋ҅ в ĐēаĐļдОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ и в ĐēаĐļдОК ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ в Đ´ĐĩŅ€ĐĩвĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸. + +/// + +## БоĐģҌ҈Đĩ Đ´ĐĩŅ‚Đ°ĐģĐĩĐš Đž `SecurityScopes` { #more-details-about-securityscopes } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `SecurityScopes` в ĐģŅŽĐąĐžĐš Ņ‚ĐžŅ‡ĐēĐĩ и в ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ… — ĐŊĐĩĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž в ÂĢĐēĐžŅ€ĐŊĐĩвОКÂģ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. + +ОĐŊ Đ˛ŅĐĩĐŗĐ´Đ° ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ security scopes, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ в Ņ‚ĐĩĐēŅƒŅ‰Đ¸Ņ… ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… `Security`, и Đ˛ŅĐĩĐŧи ĐˇĐ°Đ˛Đ¸ŅŅŅ‰Đ¸Đŧи — Đ´ĐģŅ ŅŅ‚ĐžĐš ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ и ŅŅ‚ĐžĐŗĐž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž Đ´ĐĩŅ€Đĩва ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. + +ĐŸĐžŅĐēĐžĐģҌĐē҃ `SecurityScopes` ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Đ˛ŅĐĩ scopes, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ ĐˇĐ°Đ˛Đ¸ŅŅŅ‰Đ¸Đŧи, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģиСОваĐŊĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ ĐŊаĐģĐ¸Ņ‡Đ¸Đĩ ҂ҀĐĩĐąŅƒĐĩĐŧҋ҅ scopes в Ņ‚ĐžĐēĐĩĐŊĐĩ в ОдĐŊОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸â€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, а ĐˇĐ°Ņ‚ĐĩĐŧ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ ҂ҀĐĩйОваĐŊĐ¸Ņ ĐŋĐž scopes в Ņ€Đ°ĐˇĐŊҋ҅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŅ… ĐŋŅƒŅ‚Đ¸. + +ОĐŊи ĐąŅƒĐ´ŅƒŅ‚ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒŅŅ ĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐž Đ´ĐģŅ ĐēаĐļдОК ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸. + +## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đ¸Đŧ ŅŅ‚Đž { #check-it } + +ĐžŅ‚ĐēŅ€ĐžĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API — Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ и ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ, ĐēаĐēиĐĩ scopes Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ°Đ˛Ņ‚ĐžŅ€Đ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ. + + + +Đ•ŅĐģи Đ˛Ņ‹ ĐŊĐĩ Đ˛Ņ‹ĐąĐĩŅ€ĐĩŅ‚Đĩ ĐŊи ОдиĐŊ scope, Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ÂĢĐ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹Âģ, ĐŊĐž ĐŋŅ€Đ¸ ĐŋĐžĐŋҋ҂ĐēĐĩ Đ´ĐžŅŅ‚ŅƒĐŋа Đē `/users/me/` иĐģи `/users/me/items/` ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐžŅˆĐ¸ĐąĐē҃ Đž ĐŊĐĩĐ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊҋ҅ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊĐ¸ŅŅ…. ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ Đ´ĐžŅŅ‚ŅƒĐŋ Đē `/status/` ĐąŅƒĐ´ĐĩŅ‚ вОСĐŧĐžĐļĐĩĐŊ. + +Đ•ŅĐģи Đ˛Ņ‹ Đ˛Ņ‹ĐąĐĩŅ€ĐĩŅ‚Đĩ scope `me`, ĐŊĐž ĐŊĐĩ `items`, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋ Đē `/users/me/`, ĐŊĐž ĐŊĐĩ Đē `/users/me/items/`. + +ĐĸаĐē и ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ŅŒ ŅĐž ŅŅ‚ĐžŅ€ĐžĐŊĐŊиĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŋĐžĐŋŅ‹Ņ‚Đ°ĐĩŅ‚ŅŅ ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒŅŅ Đē ОдĐŊОК иС ŅŅ‚Đ¸Ņ… ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸ ҁ Ņ‚ĐžĐēĐĩĐŊĐžĐŧ, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐŊŅ‹Đŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐŧ, — в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ Ņ‚ĐžĐŗĐž, ҁĐēĐžĐģҌĐēĐž Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊиК ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ даĐģ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ. + +## О ŅŅ‚ĐžŅ€ĐžĐŊĐŊĐ¸Ņ… иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸ŅŅ… { #about-third-party-integrations } + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ OAuth2 ÂĢpassword flowÂģ (Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ ĐŋĐž ĐŋĐ°Ņ€ĐžĐģŅŽ). + +Đ­Ņ‚Đž ҃ĐŧĐĩҁ҂ĐŊĐž, ĐēĐžĐŗĐ´Đ° ĐŧŅ‹ Đ˛Ņ…ĐžĐ´Đ¸Đŧ в ĐŊĐ°ŅˆĐĩ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ҁ ĐŊĐ°ŅˆĐ¸Đŧ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đŧ Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´ĐžĐŧ. + +ĐœŅ‹ ĐŧĐžĐļĐĩĐŧ ĐĩĐŧ҃ дОвĐĩŅ€ŅŅ‚ŅŒ ĐŋŅ€Đ¸ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊии `username` и `password`, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐžĐŊ ĐŋОд ĐŊĐ°ŅˆĐ¸Đŧ ĐēĐžĐŊŅ‚Ņ€ĐžĐģĐĩĐŧ. + +Но ĐĩҁĐģи Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚Đĩ OAuth2‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, Đē ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ ĐąŅƒĐ´ŅƒŅ‚ ĐŋОдĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒŅŅ Đ´Ņ€ŅƒĐŗĐ¸Đĩ (Ņ‚.Đĩ. Đ˛Ņ‹ ŅŅ‚Ņ€ĐžĐ¸Ņ‚Đĩ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ĐŊаĐŋОдОйиĐĩ Facebook, Google, GitHub и Ņ‚.Đŋ.), ваĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ОдиĐŊ иС Đ´Ņ€ŅƒĐŗĐ¸Ņ… ÂĢflowsÂģ. + +ХаĐŧŅ‹Đš Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅ‘ĐŊĐŊŅ‹Đš — ÂĢimplicit flowÂģ. + +ХаĐŧŅ‹Đš ĐąĐĩСОĐŋĐ°ŅĐŊŅ‹Đš — ÂĢcode flowÂģ, ĐŊĐž ĐžĐŊ ҁĐģĐžĐļĐŊĐĩĐĩ в Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸, Ņ‚Đ°Đē ĐēаĐē ҂ҀĐĩĐąŅƒĐĩŅ‚ йОĐģҌ҈Đĩ ŅˆĐ°ĐŗĐžĐ˛. Из‑за ҁĐģĐžĐļĐŊĐžŅŅ‚Đ¸ ĐŧĐŊĐžĐŗĐ¸Đĩ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩҀҋ в Đ¸Ņ‚ĐžĐŗĐĩ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒŅŽŅ‚ ÂĢimplicit flowÂģ. + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +Đ§Đ°ŅŅ‚Đž ĐēаĐļĐ´Ņ‹Đš ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ ŅĐ˛ĐžĐ¸ ÂĢflowsÂģ ĐŋĐžâ€‘Ņ€Đ°ĐˇĐŊĐžĐŧ҃ — ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ ĐąŅ€ĐĩĐŊда. + +Но в Đ¸Ņ‚ĐžĐŗĐĩ ĐžĐŊи Ņ€ĐĩаĐģĐ¸ĐˇŅƒŅŽŅ‚ ОдиĐŊ и Ņ‚ĐžŅ‚ ĐļĐĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ OAuth2. + +/// + +FastAPI вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ Đ´ĐģŅ Đ˛ŅĐĩŅ… ŅŅ‚Đ¸Ņ… OAuth2‑flows в `fastapi.security.oauth2`. + +## `Security` в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂ҀĐĩ `dependencies` Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đ° { #security-in-decorator-dependencies } + +ĐĸĐžŅ‡ĐŊĐž Ņ‚Đ°Đē ĐļĐĩ, ĐēаĐē Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ `list` иС `Depends` в ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂ҀĐĩ `dependencies` Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đ° (ҁĐŧ. [Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ в Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đ°Ņ… ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đ°Đŧ и `Security` ŅĐž `scopes`. diff --git a/docs/ru/docs/advanced/settings.md b/docs/ru/docs/advanced/settings.md new file mode 100644 index 000000000..a335548c3 --- /dev/null +++ b/docs/ru/docs/advanced/settings.md @@ -0,0 +1,346 @@ +# ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи и ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ { #settings-and-environment-variables } + +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ĐŧĐžĐŗŅƒŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ вĐŊĐĩ҈ĐŊиĐĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи иĐģи ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ҁĐĩĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐēĐģŅŽŅ‡Đ¸, ŅƒŅ‡ĐĩŅ‚ĐŊŅ‹Đĩ даĐŊĐŊŅ‹Đĩ Đ´ĐģŅ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅, ŅƒŅ‡ĐĩŅ‚ĐŊŅ‹Đĩ даĐŊĐŊŅ‹Đĩ Đ´ĐģŅ emailâ€‘ŅĐĩŅ€Đ˛Đ¸ŅĐžĐ˛ и Ņ‚.Đ´. + +БоĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Ņ‚Đ°ĐēĐ¸Ņ… ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē ŅĐ˛ĐģŅŅŽŅ‚ŅŅ иСĐŧĐĩĐŊŅĐĩĐŧŅ‹Đŧи (ĐŧĐžĐŗŅƒŅ‚ ĐŧĐĩĐŊŅŅ‚ŅŒŅŅ), ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ URL ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅. И ĐŧĐŊĐžĐŗĐ¸Đĩ иС ĐŊĐ¸Ņ… ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ÂĢŅ‡ŅƒĐ˛ŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹ĐŧиÂģ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ҁĐĩĐēŅ€Đĩ҂ҋ. + +По ŅŅ‚ĐžĐš ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊĐĩ ĐžĐąŅ‹Ņ‡ĐŊĐž Đ¸Ņ… ĐŋĐĩŅ€ĐĩĐ´Đ°ŅŽŅ‚ ҇ĐĩŅ€ĐĩС ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. + +/// tip | ХОвĐĩŅ‚ + +Đ§Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŊŅŅ‚ŅŒ, Ņ‡Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ [ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ](../environment-variables.md){.internal-link target=_blank}. + +/// + +## ĐĸиĐŋŅ‹ и ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ { #types-and-validation } + +ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ ĐŧĐžĐŗŅƒŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž Ņ‚ĐĩĐēŅŅ‚ĐžĐ˛Ņ‹Đĩ ŅŅ‚Ņ€ĐžĐēи, Ņ‚Đ°Đē ĐēаĐē ĐžĐŊи вĐŊĐĩ҈ĐŊиĐĩ ĐŋĐž ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸ŅŽ Đē Python и Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹ ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧаĐŧи и ĐžŅŅ‚Đ°ĐģҌĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК (и даĐļĐĩ ҁ Ņ€Đ°ĐˇĐŊŅ‹Đŧи ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊŅ‹Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Linux, Windows, macOS). + +Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐģŅŽĐąĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐŊĐŊĐžĐĩ в Python иС ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊОК ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ, ĐąŅƒĐ´ĐĩŅ‚ `str`, а ĐģŅŽĐąŅ‹Đĩ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đē Đ´Ņ€ŅƒĐŗĐ¸Đŧ Ņ‚Đ¸ĐŋаĐŧ иĐģи ĐģŅŽĐąĐ°Ņ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ Đ´ĐžĐģĐļĐŊŅ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ в ĐēОдĐĩ. + +## Pydantic `Settings` { #pydantic-settings } + +К ŅŅ‡Đ°ŅŅ‚ŅŒŅŽ, Pydantic ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅƒŅŽ ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņƒ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ŅŅ‚Đ¸Đŧи ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи, ĐŋĐžŅŅ‚ŅƒĐŋĐ°ŅŽŅ‰Đ¸Đŧи иС ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ, — Pydantic: ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи. + +### ĐŖŅŅ‚Đ°ĐŊОвĐēа `pydantic-settings` { #install-pydantic-settings } + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ŅƒĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Đģи [Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐžĐĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊиĐĩ](../virtual-environments.md){.internal-link target=_blank}, аĐēŅ‚Đ¸Đ˛Đ¸Ņ€ĐžĐ˛Đ°Đģи ĐĩĐŗĐž, а ĐˇĐ°Ņ‚ĐĩĐŧ ŅƒŅŅ‚Đ°ĐŊОвиĐģи ĐŋаĐēĐĩŅ‚ `pydantic-settings`: + +
+ +```console +$ pip install pydantic-settings +---> 100% +``` + +
+ +ОĐŊ Ņ‚Đ°ĐēĐļĐĩ вĐēĐģŅŽŅ‡ĐĩĐŊ ĐŋŅ€Đ¸ ŅƒŅŅ‚Đ°ĐŊОвĐēĐĩ ĐŊĐ°ĐąĐžŅ€Đ° `all` ҁ: + +
+ +```console +$ pip install "fastapi[all]" +---> 100% +``` + +
+ +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В Pydantic v1 ĐžĐŊ Đ˛Ņ…ĐžĐ´Đ¸Đģ в ĐžŅĐŊОвĐŊОК ĐŋаĐēĐĩŅ‚. ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐžĐŊ Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅĐĩŅ‚ŅŅ ĐēаĐē ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš ĐŋаĐēĐĩŅ‚, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛Ņ‹ ĐŧĐžĐŗĐģи ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐĩĐŗĐž Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸. + +/// + +### ХОСдаĐŊиĐĩ ĐžĐąŅŠĐĩĐēŅ‚Đ° `Settings` { #create-the-settings-object } + +ИĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `BaseSettings` иС Pydantic и ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŋОдĐēĐģĐ°ŅŅ, ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļиК ĐŊа Pydantic‑ĐŧОдĐĩĐģҌ. + +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž Pydantic‑ĐŧОдĐĩĐģŅĐŧ, Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Ņ‹ ĐēĐģĐ°ŅŅĐ° ҁ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв и, ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸, СĐŊĐ°Ņ‡ĐĩĐŊĐ¸ŅĐŧи ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ Ņ‚Đĩ ĐļĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ и иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, Ņ‡Ņ‚Đž и Đ´ĐģŅ Pydantic‑ĐŧОдĐĩĐģĐĩĐš, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Ņ€Đ°ĐˇĐŊŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹ даĐŊĐŊҋ҅ и Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ ҇ĐĩŅ€ĐĩС `Field()`. + +//// tab | Pydantic v2 + +{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *} + +//// + +//// tab | Pydantic v1 + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В Pydantic v1 Đ˛Ņ‹ ĐąŅ‹ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Đģи `BaseSettings` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС `pydantic`, а ĐŊĐĩ иС `pydantic_settings`. + +/// + +{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *} + +//// + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž Ņ‡Ņ‚Đž-Ņ‚Đž ĐąŅ‹ŅŅ‚Ņ€Đž ҁĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и Đ˛ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ, ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ŅŅ‚ĐžŅ‚ ĐŋŅ€Đ¸ĐŧĐĩŅ€ — Đ˛ĐžŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚ĐĩҁҌ ĐŋĐžŅĐģĐĩĐ´ĐŊиĐŧ ĐŊиĐļĐĩ. + +/// + +Đ—Đ°Ņ‚ĐĩĐŧ, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°ĐĩŅ‚Đĩ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ŅŅ‚ĐžĐŗĐž ĐēĐģĐ°ŅŅĐ° `Settings` (в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `settings`), Pydantic ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐĩŅ‚ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€ĐžĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐž, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ в вĐĩҀ҅ĐŊĐĩĐŧ Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đĩ `APP_NAME` ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐŊа Đ´ĐģŅ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Đ° `app_name`. + +ДаĐģĐĩĐĩ ĐžĐŊ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒĐĩŅ‚ и ĐŋŅ€ĐžĐ˛Đ°ĐģĐ¸Đ´Đ¸Ņ€ŅƒĐĩŅ‚ даĐŊĐŊŅ‹Đĩ. ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ĐžĐąŅŠĐĩĐēŅ‚Đ° `settings` Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ даĐŊĐŊŅ‹Đĩ Ņ‚ĐĩŅ… Ņ‚Đ¸ĐŋОв, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžĐąŅŠŅĐ˛Đ¸Đģи (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `items_per_user` ĐąŅƒĐ´ĐĩŅ‚ `int`). + +### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `settings` { #use-the-settings } + +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ `settings` в Đ˛Đ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии: + +{* ../../docs_src/settings/tutorial001.py hl[18:20] *} + +### ЗаĐŋ҃ҁĐē ҁĐĩŅ€Đ˛ĐĩŅ€Đ° { #run-the-server } + +ДаĐģĐĩĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ҁĐĩŅ€Đ˛ĐĩŅ€, ĐŋĐĩŅ€Đĩдав ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ ҇ĐĩŅ€ĐĩС ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŧĐžĐļĐŊĐž ĐˇĐ°Đ´Đ°Ņ‚ŅŒ `ADMIN_EMAIL` и `APP_NAME` Ņ‚Đ°Đē: + +
+ +```console +$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +/// tip | ХОвĐĩŅ‚ + +Đ§Ņ‚ĐžĐąŅ‹ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ Đ´ĐģŅ ОдĐŊОК ĐēĐžĐŧаĐŊĐ´Ņ‹, ĐŋŅ€ĐžŅŅ‚Đž Ņ€Đ°ĐˇĐ´ĐĩĐģŅĐšŅ‚Đĩ Đ¸Ņ… ĐŋŅ€ĐžĐąĐĩĐģаĐŧи и ҃ĐēаĐļĐ¸Ņ‚Đĩ Đ˛ŅĐĩ ĐŋĐĩŅ€ĐĩĐ´ ĐēĐžĐŧаĐŊдОК. + +/// + +ĐĸĐžĐŗĐ´Đ° ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `admin_email` ĐąŅƒĐ´ĐĩŅ‚ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ в `"deadpool@example.com"`. + +`app_name` ĐąŅƒĐ´ĐĩŅ‚ `"ChimichangApp"`. + +А `items_per_user` ŅĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ `50`. + +## ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи в Đ´Ņ€ŅƒĐŗĐžĐŧ ĐŧĐžĐ´ŅƒĐģĐĩ { #settings-in-another-module } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ‹ĐŊĐĩŅŅ‚Đ¸ ŅŅ‚Đ¸ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи в Đ´Ņ€ŅƒĐŗĐžĐš ĐŧĐžĐ´ŅƒĐģҌ, ĐēаĐē ĐŋĐžĐēаСаĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [БоĐģŅŒŅˆĐ¸Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — ĐŊĐĩҁĐēĐžĐģҌĐēĐž Ņ„Đ°ĐšĐģОв](../tutorial/bigger-applications.md){.internal-link target=_blank}. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ„Đ°ĐšĐģ `config.py` ŅĐž ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧŅ‹Đŧ: + +{* ../../docs_src/settings/app01/config.py *} + +А ĐˇĐ°Ņ‚ĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž в Ņ„Đ°ĐšĐģĐĩ `main.py`: + +{* ../../docs_src/settings/app01/main.py hl[3,11:13] *} + +/// tip | ХОвĐĩŅ‚ + +ВаĐŧ Ņ‚Đ°ĐēĐļĐĩ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ Ņ„Đ°ĐšĐģ `__init__.py`, ĐēаĐē в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [БоĐģŅŒŅˆĐ¸Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — ĐŊĐĩҁĐēĐžĐģҌĐēĐž Ņ„Đ°ĐšĐģОв](../tutorial/bigger-applications.md){.internal-link target=_blank}. + +/// + +## ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐēаĐē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ { #settings-in-a-dependency } + +ИĐŊĐžĐŗĐ´Đ° ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊĐž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅ‚ŅŒ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ҇ĐĩŅ€ĐĩС ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, вĐŧĐĩŅŅ‚Đž ĐŗĐģОйаĐģҌĐŊĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ° `settings`, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧĐžĐŗĐž ĐŋĐžĐ˛ŅŅŽĐ´Ņƒ. + +Đ­Ņ‚Đž ĐžŅĐžĐąĐĩĐŊĐŊĐž ŅƒĐ´ĐžĐąĐŊĐž ĐŋŅ€Đ¸ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊии, Ņ‚Đ°Đē ĐēаĐē ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēĐž ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ ŅĐ˛ĐžĐ¸Đŧи ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи. + +### ФаКĐģ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ { #the-config-file } + +ĐŸŅ€ĐžĐ´ĐžĐģĐļĐ°Ņ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Đ°Ņˆ Ņ„Đ°ĐšĐģ `config.py` ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: + +{* ../../docs_src/settings/app02/config.py hl[10] *} + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐŧŅ‹ ĐŊĐĩ ŅĐžĐˇĐ´Đ°ĐĩĐŧ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ `settings = Settings()`. + +### ĐžŅĐŊОвĐŊОК Ņ„Đ°ĐšĐģ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ { #the-main-app-file } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŧŅ‹ ŅĐžĐˇĐ´Đ°ĐĩĐŧ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ĐŊĐžĐ˛Ņ‹Đš `config.Settings()`. + +{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *} + +/// tip | ХОвĐĩŅ‚ + +ĐĄĐēĐžŅ€Đž ĐŧŅ‹ ĐžĐąŅŅƒĐ´Đ¸Đŧ `@lru_cache`. + +ПоĐēа ĐŧĐžĐļĐŊĐž ŅŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž `get_settings()` — ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ. + +/// + +Đ—Đ°Ņ‚ĐĩĐŧ ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ СаĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ ĐĩĐĩ в *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸* ĐēаĐē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đ°Đŧ, ĐŗĐ´Đĩ ĐŊ҃ĐļĐŊĐž. + +{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *} + +### ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи и Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ { #settings-and-testing } + +ДаĐģĐĩĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Đž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš ĐžĐąŅŠĐĩĐēŅ‚ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē вО Đ˛Ņ€ĐĩĐŧŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, ŅĐžĐˇĐ´Đ°Đ˛ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ Đ´ĐģŅ `get_settings`: + +{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *} + +В ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊии ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŧŅ‹ СадаĐĩĐŧ ĐŊОвОĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ `admin_email` ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐŊĐžĐ˛ĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ° `Settings`, а ĐˇĐ°Ņ‚ĐĩĐŧ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧ ŅŅ‚ĐžŅ‚ ĐŊĐžĐ˛Ņ‹Đš ĐžĐąŅŠĐĩĐēŅ‚. + +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ĐžĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ. + +## Đ§Ņ‚ĐĩĐŊиĐĩ Ņ„Đ°ĐšĐģа `.env` { #reading-a-env-file } + +Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐŧĐŊĐžĐŗĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐŗŅƒŅ‚ Ņ‡Đ°ŅŅ‚Đž ĐŧĐĩĐŊŅŅ‚ŅŒŅŅ, вОСĐŧĐžĐļĐŊĐž в Ņ€Đ°ĐˇĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸ŅŅ…, ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ŅƒĐ´ĐžĐąĐŊĐž ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ Đ¸Ņ… в Ņ„Đ°ĐšĐģ и Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ ĐžŅ‚Ņ‚ŅƒĐ´Đ° ĐēаĐē ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ. + +Đ­Ņ‚Đ° ĐŋŅ€Đ°ĐēŅ‚Đ¸Đēа Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊĐĩĐŊа и иĐŧĐĩĐĩŅ‚ ĐŊаСваĐŊиĐĩ: Ņ‚Đ°ĐēиĐĩ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ ĐžĐąŅ‹Ņ‡ĐŊĐž Ņ€Đ°ĐˇĐŧĐĩŅ‰Đ°ŅŽŅ‚ в Ņ„Đ°ĐšĐģĐĩ `.env`, а ŅĐ°Đŧ Ņ„Đ°ĐšĐģ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ÂĢdotenvÂģ. + +/// tip | ХОвĐĩŅ‚ + +ФаКĐģ, ĐŊĐ°Ņ‡Đ¸ĐŊĐ°ŅŽŅ‰Đ¸ĐšŅŅ ҁ Ņ‚ĐžŅ‡Đēи (`.`), ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ҁĐēҀҋ҂ҋĐŧ в ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ…, ĐŋОдОйĐŊҋ҅ Unix, Ņ‚Đ°ĐēĐ¸Ņ… ĐēаĐē Linux и macOS. + +Но Ņ„Đ°ĐšĐģ dotenv ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž Đ´ĐžĐģĐļĐĩĐŊ иĐŧĐĩŅ‚ŅŒ иĐŧĐĩĐŊĐŊĐž Ņ‚Đ°ĐēĐžĐĩ иĐŧŅ. + +/// + +Pydantic ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ ҇҂ĐĩĐŊиĐĩ Ņ‚Đ°ĐēĐ¸Ņ… Ņ„Đ°ĐšĐģОв ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ вĐŊĐĩ҈ĐŊĐĩĐš йийĐģĐ¸ĐžŅ‚ĐĩĐēи. ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ СдĐĩҁҌ: Pydantic Settings: ĐŋОддĐĩŅ€ĐļĐēа Dotenv (.env). + +/// tip | ХОвĐĩŅ‚ + +Đ§Ņ‚ĐžĐąŅ‹ ŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐģĐž, ваĐŧ ĐŊ҃ĐļĐŊĐž `pip install python-dotenv`. + +/// + +### ФаКĐģ `.env` { #the-env-file } + +ĐŖ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ„Đ°ĐšĐģ `.env` ŅĐž ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧŅ‹Đŧ: + +```bash +ADMIN_EMAIL="deadpool@example.com" +APP_NAME="ChimichangApp" +``` + +### Đ§Ņ‚ĐĩĐŊиĐĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē иС `.env` { #read-settings-from-env } + +Đ—Đ°Ņ‚ĐĩĐŧ ОйĐŊĐžĐ˛Đ¸Ņ‚Đĩ Đ˛Đ°Ņˆ `config.py` Ņ‚Đ°Đē: + +//// tab | Pydantic v2 + +{* ../../docs_src/settings/app03_an/config.py hl[9] *} + +/// tip | ХОвĐĩŅ‚ + +ĐŅ‚Ņ€Đ¸ĐąŅƒŅ‚ `model_config` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ Pydantic. ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ҁĐŧ. Pydantic: Concepts: Configuration. + +/// + +//// + +//// tab | Pydantic v1 + +{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *} + +/// tip | ХОвĐĩŅ‚ + +КĐģĐ°ŅŅ `Config` Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ Pydantic. ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ҁĐŧ. Pydantic Model Config. + +/// + +//// + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +В Pydantic вĐĩŅ€ŅĐ¸Đ¸ 1 ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Ņ СадаваĐģĐ°ŅŅŒ вО вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐŧ ĐēĐģĐ°ŅŅĐĩ `Config`, в Pydantic вĐĩŅ€ŅĐ¸Đ¸ 2 — в Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚Đĩ `model_config`. Đ­Ņ‚ĐžŅ‚ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ `dict`, и Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ и ĐžŅˆĐ¸ĐąĐēи ÂĢĐŊа ĐģĐĩŅ‚ŅƒÂģ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `SettingsConfigDict` Đ´ĐģŅ ĐžĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ ŅŅ‚ĐžĐŗĐž `dict`. + +/// + +ЗдĐĩҁҌ ĐŧŅ‹ СадаĐĩĐŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ `env_file` вĐŊŅƒŅ‚Ņ€Đ¸ Đ˛Đ°ŅˆĐĩĐŗĐž ĐēĐģĐ°ŅŅĐ° Pydantic `Settings` и ŅƒŅŅ‚Đ°ĐŊавĐģиваĐĩĐŧ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ Ņ€Đ°Đ˛ĐŊŅ‹Đŧ иĐŧĐĩĐŊи Ņ„Đ°ĐšĐģа dotenv, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ…ĐžŅ‚Đ¸Đŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ. + +### ХОСдаĐŊиĐĩ `Settings` Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ Ņ€Đ°Đˇ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `lru_cache` { #creating-the-settings-only-once-with-lru-cache } + +Đ§Ņ‚ĐĩĐŊиĐĩ Ņ„Đ°ĐšĐģа ҁ Đ´Đ¸ŅĐēа ĐžĐąŅ‹Ņ‡ĐŊĐž ĐˇĐ°Ņ‚Ņ€Đ°Ņ‚ĐŊĐ°Ņ (ĐŧĐĩĐ´ĐģĐĩĐŊĐŊĐ°Ņ) ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ, ĐŋĐžŅŅ‚ĐžĐŧ҃, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž ОдиĐŊ Ņ€Đ°Đˇ и ĐˇĐ°Ņ‚ĐĩĐŧ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ОдиĐŊ и Ņ‚ĐžŅ‚ ĐļĐĩ ĐžĐąŅŠĐĩĐēŅ‚ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē, а ĐŊĐĩ Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ Ņ„Đ°ĐšĐģ ĐŋŅ€Đ¸ ĐēаĐļĐ´ĐžĐŧ СаĐŋŅ€ĐžŅĐĩ. + +Но ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ, ĐēĐžĐŗĐ´Đ° ĐŧŅ‹ Đ´ĐĩĐģаĐĩĐŧ: + +```Python +Settings() +``` + +ŅĐžĐˇĐ´Đ°ĐĩŅ‚ŅŅ ĐŊĐžĐ˛Ņ‹Đš ĐžĐąŅŠĐĩĐēŅ‚ `Settings`, и ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐžĐŊ ҁĐŊОва ŅŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ Ņ„Đ°ĐšĐģ `.env`. + +Đ•ŅĐģи ĐąŅ‹ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐąŅ‹Đģа Ņ‚Đ°ĐēОК: + +```Python +def get_settings(): + return Settings() +``` + +ĐŧŅ‹ ĐąŅ‹ ŅĐžĐˇĐ´Đ°Đ˛Đ°Đģи ŅŅ‚ĐžŅ‚ ĐžĐąŅŠĐĩĐēŅ‚ Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž СаĐŋŅ€ĐžŅĐ° и Ņ‡Đ¸Ņ‚Đ°Đģи Ņ„Đ°ĐšĐģ `.env` ĐŊа ĐēаĐļĐ´Ņ‹Đš СаĐŋŅ€ĐžŅ. âš ī¸ + +Но Ņ‚Đ°Đē ĐēаĐē ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ `@lru_cache` ŅĐ˛ĐĩŅ€Ņ…Ņƒ, ĐžĐąŅŠĐĩĐēŅ‚ `Settings` ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐˇĐ´Đ°ĐŊ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ Ņ€Đ°Đˇ — ĐŋŅ€Đ¸ ĐŋĐĩŅ€Đ˛ĐžĐŧ Đ˛Ņ‹ĐˇĐžĐ˛Đĩ. âœ”ī¸ + +{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *} + +Đ—Đ°Ņ‚ĐĩĐŧ ĐŋŅ€Đ¸ ĐģŅŽĐąŅ‹Ņ… ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… Đ˛Ņ‹ĐˇĐžĐ˛Đ°Ņ… `get_settings()` в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ… Đ´ĐģŅ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛, вĐŧĐĩŅŅ‚Đž Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐŗĐž ĐēОда `get_settings()` и ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŊĐžĐ˛ĐžĐŗĐž ĐžĐąŅŠĐĩĐēŅ‚Đ° `Settings`, ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ Ņ‚ĐžŅ‚ ĐļĐĩ ĐžĐąŅŠĐĩĐēŅ‚, Ņ‡Ņ‚Đž ĐąŅ‹Đģ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊ ĐŋŅ€Đ¸ ĐŋĐĩŅ€Đ˛ĐžĐŧ Đ˛Ņ‹ĐˇĐžĐ˛Đĩ, ҁĐŊОва и ҁĐŊОва. + +#### ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи `lru_cache` { #lru-cache-technical-details } + +`@lru_cache` ĐŧĐžĐ´Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ŅƒĐĩŅ‚ Đ´ĐĩĐēĐžŅ€Đ¸Ņ€ŅƒĐĩĐŧŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ Ņ‚Đ°Đē, Ņ‡Ņ‚Đž ĐžĐŊа Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Ņ‚Đž ĐļĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, Ņ‡Ņ‚Đž и в ĐŋĐĩŅ€Đ˛Ņ‹Đš Ņ€Đ°Đˇ, вĐŧĐĩŅŅ‚Đž ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐžĐŗĐž Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ, Ņ‚Đž ĐĩŅŅ‚ŅŒ вĐŧĐĩŅŅ‚Đž Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ ĐēОда Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐŋОд Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ĐžĐŧ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊа ОдиĐŊ Ņ€Đ°Đˇ Đ´ĐģŅ ĐēаĐļдОК ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸Đ¸ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. Đ—Đ°Ņ‚ĐĩĐŧ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊĐŊŅ‹Đĩ Đ´ĐģŅ ĐēаĐļдОК иС ŅŅ‚Đ¸Ņ… ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸Đš, ĐąŅƒĐ´ŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ ҁĐŊОва и ҁĐŊОва ĐŋŅ€Đ¸ Đ˛Ņ‹ĐˇĐžĐ˛Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ҁ Ņ‚ĐžŅ‡ĐŊĐž Ņ‚Đ°ĐēОК ĐļĐĩ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ĐĩĐš Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ: + +```Python +@lru_cache +def say_hi(name: str, salutation: str = "Ms."): + return f"Hello {salutation} {name}" +``` + +Đ˛Đ°ŅˆĐ° ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ Ņ‚Đ°Đē: + +```mermaid +sequenceDiagram + +participant code as Code +participant function as say_hi() +participant execute as Execute function + + rect rgba(0, 255, 0, .1) + code ->> function: say_hi(name="Camila") + function ->> execute: execute function code + execute ->> code: return the result + end + + rect rgba(0, 255, 255, .1) + code ->> function: say_hi(name="Camila") + function ->> code: return stored result + end + + rect rgba(0, 255, 0, .1) + code ->> function: say_hi(name="Rick") + function ->> execute: execute function code + execute ->> code: return the result + end + + rect rgba(0, 255, 0, .1) + code ->> function: say_hi(name="Rick", salutation="Mr.") + function ->> execute: execute function code + execute ->> code: return the result + end + + rect rgba(0, 255, 255, .1) + code ->> function: say_hi(name="Rick") + function ->> code: return stored result + end + + rect rgba(0, 255, 255, .1) + code ->> function: say_hi(name="Camila") + function ->> code: return stored result + end +``` + +В ҁĐģŅƒŅ‡Đ°Đĩ ĐŊĐ°ŅˆĐĩĐš ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ `get_settings()` Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ Đ˛ĐžĐžĐąŅ‰Đĩ ĐŊĐĩ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐžĐŊа Đ˛ŅĐĩĐŗĐ´Đ° Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ ОдĐŊĐž и Ņ‚Đž ĐļĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐžĐŊа вĐĩĐ´ĐĩŅ‚ ҁĐĩĐąŅ ĐŋĐžŅ‡Ņ‚Đ¸ ĐēаĐē ĐŗĐģОйаĐģҌĐŊĐ°Ņ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ. Но Ņ‚Đ°Đē ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņâ€‘ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ĐģĐĩĐŗĐēĐž ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐĩĐĩ Đ´ĐģŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. + +`@lru_cache` — Ņ‡Đ°ŅŅ‚ŅŒ `functools`, Ņ‡Ņ‚Đž Đ˛Ņ…ĐžĐ´Đ¸Ņ‚ в ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅƒŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃ Python. ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Python ĐŋĐž `@lru_cache`. + +## Đ˜Ņ‚ĐžĐŗĐ¸ { #recap } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Pydantic Settings Đ´ĐģŅ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи и ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸ŅĐŧи Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ҁ ĐŋĐžĐģĐŊОК ĐŧĐžŅ‰ŅŒŅŽ Pydantic‑ĐŧОдĐĩĐģĐĩĐš. + +* Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, Đ˛Ņ‹ ҃ĐŋŅ€ĐžŅ‰Đ°ĐĩŅ‚Đĩ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ. +* МоĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ„Đ°ĐšĐģŅ‹ `.env`. +* `@lru_cache` ĐŋОСвОĐģŅĐĩŅ‚ ĐŊĐĩ Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ Ņ„Đ°ĐšĐģ dotenv ҁĐŊОва и ҁĐŊОва Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°, ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ Đ´Đ°Đ˛Đ°Ņ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐĩĐŗĐž вО Đ˛Ņ€ĐĩĐŧŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. diff --git a/docs/ru/docs/advanced/sub-applications.md b/docs/ru/docs/advanced/sub-applications.md new file mode 100644 index 000000000..3464f1704 --- /dev/null +++ b/docs/ru/docs/advanced/sub-applications.md @@ -0,0 +1,67 @@ +# ПодĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — Mounts (ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ) { #sub-applications-mounts } + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊŅ‹ два ĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸Đŧҋ҅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI, ĐēаĐļĐ´ĐžĐĩ ŅĐž ŅĐ˛ĐžĐ¸Đŧ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đŧ OpenAPI и ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đŧи иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°Đŧи Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иĐŧĐĩŅ‚ŅŒ ĐžŅĐŊОвĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ и ÂĢҁĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒÂģ ОдĐŊĐž (иĐģи ĐŊĐĩҁĐēĐžĐģҌĐēĐž) ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. + +## МоĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI** { #mounting-a-fastapi-application } + +ÂĢМоĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩÂģ ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚ дОйавĐģĐĩĐŊиĐĩ ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋĐž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŧ҃ ĐŋŅƒŅ‚Đ¸; даĐģĐĩĐĩ ĐžĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ Đ˛ŅŅ‘ ĐŋОд ŅŅ‚Đ¸Đŧ ĐŋŅƒŅ‚Ņ‘Đŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ в ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии _ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸_. + +### ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ вĐĩҀ҅ĐŊĐĩĐŗĐž ŅƒŅ€ĐžĐ˛ĐŊŅ { #top-level-application } + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐžŅĐŊОвĐŊĐžĐĩ, вĐĩҀ҅ĐŊĐĩĐŗĐž ŅƒŅ€ĐžĐ˛ĐŊŅ, ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** и ĐĩĐŗĐž *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*: + +{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *} + +### ПодĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ { #sub-application } + +Đ—Đ°Ņ‚ĐĩĐŧ ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ и ĐĩĐŗĐž *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +Đ­Ņ‚Đž ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ — ĐžĐąŅ‹Ņ‡ĐŊĐžĐĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI, ĐŊĐž иĐŧĐĩĐŊĐŊĐž ĐžĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ÂĢҁĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐžÂģ: + +{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *} + +### ĐĄĐŧĐžĐŊŅ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ { #mount-the-sub-application } + +В Đ˛Đ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии вĐĩҀ҅ĐŊĐĩĐŗĐž ŅƒŅ€ĐžĐ˛ĐŊŅ, `app`, ҁĐŧĐžĐŊŅ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ `subapi`. + +В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐžĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ҁĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐž ĐŋĐž ĐŋŅƒŅ‚Đ¸ `/subapi`: + +{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *} + +### ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API { #check-the-automatic-api-docs } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐēĐžĐŧаĐŊĐ´Ņƒ `fastapi` ҁ Đ˛Đ°ŅˆĐ¸Đŧ Ņ„Đ°ĐšĐģĐžĐŧ: + +
+ +```console +$ fastapi dev main.py + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +И ĐžŅ‚ĐēŅ€ĐžĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:8000/docs. + +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API Đ´ĐģŅ ĐžŅĐŊОвĐŊĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, вĐēĐģŅŽŅ‡Đ°ŅŽŅ‰ŅƒŅŽ Ņ‚ĐžĐģҌĐēĐž ĐĩĐŗĐž ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ _ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸_: + + + +Đ—Đ°Ņ‚ĐĩĐŧ ĐžŅ‚ĐēŅ€ĐžĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Đ´ĐģŅ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:8000/subapi/docs. + +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API Đ´ĐģŅ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, вĐēĐģŅŽŅ‡Đ°ŅŽŅ‰ŅƒŅŽ Ņ‚ĐžĐģҌĐēĐž ĐĩĐŗĐž ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ _ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸_, Đ˛ŅĐĩ ĐŋОд ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋОдĐŋŅƒŅ‚Đ¸ `/subapi`: + + + +Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐžĐŋŅ€ĐžĐąŅƒĐĩŅ‚Đĩ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ ĐģŅŽĐąŅ‹Đŧ иС Đ´Đ˛ŅƒŅ… иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐ˛, Đ˛ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ҁĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ Đē ĐēаĐļĐ´ĐžĐŧ҃ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ и ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ. + +### ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸: `root_path` { #technical-details-root-path } + +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŧĐžĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚Đĩ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ, FastAPI ĐŋĐžĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ŅŅ Đž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đĩ ĐŋŅƒŅ‚Đ¸ ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Đ´ĐģŅ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŧĐĩŅ…Đ°ĐŊиСĐŧ иС ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ASGI ĐŋОд ĐŊаСваĐŊиĐĩĐŧ `root_path`. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ СĐŊĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Đ´ĐģŅ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ° Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŊ҃ĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐŋŅ€ĐĩŅ„Đ¸Đēҁ ĐŋŅƒŅ‚Đ¸. + +ĐŖ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ŅĐ˛ĐžĐ¸ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ ҁĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ ĐŋОдĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, и Đ˛ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž FastAPI Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ Đ˛ŅĐĩ ŅŅ‚Đ¸ `root_path`. + +Đ’Ņ‹ ŅƒĐˇĐŊаĐĩŅ‚Đĩ йОĐģҌ҈Đĩ Đž `root_path` и Đž Ņ‚ĐžĐŧ, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž ŅĐ˛ĐŊĐž, в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [За ĐŋŅ€ĐžĐēŅĐ¸](behind-a-proxy.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/templates.md b/docs/ru/docs/advanced/templates.md new file mode 100644 index 000000000..5675ff48a --- /dev/null +++ b/docs/ru/docs/advanced/templates.md @@ -0,0 +1,126 @@ +# ШайĐģĐžĐŊŅ‹ { #templates } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐģŅŽĐąĐžĐš ŅˆĐ°ĐąĐģĐžĐŊĐ¸ĐˇĐ°Ņ‚ĐžŅ€ вĐŧĐĩҁ҂Đĩ ҁ **FastAPI**. + +Đ§Đ°ŅŅ‚Đž Đ˛Ņ‹ĐąĐ¸Ņ€Đ°ŅŽŅ‚ Jinja2 — Ņ‚ĐžŅ‚ ĐļĐĩ, Ņ‡Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ вО Flask и Đ´Ņ€ŅƒĐŗĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Ņ…. + +Đ•ŅŅ‚ŅŒ ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ Đ´ĐģŅ ĐŋŅ€ĐžŅŅ‚ĐžĐš ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ŅĐŧĐž в ŅĐ˛ĐžĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии **FastAPI** (ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ŅŅ Starlette). + +## ĐŖŅŅ‚Đ°ĐŊОвĐēа ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš { #install-dependencies } + +ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Đģи [Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐžĐĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊиĐĩ](../virtual-environments.md){.internal-link target=_blank}, аĐēŅ‚Đ¸Đ˛Đ¸Ņ€ĐžĐ˛Đ°Đģи ĐĩĐŗĐž и ŅƒŅŅ‚Đ°ĐŊОвиĐģи `jinja2`: + +
+ +```console +$ pip install jinja2 + +---> 100% +``` + +
+ +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `Jinja2Templates` { #using-jinja2templates } + +- ИĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `Jinja2Templates`. +- ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `templates`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋОСĐļĐĩ. +- ĐžĐąŅŠŅĐ˛Đ¸Ņ‚Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `Request` в *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ŅˆĐ°ĐąĐģĐžĐŊ. +- Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš `templates`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžŅ‚Ņ€ĐĩĐŊĐ´ĐĩŅ€Đ¸Ņ‚ŅŒ и вĐĩŅ€ĐŊŅƒŅ‚ŅŒ `TemplateResponse`; ĐŋĐĩŅ€ĐĩĐ´Đ°ĐšŅ‚Đĩ иĐŧŅ ŅˆĐ°ĐąĐģĐžĐŊа, ĐžĐąŅŠĐĩĐēŅ‚ `request` и ҁĐģĐžĐ˛Đ°Ņ€ŅŒ ÂĢcontextÂģ ҁ ĐŋĐ°Ņ€Đ°Đŧи ĐēĐģŅŽŅ‡-СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ Đ´ĐģŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ вĐŊŅƒŅ‚Ņ€Đ¸ ŅˆĐ°ĐąĐģĐžĐŊа Jinja2. + +{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *} + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +До FastAPI 0.108.0, Starlette 0.29.0, `name` ĐąŅ‹Đģ ĐŋĐĩŅ€Đ˛Ņ‹Đŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐŧ. + +ĐĸаĐēĐļĐĩ Ņ€Đ°ĐŊҌ҈Đĩ, в ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… вĐĩŅ€ŅĐ¸ŅŅ…, ĐžĐąŅŠĐĩĐēŅ‚ `request` ĐŋĐĩŅ€ĐĩдаваĐģŅŅ ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ ĐŋĐ°Ņ€ ĐēĐģŅŽŅ‡-СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ в ĐēĐžĐŊŅ‚ĐĩĐēҁ҂Đĩ Đ´ĐģŅ Jinja2. + +/// + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ `response_class=HTMLResponse`, иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ҁĐŧĐžĐļĐĩŅ‚ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž ĐžŅ‚Đ˛ĐĩŅ‚ ĐąŅƒĐ´ĐĩŅ‚ в Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ HTML. + +/// + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +МоĐļĐŊĐž Ņ‚Đ°ĐēĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.templating import Jinja2Templates`. + +**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚ĐžŅ‚ ĐļĐĩ `starlette.templating` ĐēаĐē `fastapi.templating` ĐŋŅ€ĐžŅŅ‚Đž Đ´ĐģŅ ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ° Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа. Но йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛ ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‚ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС Starlette. ĐĸаĐē ĐļĐĩ и ҁ `Request` и `StaticFiles`. + +/// + +## НаĐŋĐ¸ŅĐ°ĐŊиĐĩ ŅˆĐ°ĐąĐģĐžĐŊОв { #writing-templates } + +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ŅˆĐ°ĐąĐģĐžĐŊ в `templates/item.html`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +```jinja hl_lines="7" +{!../../docs_src/templates/templates/item.html!} +``` + +### ЗĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° ŅˆĐ°ĐąĐģĐžĐŊа { #template-context-values } + +В HTML, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚: + +{% raw %} + +```jinja +Item ID: {{ id }} +``` + +{% endraw %} + +...ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐēаСаĐŊ `id`, Đ˛ĐˇŅŅ‚Ņ‹Đš иС ĐŋĐĩŅ€ĐĩдаĐŊĐŊĐžĐŗĐž ваĐŧи ÂĢcontextÂģ `dict`: + +```Python +{"id": id} +``` + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´ĐģŅ ID `42` ŅŅ‚Đž ĐžŅ‚Ņ€ĐĩĐŊĐ´ĐĩŅ€Đ¸Ņ‚ŅŅ ĐēаĐē: + +```html +Item ID: 42 +``` + +### ĐŅ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ `url_for` в ŅˆĐ°ĐąĐģĐžĐŊĐĩ { #template-url-for-arguments } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `url_for()` вĐŊŅƒŅ‚Ņ€Đ¸ ŅˆĐ°ĐąĐģĐžĐŊа — ĐžĐŊ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Ņ‚Đĩ ĐļĐĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ, Ņ‡Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐ¸ŅŅŒ ĐąŅ‹ Đ˛Đ°ŅˆĐĩĐš *Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ ĐŋŅƒŅ‚Đ¸*. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚: + +{% raw %} + +```jinja + +``` + +{% endraw %} + +...ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ ҁҁҋĐģĐē҃ ĐŊа Ņ‚ĐžŅ‚ ĐļĐĩ URL, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ŅŅ *Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐžĐŧ ĐŋŅƒŅ‚Đ¸* `read_item(id=id)`. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´ĐģŅ ID `42` ŅŅ‚Đž ĐžŅ‚Ņ€ĐĩĐŊĐ´ĐĩŅ€Đ¸Ņ‚ŅŅ ĐēаĐē: + +```html + +``` + +## ШайĐģĐžĐŊŅ‹ и ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹ { #templates-and-static-files } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `url_for()` вĐŊŅƒŅ‚Ņ€Đ¸ ŅˆĐ°ĐąĐģĐžĐŊа, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҁ `StaticFiles`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Đģи ҁ `name="static"`. + +```jinja hl_lines="4" +{!../../docs_src/templates/templates/item.html!} +``` + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐˇĐ´Đ°ĐŊа ҁҁҋĐģĐēа ĐŊа CSS-Ņ„Đ°ĐšĐģ `static/styles.css` ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ: + +```CSS hl_lines="4" +{!../../docs_src/templates/static/styles.css!} +``` + +И, Ņ‚Đ°Đē ĐēаĐē Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ `StaticFiles`, ŅŅ‚ĐžŅ‚ CSS-Ņ„Đ°ĐšĐģ ĐąŅƒĐ´ĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ÂĢĐžŅ‚Đ´Đ°Đ˛Đ°Ņ‚ŅŒŅŅÂģ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ **FastAPI** ĐŋĐž URL `/static/styles.css`. + +## ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ { #more-details } + +БоĐģҌ҈Đĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚ĐĩĐš, вĐēĐģŅŽŅ‡Đ°Ņ Ņ‚Đž, ĐēаĐē Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ŅˆĐ°ĐąĐģĐžĐŊŅ‹, ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Starlette ĐŋĐž ŅˆĐ°ĐąĐģĐžĐŊаĐŧ. diff --git a/docs/ru/docs/advanced/testing-dependencies.md b/docs/ru/docs/advanced/testing-dependencies.md new file mode 100644 index 000000000..2846c5b9a --- /dev/null +++ b/docs/ru/docs/advanced/testing-dependencies.md @@ -0,0 +1,53 @@ +# ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ҁ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸ŅĐŧи { #testing-dependencies-with-overrides } + +## ПĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš вО Đ˛Ņ€ĐĩĐŧŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ { #overriding-dependencies-during-testing } + +Đ•ŅŅ‚ŅŒ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸, ĐēĐžĐŗĐ´Đ° ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ вО Đ˛Ņ€ĐĩĐŧŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. + +Đ’Ņ‹ ĐŊĐĩ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ¸ŅŅ…ĐžĐ´ĐŊĐ°Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģĐ°ŅŅŒ (и ĐģŅŽĐąŅ‹Đĩ ĐĩŅ‘ ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ Ņ‚ĐžĐļĐĩ). + +ВĐŧĐĩŅŅ‚Đž ŅŅ‚ĐžĐŗĐž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗŅƒŅŽ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Ņ‚ĐžĐģҌĐēĐž вО Đ˛Ņ€ĐĩĐŧŅ Ņ‚ĐĩŅŅ‚ĐžĐ˛ (вОСĐŧĐžĐļĐŊĐž, Ņ‚ĐžĐģҌĐēĐž в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ Ņ‚ĐĩŅŅ‚Đ°Ņ…) и ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ вĐĩСдĐĩ, ĐŗĐ´Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐžŅŅŒ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ Đ¸ŅŅ…ĐžĐ´ĐŊОК ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. + +### Đ’Đ°Ņ€Đ¸Đ°ĐŊ҂ҋ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ: вĐŊĐĩ҈ĐŊиК ҁĐĩŅ€Đ˛Đ¸Ņ { #use-cases-external-service } + +ĐŸŅ€Đ¸ĐŧĐĩŅ€: ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ вĐŊĐĩ҈ĐŊиК ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸, Đē ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ ĐŊ҃ĐļĐŊĐž ĐžĐąŅ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ. + +Đ’Ņ‹ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚Đĩ ĐĩĐŧ҃ Ņ‚ĐžĐēĐĩĐŊ, а ĐžĐŊ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ. + +ĐĸаĐēОК ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ ĐŧĐžĐļĐĩŅ‚ ĐąŅ€Đ°Ņ‚ŅŒ ĐŋĐģĐ°Ņ‚Ņƒ Са ĐēаĐļĐ´Ņ‹Đš СаĐŋŅ€ĐžŅ, и ĐĩĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛ ĐŧĐžĐļĐĩŅ‚ СаĐŊиĐŧĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ Đ˛Ņ€ĐĩĐŧĐĩĐŊи, ҇ĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Ņ„Đ¸ĐēŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž ĐŧĐžĐē-ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ Đ´ĐģŅ Ņ‚ĐĩŅŅ‚ĐžĐ˛. + +ВĐĩŅ€ĐžŅŅ‚ĐŊĐž, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ вĐŊĐĩ҈ĐŊиК ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ ОдиĐŊ Ņ€Đ°Đˇ, ĐŊĐž ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž СаĐŋ҃ҁĐēаĐĩĐŧĐžĐŗĐž Ņ‚ĐĩŅŅ‚Đ°. + +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ Đē ŅŅ‚ĐžĐŧ҃ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Ņƒ, и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅƒŅŽ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ŅŽŅ‰ŅƒŅŽ ĐŧĐžĐē-ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ, Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ Đ˛Đ°ŅˆĐ¸Ņ… Ņ‚ĐĩŅŅ‚ĐžĐ˛. + +### Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `app.dependency_overrides` { #use-the-app-dependency-overrides-attribute } + +ДĐģŅ Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°Đĩв ҃ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI** ĐĩŅŅ‚ŅŒ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `app.dependency_overrides`, ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚ĐžĐš `dict`. + +Đ§Ņ‚ĐžĐąŅ‹ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ Đ´ĐģŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, ҃ĐēаĐļĐ¸Ņ‚Đĩ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐēĐģŅŽŅ‡Đ° Đ¸ŅŅ…ĐžĐ´ĐŊŅƒŅŽ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ (Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ), а в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ — Đ˛Đ°ŅˆĐĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ (Đ´Ņ€ŅƒĐŗŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ). + +ĐĸĐžĐŗĐ´Đ° **FastAPI** ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ вĐŧĐĩŅŅ‚Đž Đ¸ŅŅ…ĐžĐ´ĐŊОК ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. + +{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *} + +/// tip | ХОвĐĩŅ‚ + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ Đ´ĐģŅ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧОК в ĐģŅŽĐąĐžĐŧ ĐŧĐĩҁ҂Đĩ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI**. + +Đ˜ŅŅ…ĐžĐ´ĐŊĐ°Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ ĐŧĐžĐļĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ в Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ ĐŋŅƒŅ‚Đ¸, в Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Đĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸ (ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ), в Đ˛Ņ‹ĐˇĐžĐ˛Đĩ `.include_router()` и Ņ‚.Đ´. + +FastAPI Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ҁĐŧĐžĐļĐĩŅ‚ ĐĩŅ‘ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ. + +/// + +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐąŅ€ĐžŅĐ¸Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ (ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ Đ¸Ņ…), ŅƒŅŅ‚Đ°ĐŊОвив `app.dependency_overrides` в ĐŋŅƒŅŅ‚ĐžĐš `dict`: + +```Python +app.dependency_overrides = {} +``` + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž вО Đ˛Ņ€ĐĩĐŧŅ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Ņ‚ĐĩŅŅ‚ĐžĐ˛, ĐˇĐ°Đ´Đ°ĐšŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ в ĐŊĐ°Ņ‡Đ°ĐģĐĩ Ņ‚ĐĩŅŅ‚Đ° (вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Ņ‚ĐĩŅŅ‚Đ°) и ŅĐąŅ€ĐžŅŅŒŅ‚Đĩ ĐĩĐŗĐž в ĐēĐžĐŊ҆Đĩ (в ĐēĐžĐŊ҆Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Ņ‚ĐĩŅŅ‚Đ°). + +/// diff --git a/docs/ru/docs/advanced/testing-events.md b/docs/ru/docs/advanced/testing-events.md new file mode 100644 index 000000000..1bf8e4723 --- /dev/null +++ b/docs/ru/docs/advanced/testing-events.md @@ -0,0 +1,12 @@ +# ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ŅĐžĐąŅ‹Ņ‚Đ¸Đš: lifespan и startup - shutdown { #testing-events-lifespan-and-startup-shutdown } + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ `lifespan` Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģŅŅ в Đ˛Đ°ŅˆĐ¸Ņ… Ņ‚ĐĩŅŅ‚Đ°Ņ…, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `TestClient` вĐŧĐĩҁ҂Đĩ ҁ ĐžĐŋĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐŧ `with`: + +{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *} + + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚ĐĩĐš в ŅŅ‚Đ°Ņ‚ŅŒĐĩ [ЗаĐŋ҃ҁĐē lifespan в Ņ‚ĐĩŅŅ‚Đ°Ņ… ĐŊа ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ ŅĐ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Starlette.](https://www.starlette.io/lifespan/#running-lifespan-in-tests) + +ДĐģŅ ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐ¸Ņ… ŅĐžĐąŅ‹Ņ‚Đ¸Đš `startup` и `shutdown` Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `TestClient` ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ: + +{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *} diff --git a/docs/ru/docs/advanced/testing-websockets.md b/docs/ru/docs/advanced/testing-websockets.md new file mode 100644 index 000000000..7c0ca2594 --- /dev/null +++ b/docs/ru/docs/advanced/testing-websockets.md @@ -0,0 +1,13 @@ +# ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ WebSocket { #testing-websockets } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžŅ‚ ĐļĐĩ `TestClient` Đ´ĐģŅ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ WebSocket. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `TestClient` ҁ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ° `with`, ĐŋОдĐēĐģŅŽŅ‡Đ°ŅŅŅŒ Đē WebSocket: + +{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *} + +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ + +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Starlette ĐŋĐž Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸ŅŽ WebSocket. + +/// diff --git a/docs/ru/docs/advanced/using-request-directly.md b/docs/ru/docs/advanced/using-request-directly.md new file mode 100644 index 000000000..bff2ddcb7 --- /dev/null +++ b/docs/ru/docs/advanced/using-request-directly.md @@ -0,0 +1,56 @@ +# ĐŸŅ€ŅĐŧĐžĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Request { #using-the-request-directly } + +До ŅŅ‚ĐžĐŗĐž Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐģи ĐŊ҃ĐļĐŊŅ‹Đĩ Ņ‡Đ°ŅŅ‚Đ¸ HTTP-СаĐŋŅ€ĐžŅĐ° вĐŧĐĩҁ҂Đĩ ҁ Đ¸Ņ… Ņ‚Đ¸ĐŋаĐŧи. + +ИСвĐģĐĩĐēĐ°Ņ даĐŊĐŊŅ‹Đĩ иС: + +* ĐŋŅƒŅ‚Đ¸ (ĐēаĐē ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛), +* HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēОв, +* Cookie, +* и Ņ‚.Đ´. + +ĐĸĐĩĐŧ ŅĐ°ĐŧŅ‹Đŧ **FastAPI** ваĐģĐ¸Đ´Đ¸Ņ€ŅƒĐĩŅ‚ ŅŅ‚Đ¸ даĐŊĐŊŅ‹Đĩ, ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒĐĩŅ‚ Đ¸Ņ… и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž API. + +Но ĐąŅ‹Đ˛Đ°ŅŽŅ‚ ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸Đ¸, ĐēĐžĐŗĐ´Đ° ĐŊ҃ĐļĐŊĐž ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒŅŅ Đē ĐžĐąŅŠĐĩĐēŅ‚Ņƒ `Request` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +## ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ Ой ĐžĐąŅŠĐĩĐēŅ‚Đĩ `Request` { #details-about-the-request-object } + +ĐĸаĐē ĐēаĐē ĐŋОд ĐēаĐŋĐžŅ‚ĐžĐŧ **FastAPI** — ŅŅ‚Đž **Starlette** ҁ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ ҁĐģĐžĐĩĐŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐąŅŠĐĩĐēŅ‚ `Request` иС Starlette. + +Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐĩҁĐģи Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ даĐŊĐŊŅ‹Đĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иС ĐžĐąŅŠĐĩĐēŅ‚Đ° `Request` (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Đ¸Ņ‚Đ°ĐĩŅ‚Đĩ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ°), Ņ‚Đž ĐžĐŊи ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ, ĐēĐžĐŊвĐĩŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ иĐģи Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ (ҁ OpenAPI, Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ° API) ҁҀĐĩĐ´ŅŅ‚Đ˛Đ°Đŧи FastAPI. + +ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐģŅŽĐąĐžĐš Đ´Ņ€ŅƒĐŗĐžĐš ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đš ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° ҁ Pydantic-ĐŧОдĐĩĐģŅŒŅŽ), ĐŋĐž-ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ ĐąŅƒĐ´ĐĩŅ‚ ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ, ĐēĐžĐŊвĐĩŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ, аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ и Ņ‚.Đ´. + +Но ĐĩŅŅ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° ĐŋĐžĐģĐĩСĐŊĐž ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐžĐąŅŠĐĩĐēŅ‚ `Request`. + +## Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐžĐąŅŠĐĩĐēŅ‚ `Request` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ { #use-the-request-object-directly } + +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ IP-Đ°Đ´Ņ€Đĩҁ/Ņ…ĐžŅŅ‚ ĐēĐģиĐĩĐŊŅ‚Đ° вĐŊŅƒŅ‚Ņ€Đ¸ Đ˛Đ°ŅˆĐĩĐš *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸*. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐŊ҃ĐļĐŊĐž ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒŅŅ Đē СаĐŋŅ€ĐžŅŅƒ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *} + +Đ•ŅĐģи ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа ĐŋŅƒŅ‚Đ¸* ҁ Ņ‚Đ¸ĐŋĐžĐŧ `Request`, **FastAPI** ĐŋОКĐŧґ҂, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐžĐąŅŠĐĩĐēŅ‚ `Request` в ŅŅ‚ĐžŅ‚ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ. + +/// tip | ХОвĐĩŅ‚ + +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž в ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ĐŧŅ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ path-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ вĐŧĐĩҁ҂Đĩ ҁ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐŧ `Request`. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, path-ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ ĐąŅƒĐ´ĐĩŅ‚ иСвĐģĐĩ҇ґĐŊ, ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°ĐŊ, ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊ Đē ҃ĐēаСаĐŊĐŊĐžĐŧ҃ Ņ‚Đ¸Đŋ҃ и СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊ в OpenAPI. + +ĐĸĐžŅ‡ĐŊĐž Ņ‚Đ°Đē ĐļĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐģŅŽĐąŅ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐž и, Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐž, ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ `Request`. + +/// + +## ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ ĐŋĐž `Request` { #request-documentation } + +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Ой ĐžĐąŅŠĐĩĐēŅ‚Đĩ `Request` ĐŊа ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ ŅĐ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Starlette. + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `from starlette.requests import Request`. + +**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐĩĐŗĐž ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Đ´ĐģŅ ŅƒĐ´ĐžĐąŅŅ‚Đ˛Đ° Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа, ĐŊĐž ŅĐ°Đŧ ĐžĐąŅŠĐĩĐēŅ‚ ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ иС Starlette. + +/// diff --git a/docs/ru/docs/advanced/websockets.md b/docs/ru/docs/advanced/websockets.md index bc9dfcbff..b73fa1ddb 100644 --- a/docs/ru/docs/advanced/websockets.md +++ b/docs/ru/docs/advanced/websockets.md @@ -1,10 +1,10 @@ -# ВĐĩĐą-ŅĐžĐēĐĩ҂ҋ +# ВĐĩĐą-ŅĐžĐēĐĩ҂ҋ { #websockets } Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ вĐĩĐą-ŅĐžĐēĐĩ҂ҋ в **FastAPI**. -## ĐŖŅŅ‚Đ°ĐŊОвĐēа `WebSockets` +## ĐŖŅŅ‚Đ°ĐŊОвĐēа `websockets` { #install-websockets } -ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž [Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ҁҀĐĩда](../virtual-environments.md){.internal-link target=_blank} ŅĐžĐˇĐ´Đ°ĐŊа, аĐēŅ‚Đ¸Đ˛Đ¸Ņ€ŅƒĐšŅ‚Đĩ ĐĩŅ‘ и ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ `websockets`: +ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Đģи [Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐžĐĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊиĐĩ](../virtual-environments.md){.internal-link target=_blank}, аĐēŅ‚Đ¸Đ˛Đ¸Ņ€ĐžĐ˛Đ°Đģи ĐĩĐŗĐž и ŅƒŅŅ‚Đ°ĐŊОвиĐģи `websockets` (йийĐģĐ¸ĐžŅ‚ĐĩĐēа Python, ҃ĐŋŅ€ĐžŅ‰Đ°ŅŽŅ‰Đ°Ņ Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģĐžĐŧ "WebSocket"):
@@ -16,31 +16,31 @@ $ pip install websockets
-## КĐģиĐĩĐŊŅ‚ WebSockets +## КĐģиĐĩĐŊŅ‚ WebSockets { #websockets-client } -### Đ Đ°ĐąĐžŅ‡ĐĩĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ +### В ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ { #in-production } -ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, в Đ˛Đ°ŅˆĐĩĐš Ņ€ĐĩаĐģҌĐŊОК ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚ĐžĐ˛ĐžĐš ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ ĐĩŅŅ‚ŅŒ Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´, Ņ€ĐĩаĐģиСОваĐŊĐŊŅ‹Đš ĐŋŅ€Đ¸ ĐŋĐžĐŧĐžŅ‰Đ¸ ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв React, Vue.js иĐģи Angular. +В ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ ҃ Đ˛Đ°Ņ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐĩŅŅ‚ŅŒ Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа Đ˛Ņ€ĐžĐ´Đĩ React, Vue.js иĐģи Angular. -И ĐŊавĐĩŅ€ĐŊŅĐēа Đ´ĐģŅ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ ĐąĐĩĐēĐĩĐŊĐ´ĐžĐŧ ҇ĐĩŅ€ĐĩС вĐĩĐą-ŅĐžĐēĐĩ҂ҋ Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁҀĐĩĐ´ŅŅ‚Đ˛Đ° Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊда. +И Đ´ĐģŅ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ ĐąĐĩĐēĐĩĐŊĐ´ĐžĐŧ ĐŋĐž WebSocket Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐąŅƒĐ´ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Đ˛Đ°ŅˆĐĩĐŗĐž Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊда. -ĐĸаĐēĐļĐĩ ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐžĐĩ ĐŧОйиĐģҌĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, ĐēĐžĐŧĐŧ҃ĐŊĐ¸Ņ†Đ¸Ņ€ŅƒŅŽŅ‰ĐĩĐĩ ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ҁ вĐĩĐą-ŅĐžĐēĐĩŅ‚Đ°Đŧи ĐŊа ĐąĐĩĐēĐĩĐŊĐ´-ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ. +ĐĸаĐēĐļĐĩ ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐžĐĩ ĐŧОйиĐģҌĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅ‹Đŧ ĐēОдОĐŧ, вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ŅƒĐĩŅ‚ ҁ Đ˛Đ°ŅˆĐ¸Đŧ WebSocket-ĐąĐĩĐēĐĩĐŊĐ´ĐžĐŧ. -Либо Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ĐēаĐēОК-ĐģийО Đ´Ņ€ŅƒĐŗĐžĐš ҁĐŋĐžŅĐžĐą вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ вĐĩĐą-ŅĐžĐēĐĩŅ‚Đ°Đŧи. +Либо ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐģŅŽĐąĐžĐš Đ´Ņ€ŅƒĐŗĐžĐš ҁĐŋĐžŅĐžĐą вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ WebSocket-ŅĐŊĐ´ĐŋОиĐŊŅ‚ĐžĐŧ. --- -Но Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° ĐŧŅ‹ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅŅ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Ņ‹Đŧ HTML Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚ĐžĐŧ ҁ ĐŊĐĩйОĐģŅŒŅˆĐ¸Đŧи Đ˛ŅŅ‚Đ°Đ˛ĐēаĐŧи JavaScript ĐēОда. +Но Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° ĐŧŅ‹ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅŅ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Ņ‹Đŧ HTML‑доĐē҃ĐŧĐĩĐŊŅ‚ĐžĐŧ ҁ ĐŊĐĩйОĐģŅŒŅˆĐ¸Đŧ JavaScript, Đ˛ŅŅ‘ вĐŊŅƒŅ‚Ņ€Đ¸ ОдĐŊОК Đ´ĐģиĐŊĐŊОК ŅŅ‚Ņ€ĐžĐēи. -КоĐŊĐĩ҇ĐŊĐž ĐļĐĩ ŅŅ‚Đž ĐŊĐĩĐžĐŋŅ‚Đ¸ĐŧаĐģҌĐŊĐž, и ĐŊа ĐŋŅ€Đ°ĐēŅ‚Đ¸ĐēĐĩ Ņ‚Đ°Đē Đ´ĐĩĐģĐ°Ņ‚ŅŒ ĐŊĐĩ ŅŅ‚ĐžĐ¸Ņ‚. +КоĐŊĐĩ҇ĐŊĐž ĐļĐĩ, ŅŅ‚Đž ĐŊĐĩĐžĐŋŅ‚Đ¸ĐŧаĐģҌĐŊĐž, и Đ˛Ņ‹ ĐąŅ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи ŅŅ‚Đž в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ. -В Ņ€ĐĩаĐģҌĐŊҋ҅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ… ŅŅ‚ĐžĐ¸Ņ‚ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ ОдĐŊиĐŧ иС Đ˛Ņ‹ŅˆĐĩ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚Ņ‹Ņ… ҁĐŋĐžŅĐžĐąĐžĐ˛. +В ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ ҃ Đ˛Đ°Ņ ĐąŅ‹Đģ ĐąŅ‹ ОдиĐŊ иС Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐ˛ Đ˛Ņ‹ŅˆĐĩ. -ДĐģŅ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° ĐŊаĐŧ ĐŊ҃ĐļĐĩĐŊ ĐŊаийОĐģĐĩĐĩ ĐŋŅ€ĐžŅŅ‚ĐžĐš ҁĐŋĐžŅĐžĐą, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋОСвОĐģĐ¸Ņ‚ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК Ņ‡Đ°ŅŅ‚Đ¸ вĐĩĐą-ŅĐžĐēĐĩŅ‚ĐžĐ˛ и ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ€Đ°ĐąĐžŅ‡Đ¸Đš ĐēОд: +ДĐģŅ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° ĐŊаĐŧ ĐŊ҃ĐļĐĩĐŊ ĐŊаийОĐģĐĩĐĩ ĐŋŅ€ĐžŅŅ‚ĐžĐš ҁĐŋĐžŅĐžĐą, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋОСвОĐģĐ¸Ņ‚ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК Ņ‡Đ°ŅŅ‚Đ¸ вĐĩĐąâ€‘ŅĐžĐēĐĩŅ‚ĐžĐ˛ и ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ€Đ°ĐąĐžŅ‡Đ¸Đš ĐēОд: {* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} -## ХОСдаĐŊиĐĩ `websocket` +## ХОСдаĐŊиĐĩ `websocket` { #create-a-websocket } ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ `websocket` в ŅĐ˛ĐžĐĩĐŧ **FastAPI** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии: @@ -54,7 +54,7 @@ $ pip install websockets /// -## ОĐļидаĐŊиĐĩ и ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēа ŅĐžĐžĐąŅ‰ĐĩĐŊиК +## ОĐļидаĐŊиĐĩ и ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēа ŅĐžĐžĐąŅ‰ĐĩĐŊиК { #await-for-messages-and-send-messages } ЧĐĩŅ€ĐĩС ŅĐŊĐ´ĐŋОиĐŊŅ‚ вĐĩĐą-ŅĐžĐēĐĩŅ‚Đ° Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ и ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ ŅĐžĐžĐąŅ‰ĐĩĐŊĐ¸Ņ. @@ -62,7 +62,7 @@ $ pip install websockets Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ и ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Đ´Đ˛ĐžĐ¸Ņ‡ĐŊŅ‹Đĩ, Ņ‚ĐĩĐēŅŅ‚ĐžĐ˛Ņ‹Đĩ и JSON даĐŊĐŊŅ‹Đĩ. -## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа в Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đ¸ +## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа в Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đ¸ { #try-it } Đ•ŅĐģи Đ˛Đ°Ņˆ Ņ„Đ°ĐšĐģ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ `main.py`, Ņ‚Đž СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐēĐžĐŧаĐŊдОК: @@ -96,7 +96,7 @@ $ fastapi dev main.py И Đ˛ŅĐĩ ĐžĐŊи ĐąŅƒĐ´ŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ОдĐŊĐž и Ņ‚Đž ĐļĐĩ вĐĩĐą-ŅĐžĐēĐĩŅ‚ ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ. -## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `Depends` и ĐŊĐĩ Ņ‚ĐžĐģҌĐēĐž +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `Depends` и ĐŊĐĩ Ņ‚ĐžĐģҌĐēĐž { #using-depends-and-others } Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ иС `fastapi` и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в ŅĐŊĐ´ĐŋОиĐŊŅ‚Đĩ вĐĩĐąŅĐžĐēĐĩŅ‚Đ°: @@ -119,7 +119,7 @@ $ fastapi dev main.py /// -### ВĐĩĐą-ŅĐžĐēĐĩ҂ҋ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи: ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа в Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đ¸ +### ВĐĩĐą-ŅĐžĐēĐĩ҂ҋ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи: ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа в Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đ¸ { #try-the-websockets-with-dependencies } Đ•ŅĐģи Đ˛Đ°Ņˆ Ņ„Đ°ĐšĐģ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ `main.py`, Ņ‚Đž СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐēĐžĐŧаĐŊдОК: @@ -150,7 +150,7 @@ $ fastapi dev main.py -## ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ĐžŅ‚ĐēĐģŅŽŅ‡ĐĩĐŊиК и Ņ€Đ°ĐąĐžŅ‚Đ° ҁ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ĐēĐģиĐĩĐŊŅ‚Đ°Đŧи +## ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ĐžŅ‚ĐēĐģŅŽŅ‡ĐĩĐŊиК и Ņ€Đ°ĐąĐžŅ‚Đ° ҁ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ĐēĐģиĐĩĐŊŅ‚Đ°Đŧи { #handling-disconnections-and-multiple-clients } Đ•ŅĐģи вĐĩĐą-ŅĐžĐēĐĩŅ‚ ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ СаĐēŅ€Ņ‹Ņ‚Đž, Ņ‚Đž `await websocket.receive_text()` Đ˛Ņ‹ĐˇĐžĐ˛ĐĩŅ‚ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ `WebSocketDisconnect`, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŧĐžĐļĐŊĐž ĐŋОКĐŧĐ°Ņ‚ŅŒ и ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐēаĐē в ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ: @@ -168,7 +168,7 @@ $ fastapi dev main.py Client #1596980209979 left the chat ``` -/// tip | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ +/// tip | ĐŸĐžĐ´ŅĐēаСĐēа ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ˛Ņ‹ŅˆĐĩ - ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ĐŋŅ€ĐžŅŅ‚ĐžĐš ĐŧиĐŊиĐŧаĐģҌĐŊŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´ĐĩĐŧĐžĐŊŅŅ‚Ņ€Đ¸Ņ€ŅƒŅŽŅ‰Đ¸Đš ĐžĐąŅ€Đ°ĐąĐžŅ‚Đē҃ и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Ņƒ ŅĐžĐžĐąŅ‰ĐĩĐŊиК ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧ вĐĩĐą-ŅĐžĐēĐĩŅ‚ ŅĐžĐĩдиĐŊĐĩĐŊĐ¸ŅĐŧ. @@ -178,7 +178,7 @@ Client #1596980209979 left the chat /// -## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ +## ДоĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ { #more-info } ДĐģŅ йОĐģĐĩĐĩ ĐŗĐģŅƒĐąĐžĐēĐžĐŗĐž Đ¸ĐˇŅƒŅ‡ĐĩĐŊĐ¸Ņ Ņ‚ĐĩĐŧŅ‹ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚ĐĩҁҌ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš Starlette: diff --git a/docs/ru/docs/advanced/wsgi.md b/docs/ru/docs/advanced/wsgi.md new file mode 100644 index 000000000..1c5bf0a62 --- /dev/null +++ b/docs/ru/docs/advanced/wsgi.md @@ -0,0 +1,35 @@ +# ПодĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ WSGI — Flask, Django и Đ´Ņ€ŅƒĐŗĐ¸Đĩ { #including-wsgi-flask-django-others } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŧĐžĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ WSGI‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐēаĐē Đ˛Ņ‹ видĐĩĐģи в [ПодĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — Mounts](sub-applications.md){.internal-link target=_blank}, [За ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ](behind-a-proxy.md){.internal-link target=_blank}. + +ДĐģŅ ŅŅ‚ĐžĐŗĐž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `WSGIMiddleware` и ОйĐĩŅ€ĐŊŅƒŅ‚ŅŒ иĐŧ Đ˛Đ°ŅˆĐĩ WSGI‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Flask, Django и Ņ‚.Đ´. + +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `WSGIMiddleware` { #using-wsgimiddleware } + +ĐŅƒĐļĐŊĐž иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ `WSGIMiddleware`. + +Đ—Đ°Ņ‚ĐĩĐŧ ОйĐĩŅ€ĐŊĐ¸Ņ‚Đĩ WSGI‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Flask) в middleware (ĐŸŅ€ĐžĐŧĐĩĐļŅƒŅ‚ĐžŅ‡ĐŊŅ‹Đš ҁĐģОК). + +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ҁĐŧĐžĐŊŅ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ ĐĩĐŗĐž ĐŊа ĐŋŅƒŅ‚ŅŒ. + +{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *} + +## ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ { #check-it } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐēаĐļĐ´Ņ‹Đš HTTP‑заĐŋŅ€ĐžŅ ĐŋĐž ĐŋŅƒŅ‚Đ¸ `/v1/` ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ Flask. + +А Đ˛ŅŅ‘ ĐžŅŅ‚Đ°ĐģҌĐŊĐžĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒŅŅ **FastAPI**. + +Đ•ŅĐģи Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ŅŅ‚Đž и ĐŋĐĩŅ€ĐĩĐšĐ´Ņ‘Ņ‚Đĩ ĐŋĐž http://localhost:8000/v1/, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ HTTPâ€‘ĐžŅ‚Đ˛ĐĩŅ‚ ĐžŅ‚ Flask: + +```txt +Hello, World from Flask! +``` + +А ĐĩҁĐģи Đ˛Ņ‹ ĐŋĐĩŅ€ĐĩĐšĐ´Ņ‘Ņ‚Đĩ ĐŋĐž http://localhost:8000/v2, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ HTTPâ€‘ĐžŅ‚Đ˛ĐĩŅ‚ ĐžŅ‚ FastAPI: + +```JSON +{ + "message": "Hello World" +} +``` diff --git a/docs/ru/docs/alternatives.md b/docs/ru/docs/alternatives.md index 3c5147e79..6380bcc45 100644 --- a/docs/ru/docs/alternatives.md +++ b/docs/ru/docs/alternatives.md @@ -1,104 +1,94 @@ -# АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹, Đ¸ŅŅ‚ĐžŅ‡ĐŊиĐēи Đ˛Đ´ĐžŅ…ĐŊОвĐĩĐŊĐ¸Ņ и ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸Ņ +# АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹, Đ¸ŅŅ‚ĐžŅ‡ĐŊиĐēи Đ˛Đ´ĐžŅ…ĐŊОвĐĩĐŊĐ¸Ņ и ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸Ņ { #alternatives-inspiration-and-comparisons } -Đ§Ņ‚Đž Đ˛Đ´ĐžŅ…ĐŊОвиĐģĐž ĐŊа ŅĐžĐˇĐ´Đ°ĐŊиĐĩ **FastAPI**, ŅŅ€Đ°Đ˛ĐŊĐĩĐŊиĐĩ ĐĩĐŗĐž ҁ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Đ°Đŧи и ҇ĐĩĐŧ҃ ĐžĐŊ ĐŊĐ°ŅƒŅ‡Đ¸ĐģŅŅ ҃ ĐŊĐ¸Ņ…. +Đ§Ņ‚Đž Đ˛Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI**, ŅŅ€Đ°Đ˛ĐŊĐĩĐŊиĐĩ ҁ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Đ°Đŧи и ҇ĐĩĐŧ҃ ĐžĐŊ ҃ ĐŊĐ¸Ņ… ĐŊĐ°ŅƒŅ‡Đ¸ĐģŅŅ. -## ВвĐĩĐ´ĐĩĐŊиĐĩ +## ВвĐĩĐ´ĐĩĐŊиĐĩ { #intro } -**FastAPI** ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģ ĐąŅ‹, ĐĩҁĐģи Đą ĐŊĐĩ ĐąŅ‹ĐģĐž йОĐģĐĩĐĩ Ņ€Đ°ĐŊĐŊĐ¸Ņ… Ņ€Đ°ĐąĐžŅ‚ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐģŅŽĐ´ĐĩĐš. +**FastAPI** ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģ ĐąŅ‹ ĐąĐĩС ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… Ņ€Đ°ĐąĐžŅ‚ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐģŅŽĐ´ĐĩĐš. -ОĐŊи ŅĐžĐˇĐ´Đ°Đģи йОĐģŅŒŅˆĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ´ĐžŅ…ĐŊОвиĐģи ĐŧĐĩĐŊŅ ĐŊа ŅĐžĐˇĐ´Đ°ĐŊиĐĩ **FastAPI**. +Đ‘Ņ‹ĐģĐž ŅĐžĐˇĐ´Đ°ĐŊĐž ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ´ĐžŅ…ĐŊОвиĐģи ĐŊа ĐĩĐŗĐž ĐŋĐžŅĐ˛ĐģĐĩĐŊиĐĩ. -Đ¯ Đ˛ŅŅŅ‡ĐĩҁĐēи иСйĐĩĐŗĐ°Đģ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŊĐžĐ˛ĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа в Ņ‚Đĩ҇ĐĩĐŊиĐĩ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐģĐĩŅ‚. -ĐĄĐŊĐ°Ņ‡Đ°Đģа Ņ ĐŋŅ‹Ņ‚Đ°ĐģŅŅ ŅĐžĐąŅ€Đ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐŊ҃ĐļĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊŅ‹ĐŊĐĩ ĐĩŅŅ‚ŅŒ в **FastAPI**, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐŋĐģĐ°ĐŗĐ¸ĐŊОв и иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. +Đ¯ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐģĐĩŅ‚ иСйĐĩĐŗĐ°Đģ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŊĐžĐ˛ĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа. ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐŋŅ‹Ņ‚Đ°ĐģŅŅ СаĐēŅ€Ņ‹Ņ‚ŅŒ Đ˛ŅĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐĩĐšŅ‡Đ°Ņ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ **FastAPI**, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° Ņ€Đ°ĐˇĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐŋĐģĐ°ĐŗĐ¸ĐŊОв и иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. -Но в ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ĐŊĐĩ ĐžŅŅ‚Đ°ĐģĐžŅŅŒ Đ´Ņ€ŅƒĐŗĐžĐŗĐž Đ˛Ņ‹ĐąĐžŅ€Đ°, ĐēŅ€ĐžĐŧĐĩ ĐēаĐē ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐģĐž ĐąŅ‹ Đ˛ŅĐĩ ŅŅ‚Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ŅŅ€Đ°ĐˇŅƒ. -Đ’ĐˇŅŅ‚ŅŒ ŅĐ°ĐŧŅ‹Đĩ ĐģŅƒŅ‡ŅˆĐ¸Đĩ идĐĩи иС ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŊĐžĐ˛Ņ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Python (ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŊĐĩ ĐąŅ‹ĐģĐž Đ´Đž вĐĩŅ€ŅĐ¸Đ¸ 3.6, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв), ĐžĐąŅŠĐĩдиĐŊĐ¸Ņ‚ŅŒ Đ¸Ņ…. +Но в ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ĐŊĐĩ ĐžŅŅ‚Đ°ĐģĐžŅŅŒ Đ´Ņ€ŅƒĐŗĐžĐŗĐž Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚Đ°, ĐēŅ€ĐžĐŧĐĩ ĐēаĐē ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ Đ˛ŅĐĩ ŅŅ‚Đ¸ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, Đ˛ĐˇŅĐ˛ ĐģŅƒŅ‡ŅˆĐ¸Đĩ идĐĩи иС ĐŋŅ€ĐĩĐļĐŊĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đ˛ Đ¸Ņ… ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž ŅƒĐ´Đ°Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ŅĐˇŅ‹Đēа, ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŋŅ€ĐĩĐļĐ´Đĩ ĐŊĐĩ ĐąŅ‹ĐģĐž (аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв в Python 3.6+). -## ĐŸŅ€ĐĩĐ´ŅˆĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ +## ĐŸŅ€ĐĩĐ´ŅˆĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ { #previous-tools } -### Django +### Django { #django } -Đ­Ņ‚Đž ŅĐ°ĐŧŅ‹Đš ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊŅ‹Đš Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, и ĐžĐŊ ĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ дОвĐĩŅ€Đ¸ĐĩĐŧ. -ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐ˛ Ņ‚Đ¸Đŋа Instagram. +Đ­Ņ‚Đž ŅĐ°ĐŧŅ‹Đš ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊŅ‹Đš Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, ĐĩĐŧ҃ ŅˆĐ¸Ņ€ĐžĐēĐž дОвĐĩŅ€ŅŅŽŅ‚. ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ´ĐģŅ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐ¸Ņ ŅĐ¸ŅŅ‚ĐĩĐŧ Đ˛Ņ€ĐžĐ´Đĩ Instagram. -Django дОвОĐģҌĐŊĐž Ņ‚ĐĩҁĐŊĐž ŅĐ˛ŅĐˇĐ°ĐŊ ҁ Ņ€ĐĩĐģŅŅ†Đ¸ĐžĐŊĐŊŅ‹Đŧи йаСаĐŧи даĐŊĐŊҋ҅ (Ņ‚Đ°ĐēиĐŧи ĐēаĐē MySQL иĐģи PostgreSQL), ĐŋĐžŅ‚ĐžĐŧ҃ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ NoSQL ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Couchbase, MongoDB, Cassandra и Ņ‚.Đŋ.) в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊОвĐŊĐžĐŗĐž Ņ…Ņ€Đ°ĐŊиĐģĐ¸Ņ‰Đ° даĐŊĐŊҋ҅ - ĐŊĐĩĐŋŅ€ĐžŅŅ‚Đž. +ОĐŊ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž Ņ‚ĐĩҁĐŊĐž ŅĐ˛ŅĐˇĐ°ĐŊ ҁ Ņ€ĐĩĐģŅŅ†Đ¸ĐžĐŊĐŊŅ‹Đŧи йаСаĐŧи даĐŊĐŊҋ҅ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, MySQL иĐģи PostgreSQL), ĐŋĐžŅŅ‚ĐžĐŧ҃ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ NoSQL-ĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Couchbase, MongoDB, Cassandra и Ņ‚. Đŋ.) в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊОвĐŊĐžĐŗĐž Ņ…Ņ€Đ°ĐŊиĐģĐ¸Ņ‰Đ° ĐŊĐĩ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Đž. -ОĐŊ ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ HTML-ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ† ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ, а ĐŊĐĩ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đŧи вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°Đŧи (React, Vue.js, Angular и Ņ‚.Đŋ.) иĐģи Đ´Ņ€ŅƒĐŗĐ¸Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, IoT) вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đŧи ҁ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ. +ОĐŊ ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ HTML ĐŊа ĐąŅĐēĐĩĐŊĐ´Đĩ, а ĐŊĐĩ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đŧ Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´ĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, React, Vue.js и Angular) иĐģи Đ´Ņ€ŅƒĐŗĐ¸Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅƒŅŅ‚Ņ€ĐžĐšŅŅ‚Đ˛Đ°Đŧи IoT), ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁ ĐŊиĐŧ ĐžĐąŅ‰Đ°ŅŽŅ‚ŅŅ. -### Django REST Framework +### Django REST Framework { #django-rest-framework } -Đ¤Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē Django REST ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ, ĐēаĐē ĐŗĐ¸ĐąĐēиК иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đš Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ вĐĩĐą-API ĐŊа ĐžŅĐŊОвĐĩ Django. +Django REST Framework ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ ĐēаĐē ĐŗĐ¸ĐąĐēиК ĐŊĐ°ĐąĐžŅ€ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐ¸Ņ вĐĩĐą-API ĐŋОвĐĩҀ҅ Django, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚ŅŒ ĐĩĐŗĐž вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ в Ņ‡Đ°ŅŅ‚Đ¸ API. -DRF Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģŅŅ ĐŧĐŊĐžĐŗĐ¸Đŧи ĐēĐžĐŧĐŋаĐŊĐ¸ŅĐŧи, вĐēĐģŅŽŅ‡Đ°Ņ Mozilla, Red Hat и Eventbrite. +ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ĐŧĐŊĐžĐŗĐ¸Đŧи ĐēĐžĐŧĐŋаĐŊĐ¸ŅĐŧи, вĐēĐģŅŽŅ‡Đ°Ņ Mozilla, Red Hat и Eventbrite. -Đ­Ņ‚Đž ĐąŅ‹Đģ ОдиĐŊ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐžĐ˛ **Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ API** и ŅŅ‚Đž ĐąŅ‹Đģа ОдĐŊа иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… идĐĩĐš, Đ˛Đ´ĐžŅ…ĐŊĐžĐ˛Đ¸Đ˛ŅˆĐ¸Ņ… ĐŊа ŅĐžĐˇĐ´Đ°ĐŊиĐĩ **FastAPI**. +Đ­Ņ‚Đž ĐąŅ‹Đģ ОдиĐŊ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐžĐ˛ **Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API**, и иĐŧĐĩĐŊĐŊĐž ŅŅ‚Đ° идĐĩŅ ОдĐŊОК иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… Đ˛Đ´ĐžŅ…ĐŊОвиĐģа ĐŊа ÂĢĐŋĐžĐ¸ŅĐēÂģ **FastAPI**. /// note | ЗаĐŧĐĩŅ‚Đēа -Django REST Framework ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Tom Christie. -ОĐŊ ĐļĐĩ ŅĐžĐˇĐ´Đ°Đģ Starlette и Uvicorn, ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžŅĐŊОваĐŊ **FastAPI**. +Django REST Framework ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ ĐĸĐžĐŧĐžĐŧ ĐšŅ€Đ¸ŅŅ‚Đ¸. ОĐŊ ĐļĐĩ ŅĐžĐˇĐ´Đ°Đģ Starlette и Uvicorn, ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžŅĐŊОваĐŊ **FastAPI**. /// -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ДоĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ ŅĐžĐˇĐ´Đ°ĐŊиĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API ҁ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐŧ вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐŧ. +НаĐģĐ¸Ņ‡Đ¸Đĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ° ҁ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš API. /// -### Flask +### Flask { #flask } -Flask - ŅŅ‚Đž "ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē", в ĐŊŅ‘Đŧ ĐŊĐĩŅ‚ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ ҁ йаСаĐŧи даĐŊĐŊҋ҅ и ĐŧĐŊĐžĐŗĐ¸Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ… вĐĩ҉ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€ĐĩĐ´ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊŅ‹ в Django. +Flask — ŅŅ‚Đž ÂĢĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēÂģ, ĐžĐŊ ĐŊĐĩ вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ ҁ йаСаĐŧи даĐŊĐŊҋ҅ и ĐŧĐŊĐžĐŗĐ¸Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ вĐĩŅ‰Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ в Django Đ¸Đ´ŅƒŅ‚ ÂĢиС ĐēĐžŅ€ĐžĐąĐēиÂģ. -Đ•ĐŗĐž ĐŋŅ€ĐžŅŅ‚ĐžŅ‚Đ° и ĐŗĐ¸ĐąĐēĐžŅŅ‚ŅŒ Đ´Đ°ŅŽŅ‚ ŅˆĐ¸Ņ€ĐžĐēиĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, Ņ‚Đ°ĐēиĐĩ ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йаС даĐŊĐŊҋ҅ NoSQL в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊОвĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ Ņ…Ņ€Đ°ĐŊĐĩĐŊĐ¸Ņ даĐŊĐŊҋ҅. +Đ­Ņ‚Đ° ĐŋŅ€ĐžŅŅ‚ĐžŅ‚Đ° и ĐŗĐ¸ĐąĐēĐžŅŅ‚ŅŒ ĐŋОСвОĐģŅĐĩŅ‚, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ NoSQL-ĐąĐ°ĐˇŅ‹ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊОвĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ Ņ…Ņ€Đ°ĐŊĐĩĐŊĐ¸Ņ даĐŊĐŊҋ҅. -ОĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚, ĐĩĐŗĐž Đ¸ĐˇŅƒŅ‡ĐĩĐŊиĐĩ иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐž ĐŋĐžĐŊŅŅ‚ĐŊĐž, Ņ…ĐžŅ‚Ņ в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŧĐĩŅŅ‚Đ°Ņ… Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ дОвОĐģҌĐŊĐž Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēĐ°Ņ. +ОĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚, ĐĩĐŗĐž ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž ĐģĐĩĐŗĐēĐž иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐž ĐžŅĐ˛ĐžĐ¸Ņ‚ŅŒ, Ņ…ĐžŅ‚Ņ ĐŧĐĩŅŅ‚Đ°Đŧи Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ дОвОĐģҌĐŊĐž Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēĐ°Ņ. -Flask Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ и Đ´ĐģŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК, ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ ĐŊĐĩ ĐŊ҃ĐļĐŊа йаСа даĐŊĐŊҋ҅, ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐŋŅ€Đ°Đ˛ Đ´ĐžŅŅ‚ŅƒĐŋа Đ´ĐģŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš и ĐŋŅ€ĐžŅ‡Đ¸Đĩ иС ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊĐž Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊҋ҅ в Django. -ĐĨĐžŅ‚Ņ ĐŧĐŊĐžĐŗĐ¸Đĩ иС ŅŅ‚Đ¸Ņ… Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ дОйавĐģĐĩĐŊŅ‹ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŋĐģĐ°ĐŗĐ¸ĐŊОв. +Đ•ĐŗĐž Ņ‚Đ°ĐēĐļĐĩ Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ Đ´ĐģŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК, ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ ĐŊĐĩ ĐŊ҃ĐļĐŊа йаСа даĐŊĐŊҋ҅, ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧи иĐģи ĐŧĐŊĐžĐŗĐ¸Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊĐž Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đĩ в Django. ĐĨĐžŅ‚Ņ ĐŧĐŊĐžĐŗĐ¸Đĩ иС ŅŅ‚Đ¸Ņ… вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš ĐŧĐžĐļĐŊĐž Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŋĐģĐ°ĐŗĐ¸ĐŊаĐŧи. -ĐĸаĐēĐžĐĩ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩĐŊиĐĩ ĐŊа Ņ‡Đ°ŅŅ‚Đ¸ и Ņ‚Đž, Ņ‡Ņ‚Đž ŅŅ‚Đž "ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē", ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐŊĐž Ņ€Đ°ŅŅˆĐ¸Ņ€Đ¸Ņ‚ŅŒ, дОйавĐģŅŅ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, ĐąŅ‹ĐģĐž ĐēĐģŅŽŅ‡ĐĩвОК ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚ŅŒŅŽ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Ņ Ņ…ĐžŅ‚ĐĩĐģ ŅĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ŅŒ. +ĐĸаĐēĐžĐĩ Ņ€Đ°ĐˇĐąĐ¸ĐĩĐŊиĐĩ ĐŊа Ņ‡Đ°ŅŅ‚Đ¸ и Ņ‚Đž, Ņ‡Ņ‚Đž ŅŅ‚Đž ÂĢĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēÂģ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐŊĐž Ņ€Đ°ŅŅˆĐ¸Ņ€ŅŅ‚ŅŒ Ņ€ĐžĐ˛ĐŊĐž ĐŋОд ĐŊ҃ĐļĐ´Ņ‹, — ĐēĐģŅŽŅ‡ĐĩĐ˛Đ°Ņ ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚ŅŒ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Ņ…ĐžŅ‚ĐĩĐģĐžŅŅŒ ŅĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ŅŒ. -ĐŸŅ€ĐžŅŅ‚ĐžŅ‚Đ° Flask, ĐŋĐžĐēаСаĐģĐ°ŅŅŒ ĐŧĐŊĐĩ ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰ĐĩĐš Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API. -Но Đĩ҉ґ ĐŊ҃ĐļĐŊĐž ĐąŅ‹ĐģĐž ĐŊĐ°ĐšŅ‚Đ¸ "Django REST Framework" Đ´ĐģŅ Flask. +ĐĄ ŅƒŅ‡Ņ‘Ņ‚ĐžĐŧ ĐŋŅ€ĐžŅŅ‚ĐžŅ‚Ņ‹ Flask ĐžĐŊ ĐēаСаĐģŅŅ Ņ…ĐžŅ€ĐžŅˆĐ¸Đŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐŧ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API. ĐĄĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ĐąŅ‹ĐģĐž ĐŊĐ°ĐšŅ‚Đ¸ ÂĢDjango REST FrameworkÂģ Đ´ĐģŅ Flask. -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -Đ­Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē. К ĐŊĐĩĐŧ҃ ĐģĐĩĐŗĐēĐž ĐąŅƒĐ´ĐĩŅ‚ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ и Ņ‡Đ°ŅŅ‚Đ¸. +Đ‘Ņ‹Ņ‚ŅŒ ĐŧиĐēŅ€Đž-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ. ОбĐģĐĩĐŗŅ‡Đ¸Ņ‚ŅŒ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛. -ДоĐģĐļĐŊа ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Đ°Ņ и ĐģŅ‘ĐŗĐēĐ°Ņ в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ŅĐ¸ŅŅ‚ĐĩĐŧа ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ СаĐŋŅ€ĐžŅĐžĐ˛. +ИĐŧĐĩŅ‚ŅŒ ĐŋŅ€ĐžŅŅ‚ŅƒŅŽ и ŅƒĐ´ĐžĐąĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ†Đ¸Đ¸. /// -### Requests +### Requests { #requests } -На ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ **FastAPI** ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐžĐš **Requests**. -Đ˜Ņ… ОйĐģĐ°ŅŅ‚ŅŒ ĐŋŅ€Đ¸ĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ĐžŅ‡ĐĩĐŊҌ Ņ€Đ°ĐˇĐŊĐ°Ņ. +**FastAPI** ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ ĐŊĐĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Đ° **Requests**. Đ˜Ņ… ОйĐģĐ°ŅŅ‚Đ¸ ĐŋŅ€Đ¸ĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ĐžŅ‡ĐĩĐŊҌ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊŅ‹. -В ĐŋŅ€Đ¸ĐŊŅ†Đ¸ĐŋĐĩ, ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Requests *вĐŊŅƒŅ‚Ņ€Đ¸* ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI. +ĐžĐąŅ‹Ņ‡ĐŊĐž Requests Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ даĐļĐĩ вĐŊŅƒŅ‚Ņ€Đ¸ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI. -Но Đ˛ŅŅ‘ ĐļĐĩ Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ в FastAPI ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ идĐĩи иС Requests. +И Đ˛ŅŅ‘ ĐļĐĩ **FastAPI** вО ĐŧĐŊĐžĐŗĐžĐŧ Đ˛Đ´ĐžŅ…ĐŊОвĐģŅĐģŅŅ Requests. -**Requests** - ŅŅ‚Đž йийĐģĐ¸ĐžŅ‚ĐĩĐēа Đ´ĐģŅ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ API в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐēĐģиĐĩĐŊŅ‚Đ°, -в Ņ‚Đž Đ˛Ņ€ĐĩĐŧŅ ĐēаĐē **FastAPI** - ŅŅ‚Đž йийĐģĐ¸ĐžŅ‚ĐĩĐēа Đ´ĐģŅ *ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ* API (Ņ‚Đž ĐĩŅŅ‚ŅŒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°). +**Requests** — ŅŅ‚Đž йийĐģĐ¸ĐžŅ‚ĐĩĐēа Đ´ĐģŅ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ API (ĐēаĐē ĐēĐģиĐĩĐŊŅ‚), а **FastAPI** — йийĐģĐ¸ĐžŅ‚ĐĩĐēа Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API (ĐēаĐē ҁĐĩŅ€Đ˛ĐĩŅ€). -ОĐŊи, Ņ‚Đ°Đē иĐģи иĐŊĐ°Ņ‡Đĩ, диаĐŧĐĩŅ‚Ņ€Đ°ĐģҌĐŊĐž ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊŅ‹ и Đ´ĐžĐŋĐžĐģĐŊŅŅŽŅ‚ Đ´Ņ€ŅƒĐŗ Đ´Ņ€ŅƒĐŗĐ°. +ОĐŊи, в ĐēаĐēĐžĐŧ-Ņ‚Đž ҁĐŧҋҁĐģĐĩ, ĐŊĐ°Ņ…ĐžĐ´ŅŅ‚ŅŅ ĐŊа ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊҋ҅ ĐēĐžĐŊŅ†Đ°Ņ… и Đ´ĐžĐŋĐžĐģĐŊŅŅŽŅ‚ Đ´Ņ€ŅƒĐŗ Đ´Ņ€ŅƒĐŗĐ°. -Requests иĐŧĐĩĐĩŅ‚ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚ĐžĐš и ĐŋĐžĐŊŅŅ‚ĐŊŅ‹Đš диСаКĐŊ, ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚ в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии и иĐŧĐĩĐĩŅ‚ Ņ€Đ°ĐˇŅƒĐŧĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. -И в Ņ‚Đž ĐļĐĩ Đ˛Ņ€ĐĩĐŧŅ ĐžĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŧĐžŅ‰ĐŊŅ‹Đš и ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩĐŧŅ‹Đš. +Requests иĐŧĐĩĐĩŅ‚ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚ĐžĐš и ĐŋĐžĐŊŅŅ‚ĐŊŅ‹Đš диСаКĐŊ, иĐŧ ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ, ĐĩŅŅ‚ŅŒ Ņ€Đ°ĐˇŅƒĐŧĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. И ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐžĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŧĐžŅ‰ĐŊŅ‹Đš и ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩĐŧŅ‹Đš. -Đ’ĐžŅ‚ ĐŋĐžŅ‡ĐĩĐŧ҃ ĐŊа ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ ŅĐ°ĐšŅ‚Đĩ ĐŊаĐŋĐ¸ŅĐ°ĐŊĐž: +ИĐŧĐĩĐŊĐŊĐž ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŊа ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ ŅĐ°ĐšŅ‚Đĩ ҁĐēаСаĐŊĐž: -> Requests - ОдиĐŊ иС ŅĐ°Đŧҋ҅ ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩĐŧҋ҅ ĐŋаĐēĐĩŅ‚ĐžĐ˛ Python Đ˛ŅĐĩŅ… Đ˛Ņ€ĐĩĐŧĐĩĐŊ +> Requests — ОдиĐŊ иС ŅĐ°Đŧҋ҅ ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩĐŧҋ҅ Python-ĐŋаĐēĐĩŅ‚ĐžĐ˛ Đ˛ŅĐĩŅ… Đ˛Ņ€ĐĩĐŧŅ‘ĐŊ - -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Đž. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ СаĐŋŅ€ĐžŅ `GET`, Đ’Ņ‹ ĐąŅ‹ ĐŊаĐŋĐ¸ŅĐ°Đģи: +ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ иĐŧ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Đž. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ `GET`, Đ˛Ņ‹ ĐąŅ‹ ĐŊаĐŋĐ¸ŅĐ°Đģи: ```Python response = requests.get("http://example.com/some/url") ``` -ĐŸŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊĐ°Ņ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸* в FastAPI ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ: +ĐĄĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰Đ°Ņ в FastAPI API-ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸ ĐŧĐžĐŗĐģа ĐąŅ‹ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: ```Python hl_lines="1" @app.get("/some/url") @@ -106,428 +96,390 @@ def read_url(): return {"message": "Hello World"} ``` -ГĐģŅĐ´Đ¸Ņ‚Đĩ, ĐēаĐē ĐŋĐžŅ…ĐžĐļĐĩ `requests.get(...)` и `@app.get(...)`. +ĐŸĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ, ĐŊĐ°ŅĐēĐžĐģҌĐēĐž ĐŋĐžŅ…ĐžĐļи `requests.get(...)` и `@app.get(...)`. -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -* ДоĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚ĐžĐš и ĐŋĐžĐŊŅŅ‚ĐŊŅ‹Đš API. -* ĐŅƒĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊаСваĐŊĐ¸Ņ HTTP-ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ (ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš) Đ´ĐģŅ ҃ĐŋŅ€ĐžŅ‰ĐĩĐŊĐ¸Ņ ĐŋĐžĐŊиĐŧаĐŊĐ¸Ņ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´ŅŅ‰ĐĩĐŗĐž. -* ДоĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ Ņ€Đ°ĐˇŅƒĐŧĐŊŅ‹Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ и ŅˆĐ¸Ņ€ĐžĐēиĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Đ¸Ņ… ĐēĐ°ŅŅ‚ĐžĐŧĐ¸ĐˇĐ°Ņ†Đ¸Đ¸. +* ИĐŧĐĩŅ‚ŅŒ ĐŋŅ€ĐžŅŅ‚ĐžĐš и ĐŋĐžĐŊŅŅ‚ĐŊŅ‹Đš API. +* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊаСваĐŊĐ¸Ņ HTTP-ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ (ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš) ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐŋŅ€ĐžŅŅ‚Ņ‹Đŧ и иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ. +* ИĐŧĐĩŅ‚ŅŒ Ņ€Đ°ĐˇŅƒĐŧĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐŊĐž и ĐŧĐžŅ‰ĐŊŅ‹Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи. /// -### Swagger / OpenAPI +### Swagger / OpenAPI { #swagger-openapi } -ГĐģавĐŊОК Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Ņ Ņ…ĐžŅ‚ĐĩĐģ ҃ĐŊĐ°ŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ‚ Django REST Framework, ĐąŅ‹Đģа Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API. +ГĐģавĐŊОК вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒŅŽ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Ņ…ĐžŅ‚ĐĩĐģĐžŅŅŒ Đ˛ĐˇŅŅ‚ŅŒ иС Django REST Framework, ĐąŅ‹Đģа Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API. -Но ĐŋĐžŅ‚ĐžĐŧ Ņ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ, Ņ‡Ņ‚Đž ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ API, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰Đ¸Đš JSON (иĐģи YAML, Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ JSON) ĐŋОд ĐŊаСваĐŊиĐĩĐŧ Swagger. +Đ—Đ°Ņ‚ĐĩĐŧ Ņ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ, Ņ‡Ņ‚Đž ĐĩŅŅ‚ŅŒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ API ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ JSON (иĐģи YAML — Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐ¸Ņ JSON), ĐŋОд ĐŊаСваĐŊиĐĩĐŧ Swagger. -И Đē ĐŊĐĩĐŧ҃ ҃ĐļĐĩ ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Swagger Đ´ĐģŅ API ĐŋОСвОĐģиĐģа ĐąŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ. +И ҃ĐļĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģ вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ Đ´ĐģŅ Swagger API. ĐŸĐžŅŅ‚ĐžĐŧ҃ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Swagger Đ´ĐģŅ API ĐŋОСвОĐģиĐģа ĐąŅ‹ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ. В ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ Swagger ĐąŅ‹Đģ ĐŋĐĩŅ€ĐĩдаĐŊ Linux Foundation и ĐŋĐĩŅ€ĐĩиĐŧĐĩĐŊОваĐŊ в OpenAPI. -Đ’ĐžŅ‚ ĐŋĐžŅ‡ĐĩĐŧ҃, ĐēĐžĐŗĐ´Đ° ĐŗĐžĐ˛ĐžŅ€ŅŅ‚ Đž вĐĩŅ€ŅĐ¸Đ¸ 2.0, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŗĐžĐ˛ĐžŅ€ŅŅ‚ "Swagger", а Đ´ĐģŅ вĐĩŅ€ŅĐ¸Đ¸ 3+ "OpenAPI". +Đ’ĐžŅ‚ ĐŋĐžŅ‡ĐĩĐŧ҃, ĐŗĐžĐ˛ĐžŅ€Ņ Đž вĐĩŅ€ŅĐ¸Đ¸ 2.0, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŗĐžĐ˛ĐžŅ€ŅŅ‚ ÂĢSwaggerÂģ, а Đž вĐĩŅ€ŅĐ¸Đ¸ 3+ — ÂĢOpenAPIÂģ. -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ‚ĐēҀҋ҂ҋĐĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Ņ‹ Đ´ĐģŅ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đš API вĐŧĐĩŅŅ‚Đž ŅĐ°ĐŧОдĐĩĐģҌĐŊҋ҅ ҁ҅ĐĩĐŧ. +Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ‚ĐēŅ€Ņ‹Ņ‚Ņ‹Đš ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ Đ´ĐģŅ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đš API вĐŧĐĩŅŅ‚Đž ŅĐ°ĐŧОдĐĩĐģҌĐŊОК ҁ҅ĐĩĐŧŅ‹. -ХОвĐŧĐĩŅŅ‚Đ¸ĐŧĐžŅŅ‚ŅŒ ҁ ĐžŅĐŊОваĐŊĐŊŅ‹Đŧи ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ°Ņ… ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐŧи иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°Đŧи: +И иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅĐŊОваĐŊĐŊŅ‹Đĩ ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ°Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°: * Swagger UI * ReDoc -ОĐŊи ĐąŅ‹Đģи Đ˛Ņ‹ĐąŅ€Đ°ĐŊŅ‹ Са ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊĐžŅŅ‚ŅŒ и ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊĐžŅŅ‚ŅŒ. -Но ŅĐ´ĐĩĐģав ĐąĐĩĐŗĐģŅ‹Đš ĐŋĐžĐ¸ŅĐē, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊĐ°ĐšŅ‚Đ¸ Đ´ĐĩŅŅŅ‚Đēи аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊҋ҅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐ˛ Đ´ĐģŅ OpenAPI, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁ **FastAPI**. +Đ­Ņ‚Đ¸ два иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ° Đ˛Ņ‹ĐąŅ€Đ°ĐŊŅ‹ Са ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊĐžŅŅ‚ŅŒ и ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊĐžŅŅ‚ŅŒ, ĐŊĐž даĐļĐĩ ĐŋŅ€Đ¸ ĐąĐĩĐŗĐģĐžĐŧ ĐŋĐžĐ¸ŅĐēĐĩ ĐŧĐžĐļĐŊĐž ĐŊĐ°ĐšŅ‚Đ¸ Đ´ĐĩŅŅŅ‚Đēи аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊҋ҅ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐ˛ Đ´ĐģŅ OpenAPI (ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁ **FastAPI**). /// -### REST ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēи Đ´ĐģŅ Flask +### REST-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēи Đ´ĐģŅ Flask { #flask-rest-frameworks } -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž REST ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв Đ´ĐģŅ Flask, ĐŊĐž ĐŋĐžŅ‚Ņ€Đ°Ņ‚Đ¸Đ˛ Đ˛Ņ€ĐĩĐŧŅ и ŅƒŅĐ¸ĐģĐ¸Ņ ĐŊа Đ¸Ņ… Đ¸ĐˇŅƒŅ‡ĐĩĐŊиĐĩ, Ņ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ, Ņ‡Ņ‚Đž ĐŧĐŊĐžĐŗĐ¸Đĩ иС ĐŊĐ¸Ņ… ĐŊĐĩ ОйĐŊОвĐģŅŅŽŅ‚ŅŅ иĐģи ĐˇĐ°ĐąŅ€ĐžŅˆĐĩĐŊŅ‹ и иĐŧĐĩŅŽŅ‚ ĐŊĐĩŅ€ĐĩŅˆŅ‘ĐŊĐŊŅ‹Đĩ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ иС-Са ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžĐŊи ĐŊĐĩĐŋŅ€Đ¸ĐŗĐžĐ´ĐŊŅ‹ Đē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸ŅŽ. +ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž REST-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв Đ´ĐģŅ Flask, ĐŊĐž, вĐģĐžĐļив Đ˛Ņ€ĐĩĐŧŅ и ŅƒŅĐ¸ĐģĐ¸Ņ в Đ¸ŅŅĐģĐĩдОваĐŊиĐĩ, Ņ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ, Ņ‡Ņ‚Đž ĐŧĐŊĐžĐŗĐ¸Đĩ иС ĐŊĐ¸Ņ… ĐŋŅ€ĐĩĐēŅ€Đ°Ņ‰ĐĩĐŊŅ‹ иĐģи ĐˇĐ°ĐąŅ€ĐžŅˆĐĩĐŊŅ‹, ҁ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ĐŊĐĩŅ€ĐĩŅˆŅ‘ĐŊĐŊŅ‹Đŧи Issue (Ņ‚Đ¸ĐēĐĩŅ‚\ĐžĐąŅ€Đ°Ņ‰ĐĩĐŊиĐĩ), иС-Са ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžĐŊи ĐŊĐĩĐŋŅ€Đ¸ĐŗĐžĐ´ĐŊŅ‹. -### Marshmallow +### Marshmallow { #marshmallow } -ОдĐŊОК иС ĐžŅĐŊОвĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧ API, ŅĐ˛ĐģŅĐĩŅ‚ŅŅ "ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ" даĐŊĐŊҋ҅, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊиĐĩ даĐŊĐŊҋ҅ иС ĐēОда (Python) вО Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐž ĐŋĐž ҁĐĩŅ‚Đ¸. -НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐ˛Ņ€Đ°Ņ‰ĐĩĐŊиĐĩ ĐžĐąŅŠĐĩĐēŅ‚Đ° ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰ĐĩĐŗĐž даĐŊĐŊŅ‹Đĩ иС ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ в ĐžĐąŅŠĐĩĐēŅ‚ JSON, ĐēĐžĐŊвĐĩŅ€Ņ‚Đ°Ņ†Đ¸Ņ ĐžĐąŅŠĐĩĐēŅ‚Đ° `datetime` в ŅŅ‚Ņ€ĐžĐē҃ и Ņ‚.Đŋ. +ОдĐŊа иС ĐžŅĐŊОвĐŊҋ҅ вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš, ĐŊ҃ĐļĐŊҋ҅ ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧ API, — ÂĢҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅÂģ даĐŊĐŊҋ҅, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊиĐĩ даĐŊĐŊҋ҅ иС ĐēОда (Python) вО Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŋĐž ҁĐĩŅ‚Đ¸. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐžĐąŅŠĐĩĐēŅ‚Đ° ҁ даĐŊĐŊŅ‹Đŧи иС ĐąĐ°ĐˇŅ‹ в JSON-ĐžĐąŅŠĐĩĐēŅ‚. ĐŸŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐžĐąŅŠĐĩĐēŅ‚ĐžĐ˛ `datetime` в ŅŅ‚Ņ€ĐžĐēи и Ņ‚. Đŋ. -Đ•Ņ‰Đĩ ОдĐŊа ваĐļĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐ°Ņ API — ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа даĐŊĐŊҋ҅, ĐŋОСвОĐģŅŅŽŅ‰Đ°Ņ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž даĐŊĐŊŅ‹Đĩ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹ и ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‚ СадаĐŊĐŊŅ‹Đŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°Đŧ. -КаĐē ĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŧĐžĐļĐŊĐž ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ĐžĐļĐ¸Đ´Đ°ŅŽŅ‚ŅŅ даĐŊĐŊŅ‹Đĩ Ņ‚Đ¸Đŋа `int`, а ĐŊĐĩ ĐēаĐēĐ°Ņ-Ņ‚Đž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐģҌĐŊĐ°Ņ ŅŅ‚Ņ€ĐžĐēа. -Đ­Ņ‚Đž ĐžŅĐžĐąĐĩĐŊĐŊĐž ĐŋĐžĐģĐĩСĐŊĐž Đ´ĐģŅ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… даĐŊĐŊҋ҅. +Đ•Ņ‰Ņ‘ ОдĐŊа ваĐļĐŊĐ°Ņ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ, Đ˛ĐžŅŅ‚Ņ€ĐĩйОваĐŊĐŊĐ°Ņ API, — ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅: ŅƒĐąĐĩĐļĐ´Đ°Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž даĐŊĐŊŅ‹Đĩ ваĐģидĐŊŅ‹ ҁ ŅƒŅ‡Ņ‘Ņ‚ĐžĐŧ СадаĐŊĐŊҋ҅ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚Đž ĐēаĐēĐžĐĩ-Ņ‚Đž ĐŋĐžĐģĐĩ — `int`, а ĐŊĐĩ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐģҌĐŊĐ°Ņ ŅŅ‚Ņ€ĐžĐēа. Đ­Ņ‚Đž ĐžŅĐžĐąĐĩĐŊĐŊĐž ĐŋĐžĐģĐĩСĐŊĐž Đ´ĐģŅ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… даĐŊĐŊҋ҅. -БĐĩС ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи даĐŊĐŊҋ҅ ВаĐŧ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐąŅ‹ ĐŋŅ€ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ. +БĐĩС ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅ ваĐŧ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐąŅ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ Đ˛ŅĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ в ĐēОдĐĩ. -ИĐŧĐĩĐŊĐŊĐž Đ´ĐģŅ ОйĐĩҁĐŋĐĩ҇ĐĩĐŊĐ¸Ņ ŅŅ‚Đ¸Ņ… Ņ„ŅƒĐŊĐēŅ†Đ¸Đš и ĐąŅ‹Đģа ŅĐžĐˇĐ´Đ°ĐŊа Marshmallow. -Đ­Ņ‚Đž ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ йийĐģĐ¸ĐžŅ‚ĐĩĐēа и Ņ ĐŧĐŊĐžĐŗĐž Ņ€Đ°Đˇ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģŅŅ ĐĩŅŽ Ņ€Đ°ĐŊҌ҈Đĩ. +ИĐŧĐĩĐŊĐŊĐž Đ´ĐģŅ ŅŅ‚Đ¸Ņ… вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš и ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Marshmallow. Đ­Ņ‚Đž ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ йийĐģĐ¸ĐžŅ‚ĐĩĐēа, Ņ ĐŧĐŊĐžĐŗĐž ĐĩĐš ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģŅŅ Ņ€Đ°ĐŊҌ҈Đĩ. -Но ĐžĐŊа ĐąŅ‹Đģа ŅĐžĐˇĐ´Đ°ĐŊа Đ´Đž Ņ‚ĐžĐŗĐž, ĐēаĐē ĐŋĐžŅĐ˛Đ¸ĐģĐ¸ŅŅŒ ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв Python. -Đ˜Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐēаĐļĐ´ŅƒŅŽ ҁ҅ĐĩĐŧ҃, -ВаĐŧ ĐŊ҃ĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐŊŅ‹Đĩ ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ и ĐēĐģĐ°ŅŅŅ‹, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đĩ Marshmallow. +Но ĐžĐŊа ĐŋĐžŅĐ˛Đ¸ĐģĐ°ŅŅŒ Đ´Đž Ņ‚ĐžĐŗĐž, ĐēаĐē в Python ĐŋĐžŅĐ˛Đ¸ĐģĐ¸ŅŅŒ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв. ĐŸĐžŅŅ‚ĐžĐŧ҃ Đ´ĐģŅ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ĐēаĐļдОК ҁ҅ĐĩĐŧŅ‹ ĐŊ҃ĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊŅ‹Đĩ ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ и ĐēĐģĐ°ŅŅŅ‹, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đĩ Marshmallow. -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēОд ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ "ҁ҅ĐĩĐŧ", ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅŽŅ‰Đ¸Ņ… Ņ‚Đ¸ĐŋŅ‹ даĐŊĐŊҋ҅ и Đ¸Ņ… ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃. +Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēОд Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ÂĢҁ҅ĐĩĐŧÂģ, ĐˇĐ°Đ´Đ°ŅŽŅ‰Đ¸Ņ… Ņ‚Đ¸ĐŋŅ‹ даĐŊĐŊҋ҅ и Đ¸Ņ… ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ. /// -### Webargs +### Webargs { #webargs } -Đ”Ņ€ŅƒĐŗĐ°Ņ ĐŊĐĩĐŧаĐģОваĐļĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ API - ĐŋĐ°Ņ€ŅĐ¸ĐŊĐŗ даĐŊĐŊҋ҅ иС Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛. +Đ•Ņ‰Ņ‘ ОдĐŊа ваĐļĐŊĐ°Ņ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ Đ´ĐģŅ API — ĐŋĐ°Ņ€ŅĐ¸ĐŊĐŗ даĐŊĐŊҋ҅ иС Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… HTTP-СаĐŋŅ€ĐžŅĐžĐ˛. -Webargs - ŅŅ‚Đž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž и ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, вĐēĐģŅŽŅ‡Đ°Ņ Flask. +Webargs — ŅŅ‚Đž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐŋОвĐĩҀ҅ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, вĐēĐģŅŽŅ‡Đ°Ņ Flask. -ДĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи даĐŊĐŊҋ҅ ĐžĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Marshmallow и ŅĐžĐˇĐ´Đ°ĐŊ Ņ‚ĐĩĐŧи ĐļĐĩ Đ°Đ˛Ņ‚ĐžŅ€Đ°Đŧи. +ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Marshmallow Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅. И ŅĐžĐˇĐ´Đ°ĐŊ Ņ‚ĐĩĐŧи ĐļĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи. -Đ­Ņ‚Đž ĐŋŅ€ĐĩĐ˛ĐžŅŅ…ĐžĐ´ĐŊŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ и Ņ Ņ‚ĐžĐļĐĩ Ņ‡Đ°ŅŅ‚Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģŅŅ иĐŧ Đ´Đž **FastAPI**. +Đ­Ņ‚Đž ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, и Ņ Ņ‚ĐžĐļĐĩ ĐŧĐŊĐžĐŗĐž иĐŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģŅŅ Đ´Đž ĐŋĐžŅĐ˛ĐģĐĩĐŊĐ¸Ņ **FastAPI**. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -Webargs ĐąŅ‹ ŅĐžĐˇĐ´Đ°ĐŊ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи Marshmallow. +Webargs ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Ņ‚ĐĩĐŧи ĐļĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи, Ņ‡Ņ‚Đž и Marshmallow. /// -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ДоĐģĐļĐŊа ĐąŅ‹Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа Đ˛Ņ…ĐžĐ´ĐŊҋ҅ даĐŊĐŊҋ҅. +ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… даĐŊĐŊҋ҅ HTTP-СаĐŋŅ€ĐžŅĐ°. /// -### APISpec +### APISpec { #apispec } -Marshmallow и Webargs ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģŅŅŽŅ‚ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃, аĐŊаĐģиС и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅ ĐēаĐē ĐŋĐģĐ°ĐŗĐ¸ĐŊŅ‹. +Marshmallow и Webargs ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ, ĐŋĐ°Ņ€ŅĐ¸ĐŊĐŗ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ ĐēаĐē ĐŋĐģĐ°ĐŗĐ¸ĐŊŅ‹. -Но Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API Đ˛ŅŅ‘ Đĩ҉ґ ĐŊĐĩ ĐąŅ‹ĐģĐž. ĐĸĐžĐŗĐ´Đ° ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ APISpec. +Но Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Đ˛ŅŅ‘ Đĩ҉ґ ĐŊĐĩ ĐąŅ‹ĐģĐž. ĐĸĐžĐŗĐ´Đ° ĐŋĐžŅĐ˛Đ¸ĐģŅŅ APISpec. -Đ­Ņ‚Đž ĐŋĐģĐ°ĐŗĐ¸ĐŊ Đ´ĐģŅ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, в Ņ‚ĐžĐŧ Ņ‡Đ¸ŅĐģĐĩ и Đ´ĐģŅ Starlette. +Đ­Ņ‚Đž ĐŋĐģĐ°ĐŗĐ¸ĐŊ Đ´ĐģŅ ĐŧĐŊĐžĐŗĐ¸Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв (ĐĩŅŅ‚ŅŒ ĐŋĐģĐ°ĐŗĐ¸ĐŊ и Đ´ĐģŅ Starlette). -ОĐŊ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Ņ‚Đ°Đē - Đ’Ņ‹ СаĐŋĐ¸ŅŅ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ҁ҅ĐĩĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ„ĐžŅ€ĐŧĐ°Ņ‚ YAML, вĐŊŅƒŅ‚Ņ€Đ¸ Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗĐ° ĐēаĐļдОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‰ĐĩĐš ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚. +ОĐŊ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Ņ‚Đ°Đē: Đ˛Ņ‹ ĐŋĐ¸ŅˆĐĩŅ‚Đĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ҁ҅ĐĩĐŧŅ‹ в Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ YAML вĐŊŅƒŅ‚Ņ€Đ¸ Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗĐ° ĐēаĐļдОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‰ĐĩĐš ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚. -Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ ŅŅ‚Đ¸ Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗĐ¸, ĐžĐŊ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ ҁ҅ĐĩĐŧ҃ OpenAPI. +И ĐžĐŊ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ ҁ҅ĐĩĐŧŅ‹ OpenAPI. -ĐĸаĐē ŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Đ´ĐģŅ Flask, Starlette, Responder и Ņ‚.Đŋ. +ĐĸаĐē ŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ вО Flask, Starlette, Responder и Ņ‚. Đ´. -Но Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ҃ ĐŊĐ°Ņ вОСĐŊиĐēаĐĩŅ‚ ĐŊĐžĐ˛Đ°Ņ ĐŋŅ€ĐžĐąĐģĐĩĐŧа - ĐŊаĐģĐ¸Ņ‡Đ¸Đĩ ĐŋĐžŅŅ‚ĐžŅ€ĐžĐŊĐŊĐĩĐŗĐž ĐŧиĐēŅ€Đž-ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° вĐŊŅƒŅ‚Ņ€Đ¸ ĐēОда Python (йОĐģŅŒŅˆĐ¸Đĩ YAML). +Но ҃ ĐŊĐ°Ņ ҁĐŊОва вОСĐŊиĐēаĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧа: ĐŋĐžŅĐ˛ĐģŅĐĩŅ‚ŅŅ ĐŧиĐēŅ€Đž-ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ вĐŊŅƒŅ‚Ņ€Đ¸ ŅŅ‚Ņ€ĐžĐēи Python (йОĐģŅŒŅˆĐžĐš YAML). -Đ ĐĩдаĐēŅ‚ĐžŅ€ ĐēОда ĐŊĐĩ ĐžŅĐžĐąĐž ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŧĐžŅ‡ŅŒ в Ņ‚Đ°ĐēОК ĐŋĐ°Ņ€Đ°Đ´Đ¸ĐŗĐŧĐĩ. -А иСĐŧĐĩĐŊив ĐēаĐēиĐĩ-Ņ‚Đž ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ иĐģи ҁ҅ĐĩĐŧŅ‹ Đ´ĐģŅ Marshmallow ĐŧĐžĐļĐŊĐž ĐˇĐ°ĐąŅ‹Ņ‚ŅŒ ĐžŅ‚Ņ€ĐĩдаĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗ ҁ YAML и ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐ°Ņ ҁ҅ĐĩĐŧа ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ ĐŊĐĩĐ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊОК. +Đ ĐĩдаĐēŅ‚ĐžŅ€ ĐēОда ĐŧаĐģĐž ҇ĐĩĐŧ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŧĐžŅ‡ŅŒ. И ĐĩҁĐģи ĐŧŅ‹ иСĐŧĐĩĐŊиĐŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ иĐģи ҁ҅ĐĩĐŧŅ‹ Marshmallow и ĐˇĐ°ĐąŅƒĐ´ĐĩĐŧ Ņ‚Đ°ĐēĐļĐĩ иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ YAML в Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗĐĩ, ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐ°Ņ ҁ҅ĐĩĐŧа ŅƒŅŅ‚Đ°Ņ€ĐĩĐĩŅ‚. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -APISpec Ņ‚ĐžĐļĐĩ ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Đ°Đ˛Ņ‚ĐžŅ€Đ°Đŧи Marshmallow. +APISpec ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Ņ‚ĐĩĐŧи ĐļĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи, Ņ‡Ņ‚Đž и Marshmallow. /// -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -НĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧа ĐŋОддĐĩŅ€ĐļĐēа ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ĐžĐŗĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ° Đ´ĐģŅ API - OpenAPI. +ПоддĐĩŅ€ĐļĐē҃ ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ĐžĐŗĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ° Đ´ĐģŅ API — OpenAPI. /// -### Flask-apispec +### Flask-apispec { #flask-apispec } -Đ­Ņ‚Đž ĐŋĐģĐ°ĐŗĐ¸ĐŊ Đ´ĐģŅ Flask, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐ˛ŅĐˇĐ°ĐŊ ҁ Webargs, Marshmallow и APISpec. +Đ­Ņ‚Đž ĐŋĐģĐ°ĐŗĐ¸ĐŊ Đ´ĐģŅ Flask, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐ˛ŅĐˇŅ‹Đ˛Đ°ĐĩŅ‚ Webargs, Marshmallow и APISpec. -ОĐŊ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ ĐžŅ‚ Webargs и Marshmallow, а ĐˇĐ°Ņ‚ĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ APISpec Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ҁ҅ĐĩĐŧŅ‹ OpenAPI. +ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ иС Webargs и Marshmallow, Ņ‡Ņ‚ĐžĐąŅ‹ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧŅ‹ OpenAPI ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ APISpec. -Đ­Ņ‚Đž ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš, ĐŊĐž ĐēŅ€Đ°ĐšĐŊĐĩ ĐŊĐĩĐ´ĐžĐžŅ†ĐĩĐŊŅ‘ĐŊĐŊŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚. -ОĐŊ Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ йОĐģĐĩĐĩ ĐŋĐžĐŋ҃ĐģŅŅ€ĐĩĐŊ, ҇ĐĩĐŧ ĐŧĐŊĐžĐŗĐ¸Đĩ ĐŋĐģĐ°ĐŗĐ¸ĐŊŅ‹ Đ´ĐģŅ Flask. -ВозĐŧĐžĐļĐŊĐž, ŅŅ‚Đž ŅĐ˛ŅĐˇĐ°ĐŊĐž ҁ Ņ‚ĐĩĐŧ, Ņ‡Ņ‚Đž ĐĩĐŗĐž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ ҁĐģĐ¸ŅˆĐēĐžĐŧ ҁĐēŅƒĐ´ĐŊа и Đ°ĐąŅŅ‚Ņ€Đ°ĐēŅ‚ĐŊа. +ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš и ĐŊĐĩĐ´ĐžĐžŅ†ĐĩĐŊŅ‘ĐŊĐŊŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚. ОĐŊ ĐˇĐ°ŅĐģ҃ĐļиваĐĩŅ‚ йОĐģҌ҈ĐĩĐš ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊĐžŅŅ‚Đ¸, ҇ĐĩĐŧ ĐŧĐŊĐžĐŗĐ¸Đĩ ĐŋĐģĐ°ĐŗĐ¸ĐŊŅ‹ Đ´ĐģŅ Flask. ВозĐŧĐžĐļĐŊĐž, иС-Са ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐēŅ€Đ°Ņ‚ĐēОК и Đ°ĐąŅŅ‚Ņ€Đ°ĐēŅ‚ĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. -ОĐŊ иСйавиĐģ ĐžŅ‚ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ ĐŋĐ¸ŅĐ°Ņ‚ŅŒ Ņ‡ŅƒĐļĐĩŅ€ĐžĐ´ĐŊŅ‹Đš ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ YAML вĐŊŅƒŅ‚Ņ€Đ¸ Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗĐžĐ˛. +Đ­Ņ‚Đž Ņ€ĐĩŅˆĐ¸ĐģĐž ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ ĐŋĐ¸ŅĐ°Ņ‚ŅŒ YAML (Đĩ҉ґ ОдиĐŊ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ) в Đ´ĐžĐēŅŅ‚Ņ€Đ¸ĐŊĐŗĐ°Ņ… Python. -ĐĸаĐēĐžĐĩ ŅĐžŅ‡ĐĩŅ‚Đ°ĐŊиĐĩ Flask, Flask-apispec, Marshmallow и Webargs ĐąŅ‹ĐģĐž ĐŧОиĐŧ ĐģŅŽĐąĐ¸ĐŧŅ‹Đŧ ҁ҂ĐĩĐēĐžĐŧ ĐŋŅ€Đ¸ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊии ĐąŅĐēĐĩĐŊда Đ´Đž ĐŋĐžŅĐ˛ĐģĐĩĐŊĐ¸Ņ **FastAPI**. +КоĐŧйиĐŊĐ°Ņ†Đ¸Ņ Flask, Flask-apispec ҁ Marshmallow и Webargs ĐąŅ‹Đģа ĐŧОиĐŧ ĐģŅŽĐąĐ¸ĐŧŅ‹Đŧ ĐąŅĐēĐĩĐŊĐ´-ҁ҂ĐĩĐēĐžĐŧ Đ´Đž ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ **FastAPI**. -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ŅŅ‚ĐžĐŗĐž ҁ҂ĐĩĐēа ĐŋŅ€Đ¸Đ˛ĐĩĐģĐž Đē ŅĐžĐˇĐ´Đ°ĐŊĐ¸ŅŽ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛ ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐ˛. Đ¯ и ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐēĐžĐŧаĐŊĐ´Ņ‹ Đ´Đž ŅĐ¸Ņ… ĐŋĐžŅ€ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ Đ¸Ņ…: +Đ•ĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€Đ¸Đ˛ĐĩĐģĐž Đē ŅĐžĐˇĐ´Đ°ĐŊĐ¸ŅŽ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… full-stack ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛ ĐŊа Flask. Đ­Ņ‚Đž ĐžŅĐŊОвĐŊŅ‹Đĩ ҁ҂ĐĩĐēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ (и ĐŊĐĩҁĐēĐžĐģҌĐēĐž вĐŊĐĩ҈ĐŊĐ¸Ņ… ĐēĐžĐŧаĐŊĐ´) Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи Đ´Đž ŅĐ¸Ņ… ĐŋĐžŅ€: * https://github.com/tiangolo/full-stack * https://github.com/tiangolo/full-stack-flask-couchbase * https://github.com/tiangolo/full-stack-flask-couchdb -Đ­Ņ‚Đ¸ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Ņ‹ ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐ˛ Ņ‚Đ°ĐēĐļĐĩ ŅŅ‚Đ°Đģи ĐžŅĐŊОвОК Đ´ĐģŅ [ГĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛ ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐ˛ ҁ **FastAPI**](project-generation.md){.internal-link target=_blank}. +И ŅŅ‚Đ¸ ĐļĐĩ full-stack ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Ņ‹ ŅŅ‚Đ°Đģи ĐžŅĐŊОвОК Đ´ĐģŅ [ГĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛ ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐ˛ **FastAPI**](project-generation.md){.internal-link target=_blank}. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -КаĐē ĐŊи ŅŅ‚Ņ€Đ°ĐŊĐŊĐž, ĐŊĐž Flask-apispec Ņ‚ĐžĐļĐĩ ŅĐžĐˇĐ´Đ°ĐŊ Đ°Đ˛Ņ‚ĐžŅ€Đ°Đŧи Marshmallow. +Flask-apispec ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Ņ‚ĐĩĐŧи ĐļĐĩ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи, Ņ‡Ņ‚Đž и Marshmallow. /// -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ĐĄŅ…ĐĩĐŧа OpenAPI Đ´ĐžĐģĐļĐŊа ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžŅ‚ ĐļĐĩ ĐēОд, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģŅĐĩŅ‚ ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ и ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ даĐŊĐŊҋ҅. +ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸ŅŽ ҁ҅ĐĩĐŧŅ‹ OpenAPI иС Ņ‚ĐžĐŗĐž ĐļĐĩ ĐēОда, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚ ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ и ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ. /// -### NestJS (и Angular) +### NestJS (и Angular) { #nestjs-and-angular } -ЗдĐĩҁҌ даĐļĐĩ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Python. NestJS - ŅŅ‚ĐžŅ‚ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē ĐŊаĐŋĐ¸ŅĐ°ĐŊĐŊŅ‹Đš ĐŊа JavaScript (TypeScript), ĐžŅĐŊОваĐŊĐŊŅ‹Đš ĐŊа NodeJS и Đ˛Đ´ĐžŅ…ĐŊОвĐģŅ‘ĐŊĐŊŅ‹Đš Angular. +Đ­Ņ‚Đž даĐļĐĩ ĐŊĐĩ Python. NestJS — ŅŅ‚Đž JavaScript/TypeScript-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē ĐŊа NodeJS, Đ˛Đ´ĐžŅ…ĐŊОвĐģŅ‘ĐŊĐŊŅ‹Đš Angular. -ОĐŊ ĐŋОСвОĐģŅĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐŊĐĩŅ‡Ņ‚Đž ĐŋĐžŅ…ĐžĐļĐĩĐĩ ĐŊа Ņ‚Đž, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Flask-apispec. +ОĐŊ Đ´ĐžŅŅ‚Đ¸ĐŗĐ°ĐĩŅ‚ ҇ĐĩĐŗĐž-Ņ‚Đž ĐžŅ‚Ņ‡Đ°ŅŅ‚Đ¸ ĐŋĐžŅ…ĐžĐļĐĩĐŗĐž ĐŊа Ņ‚Đž, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ҁ Flask-apispec. -В ĐŊĐĩĐŗĐž Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊа ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, Đĩ҉ґ ОдĐŊа идĐĩŅ Đ˛ĐˇŅŅ‚Đ°Ņ ĐžŅ‚ Angular. -ОдĐŊаĐēĐž ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸Ņ "вĐŊĐĩĐ´Ņ€ĐĩĐŊиК" (ĐēаĐē и вО Đ˛ŅĐĩŅ… Đ´Ņ€ŅƒĐŗĐ¸Ņ… иСвĐĩҁ҂ĐŊҋ҅ ĐŧĐŊĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ… вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš), Ņ‡Ņ‚Đž ŅƒĐ˛ĐĩĐģĐ¸Ņ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž и ĐŋĐžĐ˛Ņ‚ĐžŅ€ŅĐĩĐŧĐžŅŅ‚ŅŒ ĐēОда. +В ĐŊŅ‘Đŧ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊа ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, Đ˛Đ´ĐžŅ…ĐŊОвĐģŅ‘ĐŊĐŊĐ°Ņ Angular 2. ĐĸŅ€ĐĩĐąŅƒĐĩŅ‚ŅŅ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸Ņ ÂĢиĐŊĐļĐĩĐēŅ‚Đ¸Ņ€ŅƒĐĩĐŧҋ҅Âģ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛ (ĐēаĐē и вО Đ˛ŅĐĩŅ… иСвĐĩҁ҂ĐŊҋ҅ ĐŧĐŊĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ… вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš), Ņ‡Ņ‚Đž дОйавĐģŅĐĩŅ‚ ĐŧĐŊĐžĐŗĐžŅĐģОвĐŊĐžŅŅ‚Đ¸ и ĐŋĐžĐ˛Ņ‚ĐžŅ€ŅĐĩĐŧĐžŅŅ‚Đ¸ ĐēОда. -ĐĸаĐē ĐēаĐē ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ в ĐŊŅ‘Đŧ ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°ŅŽŅ‚ŅŅ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Ņ‚Đ¸ĐŋОв TypeScript (аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž ĐŋĐžĐ´ŅĐēаСĐēаĐŧ Ņ‚Đ¸ĐŋОв в Python), ĐŋОддĐĩŅ€ĐļĐēа Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ дОвОĐģҌĐŊĐž Ņ…ĐžŅ€ĐžŅˆĐž. +ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°ŅŽŅ‚ŅŅ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Ņ‚Đ¸ĐŋОв TypeScript (аĐŊаĐģĐžĐŗ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đš Ņ‚Đ¸ĐŋОв в Python), ĐŋОддĐĩŅ€ĐļĐēа Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° вĐĩҁҌĐŧа Ņ…ĐžŅ€ĐžŅˆĐ°. -Но ĐŋĐžŅĐēĐžĐģҌĐē҃ даĐŊĐŊŅ‹Đĩ иС TypeScript ĐŊĐĩ ŅĐžŅ…Ņ€Đ°ĐŊŅŅŽŅ‚ŅŅ ĐŋĐžŅĐģĐĩ ĐēĐžĐŧĐŋиĐģŅŅ†Đ¸Đ¸ в JavaScript, ĐžĐŊ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģĐ°ĐŗĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв Đ´ĐģŅ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. -ИС-Са ŅŅ‚ĐžĐŗĐž и ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… диСаКĐŊĐĩҀҁĐēĐ¸Ņ… Ņ€Đĩ҈ĐĩĐŊиК, Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ҁ҅ĐĩĐŧ, ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ вО ĐŧĐŊĐžĐŗĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ… дОйавĐģŅŅ‚ŅŒ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Ņ‹. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ŅŅ‚Đž ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ дОвОĐģҌĐŊĐž ĐŧĐŊĐžĐŗĐžŅĐģОвĐŊŅ‹Đŧ. +Но Ņ‚Đ°Đē ĐēаĐē даĐŊĐŊŅ‹Đĩ Đž Ņ‚Đ¸ĐŋĐ°Ņ… TypeScript ĐŊĐĩ ŅĐžŅ…Ņ€Đ°ĐŊŅŅŽŅ‚ŅŅ ĐŋĐžŅĐģĐĩ ĐēĐžĐŧĐŋиĐģŅŅ†Đ¸Đ¸ в JavaScript, ĐžĐŊ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģĐ°ĐŗĐ°Ņ‚ŅŒŅŅ ĐŊа Ņ‚Đ¸ĐŋŅ‹ Đ´ĐģŅ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžĐŗĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. Из‑за ŅŅ‚ĐžĐŗĐž и ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŋŅ€ĐžĐĩĐēŅ‚ĐŊҋ҅ Ņ€Đĩ҈ĐĩĐŊиК Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ҁ҅ĐĩĐŧ ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ дОйавĐģŅŅ‚ŅŒ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€Ņ‹ вО ĐŧĐŊĐžĐŗĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ…. В Đ¸Ņ‚ĐžĐŗĐĩ ŅŅ‚Đž ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ дОвОĐģҌĐŊĐž ĐŧĐŊĐžĐŗĐžŅĐģОвĐŊŅ‹Đŧ. -ĐšŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž, ĐžĐŊ ĐŊĐĩ ĐžŅ‡ĐĩĐŊҌ Ņ…ĐžŅ€ĐžŅˆĐž ҁĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ ҁ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧи ĐŧОдĐĩĐģŅĐŧи. -Đ•ŅĐģи в СаĐŋŅ€ĐžŅĐĩ иĐŧĐĩĐĩŅ‚ŅŅ ĐžĐąŅŠĐĩĐēŅ‚ JSON, вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ ĐŋĐžĐģŅ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž, в ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, ŅĐ˛ĐģŅŅŽŅ‚ŅŅ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧи ĐžĐąŅŠĐĩĐēŅ‚Đ°Đŧи JSON, ŅŅ‚Đž ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐģĐļĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐž и ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊĐž. +ОĐŊ ĐŋĐģĐžŅ…Đž ҁĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ ҁ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧи ĐŧОдĐĩĐģŅĐŧи. Đ•ŅĐģи JSON-Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° — ŅŅ‚Đž ĐžĐąŅŠĐĩĐēŅ‚ JSON, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ ĐŋĐžĐģŅ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅĐ°Đŧи ŅĐ˛ĐģŅŅŽŅ‚ŅŅ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧи ĐžĐąŅŠĐĩĐēŅ‚Đ°Đŧи JSON, ŅŅ‚Đž ĐŊĐĩĐģŅŒĐˇŅ ĐēаĐē ҁĐģĐĩĐ´ŅƒĐĩŅ‚ СадОĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и ĐŋŅ€ĐžĐ˛Đ°ĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ. -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ĐŅƒĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв, Ņ‡Ņ‚ĐžĐą Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ ĐŋОддĐĩŅ€ĐļĐēОК Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° ĐēОда. +Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đ¸ĐŋŅ‹ Python Đ´ĐģŅ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊОК ĐŋОддĐĩŅ€ĐļĐēи в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ ĐēОда. -ĐŅƒĐļĐŊа ĐŧĐžŅ‰ĐŊĐ°Ņ ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. НĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧ ҁĐŋĐžŅĐžĐą Đ´ĐģŅ ҃ĐŧĐĩĐŊҌ҈ĐĩĐŊĐ¸Ņ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐžĐ˛ ĐēОда. +ИĐŧĐĩŅ‚ŅŒ ĐŧĐžŅ‰ĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. ĐĐ°ĐšŅ‚Đ¸ ҁĐŋĐžŅĐžĐą ĐŧиĐŊиĐŧĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐĩĐŊиĐĩ ĐēОда. /// -### Sanic +### Sanic { #sanic } -Sanic ĐąŅ‹Đģ ОдĐŊиĐŧ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ҇ҀĐĩĐˇĐ˛Ņ‹Ņ‡Đ°ĐšĐŊĐž ĐąŅ‹ŅŅ‚Ņ€Ņ‹Ņ… Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв ĐžŅĐŊОваĐŊĐŊҋ҅ ĐŊа `asyncio`. -ОĐŊ ĐąŅ‹Đģ ŅĐ´ĐĩĐģаĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļиĐŧ ĐŊа Flask. +Đ­Ņ‚Đž ĐąŅ‹Đģ ОдиĐŊ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ҇ҀĐĩĐˇĐ˛Ņ‹Ņ‡Đ°ĐšĐŊĐž ĐąŅ‹ŅŅ‚Ņ€Ņ‹Ņ… Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв ĐŊа ĐžŅĐŊОвĐĩ `asyncio`. ОĐŊ ĐąŅ‹Đģ ŅĐ´ĐĩĐģаĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļиĐŧ ĐŊа Flask. /// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи -В ĐŊŅ‘Đŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ `uvloop` вĐŧĐĩŅŅ‚Đž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊĐžĐŗĐž Ņ†Đ¸ĐēĐģа ŅĐžĐąŅ‹Ņ‚Đ¸Đš `asyncio`, Ņ‡Ņ‚Đž и ŅĐ´ĐĩĐģаĐģĐž ĐĩĐŗĐž Ņ‚Đ°ĐēиĐŧ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đŧ. +ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ `uvloop` вĐŧĐĩŅŅ‚Đž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊĐžĐŗĐž Ņ†Đ¸ĐēĐģа `asyncio` в Python. Đ­Ņ‚Đž и ŅĐ´ĐĩĐģаĐģĐž ĐĩĐŗĐž Ņ‚Đ°ĐēиĐŧ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đŧ. -ОĐŊ ŅĐ˛ĐŊĐž Đ˛Đ´ĐžŅ…ĐŊОвиĐģ ŅĐžĐˇĐ´Đ°Ņ‚ĐĩĐģĐĩĐš Uvicorn и Starlette, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ в ĐŊĐ°ŅŅ‚ĐžŅŅ‰ĐĩĐĩ Đ˛Ņ€ĐĩĐŧŅ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ Sanic в ĐžŅ‚ĐēҀҋ҂ҋ҅ ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēĐ°Ņ…. +ОĐŊ ŅĐ˛ĐŊĐž Đ˛Đ´ĐžŅ…ĐŊОвиĐģ Uvicorn и Starlette, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐĩĐšŅ‡Đ°Ņ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ Sanic в ĐžŅ‚ĐēҀҋ҂ҋ҅ ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēĐ°Ņ…. /// -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ДоĐģĐļĐŊа ĐąŅ‹Ņ‚ŅŒ ҁ҃ĐŧĐ°ŅŅˆĐĩĐ´ŅˆĐ°Ņ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. +ĐŸĐžĐ¸ŅĐē ҁĐŋĐžŅĐžĐąĐ° Đ´ĐžŅŅ‚Đ¸Ņ‡ŅŒ ҁ҃ĐŧĐ°ŅŅˆĐĩĐ´ŅˆĐĩĐš ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸. -ДĐģŅ ŅŅ‚ĐžĐŗĐž **FastAPI** ĐžŅĐŊОваĐŊ ĐŊа Starlette, ŅĐ°ĐŧĐžĐŧ ĐąŅ‹ŅŅ‚Ņ€ĐžĐŧ иС Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв (ĐŋĐž СаĐŧĐĩŅ€Đ°Đŧ ĐŊĐĩСаиĐŊŅ‚ĐĩŅ€ĐĩŅĐžĐ˛Đ°ĐŊĐŊҋ҅ ĐģĐ¸Ņ†). +ИĐŧĐĩĐŊĐŊĐž ĐŋĐžŅŅ‚ĐžĐŧ҃ **FastAPI** ĐžŅĐŊОваĐŊ ĐŊа Starlette, Ņ‚Đ°Đē ĐēаĐē ŅŅ‚Đž ŅĐ°ĐŧŅ‹Đš ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đš Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đš ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē (ĐŋĐž даĐŊĐŊŅ‹Đŧ ŅŅ‚ĐžŅ€ĐžĐŊĐŊĐ¸Ņ… ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēОв). /// -### Falcon +### Falcon { #falcon } -Falcon - Đĩ҉ґ ОдиĐŊ Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē. -В ĐŊŅ‘Đŧ ĐŧиĐŊиĐŧ҃Đŧ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš и ĐžĐŊ ŅĐžĐˇĐ´Đ°ĐŊ, Ņ‡Ņ‚ĐžĐą ĐąŅ‹Ņ‚ŅŒ ĐžŅĐŊОвОК Đ´ĐģŅ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Hug. +Falcon — Đĩ҉ґ ОдиĐŊ Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, ĐžĐŊ ĐŧиĐŊиĐŧаĐģĐ¸ŅŅ‚Đ¸Ņ‡ĐĩĐŊ и ҁĐģ҃ĐļĐ¸Ņ‚ ĐžŅĐŊОвОК Đ´ĐģŅ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, Ņ‚Đ°ĐēĐ¸Ņ… ĐēаĐē Hug. -Đ¤ŅƒĐŊĐēŅ†Đ¸Đ¸ в ĐŊŅ‘Đŧ ĐŋĐžĐģŅƒŅ‡Đ°ŅŽŅ‚ два ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° - "СаĐŋŅ€ĐžŅ Đē ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ" и "ĐžŅ‚Đ˛ĐĩŅ‚ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°". -Đ—Đ°Ņ‚ĐĩĐŧ Đ’Ņ‹ "Ņ‡Đ¸Ņ‚Đ°ĐĩŅ‚Đĩ" Ņ‡Đ°ŅŅ‚ŅŒ СаĐŋŅ€ĐžŅĐ° и "ĐŋĐ¸ŅˆĐ¸Ņ‚Đĩ" Ņ‡Đ°ŅŅ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. -ИС-Са Ņ‚Đ°ĐēОК ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Đ¸ ĐŊĐĩвОСĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ СаĐŋŅ€ĐžŅĐ° и Ņ‚ĐĩĐģа ŅĐžĐžĐąŅ‰ĐĩĐŊĐ¸Ņ ŅĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đŧи ĐŋĐžĐ´ŅĐēаСĐēаĐŧи Ņ‚Đ¸ĐŋОв Python в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸. +ОĐŊ ҁĐŋŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊ Ņ‚Đ°Đē, Ņ‡Ņ‚Đž Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŋĐžĐģŅƒŅ‡Đ°ŅŽŅ‚ два ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°: ÂĢrequestÂģ и ÂĢresponseÂģ. Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ÂĢŅ‡Đ¸Ņ‚Đ°ĐĩŅ‚ĐĩÂģ Ņ‡Đ°ŅŅ‚Đ¸ иС СаĐŋŅ€ĐžŅĐ° и ÂĢĐŋĐ¸ŅˆĐĩŅ‚ĐĩÂģ Ņ‡Đ°ŅŅ‚Đ¸ в ĐžŅ‚Đ˛ĐĩŅ‚. Из‑за Ņ‚Đ°ĐēĐžĐŗĐž диСаКĐŊа ĐŊĐĩвОСĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ СаĐŋŅ€ĐžŅĐ° и Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đŧи аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв Python ĐēаĐē ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, и ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅, и Đ¸Ņ… ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ, и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŊ҃ĐļĐŊĐž ĐŋŅ€ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°Ņ‚ŅŒ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ. -Либо ŅŅ‚Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊŅ‹ вО ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, ҁĐēĐžĐŊŅŅ‚Ņ€ŅƒĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ĐŋОвĐĩҀ҅ Falcon, ĐēаĐē в Hug. -ĐĸаĐēĐ°Ņ ĐļĐĩ ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚ŅŒ ĐŋŅ€Đ¸ŅŅƒŅ‚ŅŅ‚Đ˛ŅƒĐĩŅ‚ и в Đ´Ņ€ŅƒĐŗĐ¸Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐ°Ņ…, Đ˛Đ´ĐžŅ…ĐŊОвĐģŅ‘ĐŊĐŊҋ҅ идĐĩĐĩĐš Falcon, Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐžĐąŅŠĐĩĐēŅ‚ СаĐŋŅ€ĐžŅĐ° и ОдиĐŊ ĐžĐąŅŠĐĩĐēŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚Đ°. +ĐŸĐžŅŅ‚ĐžĐŧ҃ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ Đ´ĐžĐģĐļĐŊŅ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ в ĐēОдĐĩ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ, ĐŊĐĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи. Либо Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ Ņ€ĐĩаĐģиСОваĐŊŅ‹ вО ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐĩ ĐŋОвĐĩҀ҅ Falcon, ĐēаĐē в Hug. Đĸа ĐļĐĩ ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚ŅŒ ĐĩŅŅ‚ŅŒ и в Đ´Ņ€ŅƒĐŗĐ¸Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐ°Ņ…, Đ˛Đ´ĐžŅ…ĐŊОвĐģŅ‘ĐŊĐŊҋ҅ диСаКĐŊĐžĐŧ Falcon — ҁ ОдĐŊиĐŧ ĐžĐąŅŠĐĩĐēŅ‚ĐžĐŧ СаĐŋŅ€ĐžŅĐ° и ОдĐŊиĐŧ ĐžĐąŅŠĐĩĐēŅ‚ĐžĐŧ ĐžŅ‚Đ˛ĐĩŅ‚Đ° в ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°Ņ…. -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ĐĐ°ĐšĐ´Đ¸Ņ‚Đĩ ҁĐŋĐžŅĐžĐąŅ‹ Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊОК ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸. +ĐŸĐžĐ¸ŅĐē ҁĐŋĐžŅĐžĐąĐžĐ˛ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. -ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ `ĐžŅ‚Đ˛ĐĩŅ‚Đ° ҁĐĩŅ€Đ˛ĐĩŅ€Đ°` в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ…, ĐēаĐē в Hug. +ВĐŧĐĩҁ҂Đĩ ҁ Hug (Ņ‚Đ°Đē ĐēаĐē Hug ĐžŅĐŊОваĐŊ ĐŊа Falcon) Đ˛Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response` в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ…. -ĐĨĐžŅ‚Ņ в FastAPI ŅŅ‚Đž ĐŊĐĩĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐžŅĐŊОвĐŊĐžĐŧ Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°ĐŗĐžĐģОвĐēОв, Đē҃Đēи и аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊҋ҅ ĐēОдОв ŅĐžŅŅ‚ĐžŅĐŊĐ¸Ņ. +ĐĨĐžŅ‚Ņ в FastAPI ŅŅ‚Đž ĐŊĐĩĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž, и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐžŅĐŊОвĐŊĐžĐŧ Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēОв, cookie и аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊҋ҅ ŅŅ‚Đ°Ņ‚ŅƒŅ-ĐēОдОв. /// -### Molten +### Molten { #molten } -Molten ĐŧĐŊĐĩ ĐŋĐžĐŋаĐģŅŅ ĐŊа ĐŊĐ°Ņ‡Đ°ĐģҌĐŊОК ŅŅ‚Đ°Đ´Đ¸Đ¸ ĐŊаĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ **FastAPI**. В ĐŊŅ‘Đŧ ĐąŅ‹Đģи ĐŋĐžŅ…ĐžĐļиĐĩ идĐĩи: +Đ¯ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ Molten ĐŊа Ņ€Đ°ĐŊĐŊĐ¸Ņ… ŅŅ‚Đ°ĐŋĐ°Ņ… ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ **FastAPI**. И ҃ ĐŊĐĩĐŗĐž ĐąŅ‹Đģи ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļиĐĩ идĐĩи: -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐžĐ´ŅĐēаСОĐē Ņ‚Đ¸ĐŋОв. -* ВаĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ Đ¸ŅŅ…ĐžĐ´Ņ иС ŅŅ‚Đ¸Ņ… ĐŋĐžĐ´ŅĐēаСОĐē. +* ĐžŅĐŊОваĐŊ ĐŊа аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŅ… Ņ‚Đ¸ĐŋОв Python. +* ВаĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ иС ŅŅ‚Đ¸Ņ… Ņ‚Đ¸ĐŋОв. * ĐĄĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. -В ĐŊŅ‘Đŧ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ŅŅ ŅŅ‚ĐžŅ€ĐžĐŊĐŊиĐĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи (Ņ‚Đ°ĐēиĐĩ, ĐēаĐē Pydantic) Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. -ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ Ņ‚Đ¸ĐŋОв ĐŊĐĩĐŋŅ€ĐžŅŅ‚Đž. +ОĐŊ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ŅŅ‚ĐžŅ€ĐžĐŊĐŊŅŽŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃ Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, Ņ‚Đ°ĐēŅƒŅŽ ĐēаĐē Pydantic, — ҃ ĐŊĐĩĐŗĐž ŅĐ˛ĐžŅ. ĐŸĐžŅŅ‚ĐžĐŧ҃ Ņ‚Đ°ĐēиĐĩ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ Ņ‚Đ¸ĐŋОв даĐŊĐŊҋ҅ ĐąŅƒĐ´ĐĩŅ‚ ҁĐģĐžĐļĐŊĐĩĐĩ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ. -ĐĸаĐēĐļĐĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ йОĐģĐĩĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐ°Ņ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Ņ и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ WSGI, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŊĐĩ ĐŋŅ€ĐĩĐ´ĐŊаСĐŊĐ°Ņ‡ĐĩĐŊ Đ´ĐģŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ҁ Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Uvicorn, Starlette и Sanic, в ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚ ASGI. +ĐĸŅ€ĐĩĐąŅƒŅŽŅ‚ŅŅ йОĐģĐĩĐĩ ĐŧĐŊĐžĐŗĐžŅĐģОвĐŊŅ‹Đĩ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸. И Ņ‚Đ°Đē ĐēаĐē ĐžĐŊ ĐžŅĐŊОваĐŊ ĐŊа WSGI (вĐŧĐĩŅŅ‚Đž ASGI), ĐžĐŊ ĐŊĐĩ ĐŋŅ€ĐĩĐ´ĐŊаСĐŊĐ°Ņ‡ĐĩĐŊ Đ´ĐģŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛ Đ˛Ņ‹ŅĐžĐēОК ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ˛Ņ€ĐžĐ´Đĩ Uvicorn, Starlette и Sanic. -Đ•ĐŗĐž ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ҂ҀĐĩĐąŅƒĐĩŅ‚ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊОК Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸, и ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅŽŅ‚ŅŅ, ĐēаĐē ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ Ņ‚Đ¸ĐŋОв. -ИС-Са ŅŅ‚ĐžĐŗĐž ĐŊĐĩвОСĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ йОĐģĐĩĐĩ ОдĐŊĐžĐŗĐž "ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚Đ°" (ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸), ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐŊŅ‹Đš Ņ‚Đ¸Đŋ. +ĐĄĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš ҂ҀĐĩĐąŅƒĐĩŅ‚ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊОК Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, а ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ Ņ€Đ°ĐˇŅ€ĐĩŅˆĐ°ŅŽŅ‚ŅŅ ĐŋĐž ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đŧ Ņ‚Đ¸ĐŋаĐŧ. ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐŊĐĩвОСĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ йОĐģĐĩĐĩ ОдĐŊĐžĐŗĐž ÂĢĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚Đ°Âģ, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‰ĐĩĐŗĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš Ņ‚Đ¸Đŋ. -ĐœĐ°Ņ€ŅˆŅ€ŅƒŅ‚Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅŅŽŅ‚ŅŅ в ĐĩдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐŧ ĐŧĐĩҁ҂Đĩ ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊҋ҅ в Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ… (вĐŧĐĩŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛, в ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžĐąŅ‘Ņ€ĐŊŅƒŅ‚Ņ‹ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‰Đ¸Đĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ Ņ€ĐĩŅŅƒŅ€ŅŅ‹). -Đ­Ņ‚Đž йОĐģҌ҈Đĩ ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа Django, ҇ĐĩĐŧ ĐŊа Flask и Starlette. -ОĐŊ Ņ€Đ°ĐˇĐ´ĐĩĐģŅĐĩŅ‚ в ĐēОдĐĩ вĐĩŅ‰Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ дОвОĐģҌĐŊĐž Ņ‚ĐĩҁĐŊĐž ŅĐ˛ŅĐˇĐ°ĐŊŅ‹. +ĐœĐ°Ņ€ŅˆŅ€ŅƒŅ‚Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅŅŽŅ‚ŅŅ в ОдĐŊĐžĐŧ ĐŧĐĩҁ҂Đĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ в Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ… (вĐŧĐĩŅŅ‚Đž Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€ŅĐŧĐž ĐŊад Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‰ĐĩĐš ŅĐŊĐ´ĐŋОиĐŊŅ‚). Đ­Ņ‚Đž ĐąĐģиĐļĐĩ Đē Ņ‚ĐžĐŧ҃, ĐēаĐē ŅŅ‚Đž Đ´ĐĩĐģаĐĩŅ‚ Django, ҇ĐĩĐŧ Flask (и Starlette). Đ­Ņ‚Đž Ņ€Đ°ĐˇĐ´ĐĩĐģŅĐĩŅ‚ в ĐēОдĐĩ вĐĩŅ‰Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ дОвОĐģҌĐŊĐž Ņ‚ĐĩҁĐŊĐž ŅĐ˛ŅĐˇĐ°ĐŊŅ‹. -/// check | ИдĐĩŅ Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ОĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Ņ‚Đ¸ĐŋОв даĐŊĐŊҋ҅, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ĐžĐ˛ ĐŧОдĐĩĐģи "ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ". -Đ­Ņ‚Đž ҃ĐģŅƒŅ‡ŅˆĐ°ĐĩŅ‚ ĐŋĐžĐŧĐžŅ‰ŅŒ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° и Ņ€Đ°ĐŊҌ҈Đĩ ŅŅ‚Đž ĐŊĐĩ ĐąŅ‹ĐģĐž Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐž в Pydantic. +ОĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Ņ‚Đ¸ĐŋОв даĐŊĐŊҋ҅, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ÂĢĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽÂģ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ĐžĐ˛ ĐŧОдĐĩĐģи. Đ­Ņ‚Đž ҃ĐģŅƒŅ‡ŅˆĐ°ĐĩŅ‚ ĐŋОддĐĩŅ€ĐļĐē҃ в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ ĐēОда, и Ņ€Đ°ĐŊҌ҈Đĩ ŅŅ‚ĐžĐŗĐž ĐŊĐĩ ĐąŅ‹ĐģĐž в Pydantic. -ФаĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи ŅŅ‚Đž ĐŋĐžĐ´Ņ‚ĐžĐģĐēĐŊ҃ĐģĐž ĐŊа ОйĐŊОвĐģĐĩĐŊиĐĩ Pydantic Đ´ĐģŅ ĐŋОддĐĩŅ€ĐļĐēи ОдиĐŊаĐēĐžĐ˛ĐžĐŗĐž ŅŅ‚Đ¸ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐžĐē (Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ŅŅ‚ĐžŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģ ҃ĐļĐĩ Đ´ĐžŅŅ‚ŅƒĐŋĐĩĐŊ в Pydantic). +ФаĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи ŅŅ‚Đž Đ˛Đ´ĐžŅ…ĐŊОвиĐģĐž ĐŊа ОйĐŊОвĐģĐĩĐŊиĐĩ Ņ‡Đ°ŅŅ‚ĐĩĐš Pydantic, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ Ņ‚Đ°ĐēОК ĐļĐĩ ŅŅ‚Đ¸ĐģҌ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ (Đ˛ŅŅ ŅŅ‚Đ° Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ҃ĐļĐĩ ĐĩŅŅ‚ŅŒ в Pydantic). /// -### Hug +### Hug { #hug } -Hug ĐąŅ‹Đģ ОдĐŊиĐŧ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Đ˛ŅˆĐ¸Ņ… ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊиĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ API ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ ĐŋĐžĐ´ŅĐēаСОĐē Ņ‚Đ¸ĐŋОв Python. -Đ­Ņ‚Đ° ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ идĐĩŅ ĐąŅ‹Đģа Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊа и Đ´Ņ€ŅƒĐŗĐ¸Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи. +Hug ĐąŅ‹Đģ ОдĐŊиĐŧ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Đ˛ŅˆĐ¸Ņ… ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊиĐĩ Ņ‚Đ¸ĐŋОв ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ API ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đš Ņ‚Đ¸ĐŋОв Python. Đ­Ņ‚Đž ĐąŅ‹Đģа ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ идĐĩŅ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Đ˛Đ´ĐžŅ…ĐŊОвиĐģа и Đ´Ņ€ŅƒĐŗĐ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ. -ĐŸŅ€Đ¸ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊии ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ вĐŧĐĩŅŅ‚Đž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊҋ҅ Ņ‚Đ¸ĐŋОв Python Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐ¸ŅŅŒ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹, ĐŊĐž Đ˛ŅŅ‘ ĐļĐĩ ŅŅ‚Đž ĐąŅ‹Đģ ĐžĐŗŅ€ĐžĐŧĐŊŅ‹Đš ŅˆĐ°Đŗ вĐŋĐĩŅ€ĐĩĐ´. +ОĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ Ņ‚Đ¸ĐŋŅ‹ в ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸ŅŅ… вĐŧĐĩŅŅ‚Đž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊҋ҅ Ņ‚Đ¸ĐŋОв Python, ĐŊĐž ŅŅ‚Đž Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅ‹Đģ ĐžĐŗŅ€ĐžĐŧĐŊŅ‹Đš ŅˆĐ°Đŗ вĐŋĐĩŅ€Ņ‘Đ´. -Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ĐąŅ‹Đģ ОдиĐŊ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Đ˛ŅˆĐ¸Ņ… ĐŋĐžĐģĐŊŅƒŅŽ API-ҁ҅ĐĩĐŧ҃ в Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ JSON. +ОĐŊ Ņ‚Đ°ĐēĐļĐĩ ĐąŅ‹Đģ ОдĐŊиĐŧ иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Đ˛ŅˆĐ¸Ņ… ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅƒŅŽ ҁ҅ĐĩĐŧ҃, ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°ŅŽŅ‰ŅƒŅŽ вĐĩҁҌ API в JSON. -ДаĐŊĐŊĐ°Ņ ҁ҅ĐĩĐŧа ĐŊĐĩ ĐŋŅ€Đ¸Đ´ĐĩŅ€ĐļиваĐģĐ°ŅŅŒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐ˛ Đ˛Ņ€ĐžĐ´Đĩ OpenAPI и JSON Schema. -ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐąŅ‹ĐģĐž ĐąŅ‹ ĐŊĐĩĐŋŅ€ĐžŅŅ‚Đž ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ ĐĩŅ‘ ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Swagger UI. -Но ĐžĐŋŅŅ‚ŅŒ ĐļĐĩ, ŅŅ‚Đž ĐąŅ‹Đģа ĐžŅ‡ĐĩĐŊҌ иĐŊĐŊĐžĐ˛Đ°Ņ†Đ¸ĐžĐŊĐŊĐ°Ņ идĐĩŅ. +ОĐŊ ĐŊĐĩ ĐąŅ‹Đģ ĐžŅĐŊОваĐŊ ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ°Ņ… Đ˛Ņ€ĐžĐ´Đĩ OpenAPI и JSON Schema. ĐŸĐžŅŅ‚ĐžĐŧ҃ иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Swagger UI, ĐąŅ‹ĐģĐž ĐąŅ‹ ĐŊĐĩĐŋŅ€ĐžŅŅ‚Đž. Но, ĐžĐŋŅŅ‚ŅŒ ĐļĐĩ, ŅŅ‚Đž ĐąŅ‹Đģа ĐžŅ‡ĐĩĐŊҌ иĐŊĐŊĐžĐ˛Đ°Ņ†Đ¸ĐžĐŊĐŊĐ°Ņ идĐĩŅ. -Đ•Ņ‰Ņ‘ ҃ ĐŊĐĩĐŗĐž ĐĩŅŅ‚ŅŒ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐ°Ņ и ĐŊĐĩĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ: Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ОдиĐŊ и Ņ‚ĐžŅ‚ ĐļĐĩ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē ĐŧĐžĐļĐŊĐž ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ и API, и CLI. +ĐŖ ĐŊĐĩĐŗĐž ĐĩŅŅ‚ŅŒ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐ°Ņ и ĐŊĐĩĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚ŅŒ: ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ОдĐŊĐžĐŗĐž и Ņ‚ĐžĐŗĐž ĐļĐĩ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа ĐŧĐžĐļĐŊĐž ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ и API, и CLI. -ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐžĐŊ ĐžŅĐŊОваĐŊ ĐŊа WSGI, ŅŅ‚Đ°Ņ€ĐžĐŧ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đĩ Đ´ĐģŅ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ вĐĩĐą-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐžĐŊ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ вĐĩĐą-ŅĐžĐēĐĩŅ‚Đ°Đŧи и Đ´Ņ€ŅƒĐŗĐ¸Đŧи ĐŧОдĐŊŅ‹Đŧи ŅˆŅ‚ŅƒĐēаĐŧи, ĐŊĐž Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ОйĐģадаĐĩŅ‚ Đ˛Ņ‹ŅĐžĐēОК ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒŅŽ. +ĐĸаĐē ĐēаĐē ĐžĐŊ ĐžŅĐŊОваĐŊ ĐŊа ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐŧ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đĩ Đ´ĐģŅ ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ вĐĩĐą-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв Python (WSGI), ĐžĐŊ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ WebSocket и ĐŋŅ€ĐžŅ‡Đ¸Đŧ, Ņ…ĐžŅ‚Ņ Ņ‚Đ°ĐēĐļĐĩ Đ´ĐĩĐŧĐžĐŊŅŅ‚Ņ€Đ¸Ņ€ŅƒĐĩŅ‚ Đ˛Ņ‹ŅĐžĐēŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -Hug ŅĐžĐˇĐ´Đ°ĐŊ Timothy Crosley, Đ°Đ˛Ņ‚ĐžŅ€ĐžĐŧ `isort`, ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐžĐŗĐž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ° Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК ŅĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đēи иĐŧĐŋĐžŅ€Ņ‚ĐžĐ˛ в Python-Ņ„Đ°ĐšĐģĐ°Ņ…. +Hug ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ ĐĸиĐŧĐžŅ‚Đ¸ ĐšŅ€ĐžŅĐģи, Ņ‚ĐĩĐŧ ĐļĐĩ Đ°Đ˛Ņ‚ĐžŅ€ĐžĐŧ `isort`, ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐžĐŗĐž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ° Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК ŅĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đēи иĐŧĐŋĐžŅ€Ņ‚ĐžĐ˛ в Ņ„Đ°ĐšĐģĐ°Ņ… Python. /// -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | ИдĐĩи, Đ˛Đ´ĐžŅ…ĐŊĐžĐ˛Đ¸Đ˛ŅˆĐ¸Đĩ **FastAPI** -Hug ĐŋОвĐģĐ¸ŅĐģ ĐŊа ŅĐžĐˇĐ´Đ°ĐŊиĐĩ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Ņ‡Đ°ŅŅ‚ĐĩĐš APIStar и ĐąŅ‹Đģ ОдĐŊиĐŧ иС иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ ҁ҇ĐĩĐģ ĐŊаийОĐģĐĩĐĩ ĐŧĐŊĐžĐŗĐžĐžĐąĐĩŅ‰Đ°ŅŽŅ‰Đ¸Đŧи, ĐŊĐ°Ņ€ŅĐ´Ņƒ ҁ APIStar. +Hug Đ˛Đ´ĐžŅ…ĐŊОвиĐģ Ņ‡Đ°ŅŅ‚Đ¸ APIStar и ĐąŅ‹Đģ ОдĐŊиĐŧ иС ĐŊаийОĐģĐĩĐĩ ĐŧĐŊĐžĐŗĐžĐžĐąĐĩŅ‰Đ°ŅŽŅ‰Đ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ ĐŊĐ°ŅˆŅ‘Đģ, ĐŊĐ°Ņ€ŅĐ´Ņƒ ҁ APIStar. -Hug ĐŊĐ°Ņ‚ĐžĐģĐēĐŊ҃Đģ ĐŊа ĐŧҋҁĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в **FastAPI** ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв Python Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ҁ҅ĐĩĐŧŅ‹, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅŽŅ‰ĐĩĐš API и ĐĩĐŗĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ. +Hug ĐŋĐžĐŧĐžĐŗ Đ˛Đ´ĐžŅ…ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв Python Đ´ĐģŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅŽŅ‰ŅƒŅŽ API. -Hug Đ˛Đ´ĐžŅ…ĐŊОвиĐģ **FastAPI** ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `ĐžŅ‚Đ˛ĐĩŅ‚Đ°` в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ… Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°ĐŗĐžĐģОвĐēОв и Đē҃Đēи. +Hug Đ˛Đ´ĐžŅ…ĐŊОвиĐģ **FastAPI** ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `response` в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ… Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēОв и cookie. /// -### APIStar (<= 0.5) +### APIStar (<= 0.5) { #apistar-0-5 } -НĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŋŅ€Đ¸ĐŊŅŅ‚ŅŒ Ņ€Đĩ҈ĐĩĐŊиĐĩ Đž ŅĐžĐˇĐ´Đ°ĐŊии **FastAPI**, Ņ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ **APIStar**. -В ĐŊĐĩĐŧ ĐąŅ‹ĐģĐž ĐŋĐžŅ‡Ņ‚Đ¸ Đ˛ŅĐĩ, Ņ‡Ņ‚Đž Ņ Đ¸ŅĐēаĐģ и ҃ ĐŊĐĩĐŗĐž ĐąŅ‹Đģ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš диСаКĐŊ. +ĐŸŅ€ŅĐŧĐž ĐŋĐĩŅ€ĐĩĐ´ Ņ€Đĩ҈ĐĩĐŊиĐĩĐŧ ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ **FastAPI** Ņ ĐŊĐ°ŅˆŅ‘Đģ ҁĐĩŅ€Đ˛ĐĩŅ€ **APIStar**. В ĐŊŅ‘Đŧ ĐąŅ‹ĐģĐž ĐŋĐžŅ‡Ņ‚Đ¸ Đ˛ŅŅ‘, Ņ‡Ņ‚Đž Ņ Đ¸ŅĐēаĐģ, и ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đš диСаКĐŊ. -Đ­Ņ‚Đž ĐąŅ‹Đģа ОдĐŊа иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Đš ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰ĐĩĐŗĐž ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв Đ´ĐģŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ и СаĐŋŅ€ĐžŅĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ ĐēĐžĐŗĐ´Đ°-ĐģийО видĐĩĐģ (Đ´Đž NestJS и Molten). -Đ¯ ĐŊĐ°ŅˆŅ‘Đģ ĐĩĐŗĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž в Ņ‚Đž ĐļĐĩ Đ˛Ņ€ĐĩĐŧŅ, Ņ‡Ņ‚Đž и Hug, ĐŊĐž APIStar Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ OpenAPI. +Đ­Ņ‚Đž ĐąŅ‹Đģа ОдĐŊа иС ĐŋĐĩŅ€Đ˛Ņ‹Ņ… Ņ€ĐĩаĐģĐ¸ĐˇĐ°Ņ†Đ¸Đš ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰ĐĩĐŗĐž аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв Python Đ´ĐģŅ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ и СаĐŋŅ€ĐžŅĐžĐ˛ (Đ´Đž NestJS и Molten), ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ видĐĩĐģ. Đ¯ ОйĐŊĐ°Ņ€ŅƒĐļиĐģ ĐĩĐŗĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž в Ņ‚Đž ĐļĐĩ Đ˛Ņ€ĐĩĐŧŅ, Ņ‡Ņ‚Đž и Hug. Но APIStar Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ OpenAPI. -В ĐŊŅ‘Đŧ ĐąŅ‹Đģи Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ и ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ ҁ҅ĐĩĐŧŅ‹ OpenAPI ĐžŅĐŊОваĐŊĐŊŅ‹Đĩ ĐŊа ĐŋĐžĐ´ŅĐēаСĐēĐ°Ņ… Ņ‚Đ¸ĐŋОв в ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ…. +В ĐŊŅ‘Đŧ ĐąŅ‹Đģи Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ и ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ ҁ҅ĐĩĐŧŅ‹ OpenAPI ĐŊа ĐžŅĐŊОвĐĩ Ņ‚ĐĩŅ… ĐļĐĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đš Ņ‚Đ¸ĐŋОв в ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ…. -ĐŸŅ€Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊии ҁ҅ĐĩĐŧŅ‹ Ņ‚ĐĩĐģа ŅĐžĐžĐąŅ‰ĐĩĐŊĐ¸Ņ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐ¸ŅŅŒ ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв, ĐēаĐē в Pydantic, ŅŅ‚Đž йОĐģҌ҈Đĩ ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа Marshmallow, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŋĐžĐŧĐžŅ‰ŅŒ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° ĐąŅ‹Đģа ĐŊĐĩĐ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Ņ…ĐžŅ€ĐžŅˆĐĩĐš, ĐŊĐž Đ˛ŅŅ‘ ĐļĐĩ APIStar ĐąŅ‹Đģ ĐģŅƒŅ‡ŅˆĐ¸Đŧ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐŧ. +ОĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ ҁ҅ĐĩĐŧŅ‹ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ° ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐž Ņ‚Đĩ ĐļĐĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв Python, ĐēаĐē в Pydantic, — ŅŅ‚Đž ĐąŅ‹ĐģĐž ĐąĐģиĐļĐĩ Đē Marshmallow, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŋОддĐĩŅ€ĐļĐēа Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° ĐąŅ‹Đģа ĐąŅ‹ Ņ…ŅƒĐļĐĩ, ĐŊĐž Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž APIStar ĐžŅŅ‚Đ°Đ˛Đ°ĐģŅŅ ĐģŅƒŅ‡ŅˆĐ¸Đŧ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐŧ. -На Ņ‚ĐžŅ‚ ĐŧĐžĐŧĐĩĐŊŅ‚ ҃ ĐŊĐĩĐŗĐž ĐąŅ‹Đģи ĐģŅƒŅ‡ŅˆĐ¸Đĩ ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚ĐĩĐģи ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ (ĐŋŅ€ĐžĐ¸ĐŗŅ€Ņ‹Đ˛Đ°ŅŽŅ‰Đ¸Đĩ Ņ‚ĐžĐģҌĐēĐž Starlette). +На Ņ‚ĐžŅ‚ ĐŧĐžĐŧĐĩĐŊŅ‚ ҃ ĐŊĐĩĐŗĐž ĐąŅ‹Đģи ĐģŅƒŅ‡ŅˆĐ¸Đĩ ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚ĐĩĐģи в ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēĐ°Ņ… (ĐĩĐŗĐž ĐŋŅ€ĐĩĐ˛ĐžŅŅ…ĐžĐ´Đ¸Đģ Ņ‚ĐžĐģҌĐēĐž Starlette). -ИСĐŊĐ°Ņ‡Đ°ĐģҌĐŊĐž ҃ ĐŊĐĩĐŗĐž ĐŊĐĩ ĐąŅ‹ĐģĐž Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API Đ´ĐģŅ вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°, ĐŊĐž Ņ СĐŊаĐģ, Ņ‡Ņ‚Đž ĐŧĐžĐŗŅƒ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Đē ĐŊĐĩĐŧ҃ Swagger UI. +ĐĄĐŊĐ°Ņ‡Đ°Đģа ҃ ĐŊĐĩĐŗĐž ĐŊĐĩ ĐąŅ‹ĐģĐž вĐĩб‑UI Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API, ĐŊĐž Ņ СĐŊаĐģ, Ņ‡Ņ‚Đž ĐŧĐžĐŗŅƒ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Đē ĐŊĐĩĐŧ҃ Swagger UI. -В APIStar ĐąŅ‹Đģа ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Ņ‚ĐžĐļĐĩ ҂ҀĐĩйОваĐģа ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸ŅŽ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛, ĐēаĐē и Ņ€Đ°ĐŊĐĩĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ. -Но, Ņ‚ĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, ŅŅ‚Đž ĐąŅ‹Đģа ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ ŅˆŅ‚ŅƒĐēа. +ĐŖ ĐŊĐĩĐŗĐž ĐąŅ‹Đģа ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. ОĐŊа ҂ҀĐĩйОваĐģа ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊОК Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛, ĐēаĐē и Đ´Ņ€ŅƒĐŗĐ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, ĐžĐąŅŅƒĐļĐ´Đ°Đ˛ŅˆĐ¸ĐĩŅŅ Đ˛Ņ‹ŅˆĐĩ. Но Đ˛ŅŅ‘ ĐļĐĩ ŅŅ‚Đž ĐąŅ‹Đģа ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ. -Đ¯ ĐŊĐĩ ҁĐŧĐžĐŗ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž в ĐŋĐžĐģĐŊĐžŅ†ĐĩĐŊĐŊĐžĐŧ ĐŋŅ€ĐžĐĩĐēŅ‚Đĩ, Ņ‚Đ°Đē ĐēаĐē ĐąŅ‹Đģи ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ ŅĐž Đ˛ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐŊиĐĩĐŧ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ в ҁ҅ĐĩĐŧ҃ OpenAPI, иС-Са ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŊĐĩвОСĐŧĐžĐļĐŊĐž ĐąŅ‹ĐģĐž Đ˛ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ Đ˛ŅĐĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐŋŅ€Đ¸ĐŧĐĩĐŊŅĐĩĐŧŅ‹Đĩ в ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Đ°Ņ… ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐ˛ ĐŊа ĐžŅĐŊОвĐĩ Flask-apispec. -Đ¯ дОйавиĐģ в ŅĐ˛ĐžĐš ҁĐŋĐ¸ŅĐžĐē ĐˇĐ°Đ´Đ°Ņ‡ ŅĐžĐˇĐ´Đ°ĐŊиĐĩ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ°, дОйавĐģŅŅŽŅ‰ĐĩĐŗĐž ŅŅ‚Ņƒ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ. +МĐŊĐĩ Ņ‚Đ°Đē и ĐŊĐĩ ŅƒĐ´Đ°ĐģĐžŅŅŒ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž в ĐŋĐžĐģĐŊĐžĐŧ ĐŋŅ€ĐžĐĩĐēŅ‚Đĩ, ĐŋĐžŅĐēĐžĐģҌĐē҃ ĐŊĐĩ ĐąŅ‹ĐģĐž иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ ҁ ŅĐ¸ŅŅ‚ĐĩĐŧОК ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ĐŋĐžŅŅ‚ĐžĐŧ҃ Ņ ĐŊĐĩ ĐŧĐžĐŗ СаĐŧĐĩĐŊĐ¸Ņ‚ŅŒ Đ˛ŅĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ иĐŧĐĩĐģ ҁ full-stack ĐŗĐĩĐŊĐĩŅ€Đ°Ņ‚ĐžŅ€Đ°Đŧи ĐŊа ĐžŅĐŊОвĐĩ Flask-apispec. В ĐŧĐžŅ‘Đŧ ĐąŅĐēĐģĐžĐŗĐĩ ĐąŅ‹ĐģĐž ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ (СаĐŋŅ€ĐžŅ ĐŊа иСĐŧĐĩĐŊĐĩĐŊиĐĩ), дОйавĐģŅŅŽŅ‰Đ¸Đš ŅŅ‚Ņƒ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ. -В даĐģҌĐŊĐĩĐšŅˆĐĩĐŧ Ņ„ĐžĐē҃ҁ ĐŋŅ€ĐžĐĩĐēŅ‚Đ° ҁĐŧĐĩŅŅ‚Đ¸ĐģŅŅ. +Đ—Đ°Ņ‚ĐĩĐŧ Ņ„ĐžĐē҃ҁ ĐŋŅ€ĐžĐĩĐēŅ‚Đ° ҁĐŧĐĩŅŅ‚Đ¸ĐģŅŅ. -Đ­Ņ‚Đž йОĐģҌ҈Đĩ ĐŊĐĩ ĐąŅ‹Đģ API-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, Ņ‚Đ°Đē ĐēаĐē Đ°Đ˛Ņ‚ĐžŅ€ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸ĐģŅŅ ĐŊа Starlette. +Đ­Ņ‚Đž ĐŋĐĩŅ€ĐĩŅŅ‚Đ°Đģ ĐąŅ‹Ņ‚ŅŒ вĐĩĐą-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē Đ´ĐģŅ API, Ņ‚Đ°Đē ĐēаĐē Đ°Đ˛Ņ‚ĐžŅ€Ņƒ ĐŊ҃ĐļĐŊĐž ĐąŅ‹ĐģĐž ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа Starlette. -ĐŅ‹ĐŊĐĩ APIStar - ŅŅ‚Đž ĐŊĐ°ĐąĐžŅ€ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đš OpenAPI. +ĐĄĐĩĐšŅ‡Đ°Ņ APIStar — ŅŅ‚Đž ĐŊĐ°ĐąĐžŅ€ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đš OpenAPI, а ĐŊĐĩ вĐĩĐą-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -APIStar ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Tom Christie. ĐĸĐžŅ‚ ŅĐ°ĐŧŅ‹Đš ĐŋĐ°Ņ€ĐĩĐŊҌ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐˇĐ´Đ°Đģ: +APIStar ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ ĐĸĐžĐŧĐžĐŧ ĐšŅ€Đ¸ŅŅ‚Đ¸. ĐĸĐĩĐŧ ŅĐ°ĐŧŅ‹Đŧ ҇ĐĩĐģОвĐĩĐēĐžĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐˇĐ´Đ°Đģ: * Django REST Framework * Starlette (ĐŊа ĐēĐžŅ‚ĐžŅ€ĐžĐŧ ĐžŅĐŊОваĐŊ **FastAPI**) -* Uvicorn (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đš в Starlette и **FastAPI**) +* Uvicorn (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Starlette и **FastAPI**) /// -/// check | ИдĐĩи Đ´ĐģŅ **FastAPI** +/// check | Đ’Đ´ĐžŅ…ĐŊОвиĐģĐž **FastAPI** ĐŊа -ВоĐŋĐģĐžŅ‰ĐĩĐŊиĐĩ. +ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°ĐŊиĐĩ. -МĐŊĐĩ ĐēаСаĐģĐžŅŅŒ ĐąĐģĐĩŅŅ‚ŅŅ‰ĐĩĐš идĐĩĐĩĐš ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž Ņ„ŅƒĐŊĐēŅ†Đ¸Đš (ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ, Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ) ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ОдĐŊĐ¸Ņ… и Ņ‚ĐĩŅ… ĐļĐĩ Ņ‚Đ¸ĐŋОв Python, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ŅŽŅ‚ Đĩ҉ґ и ĐŋĐžĐŧĐžŅ‰ŅŒ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° ĐēОда. +ИдĐĩŅ ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ŅŅ€Đ°ĐˇŅƒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž вĐĩ҉ĐĩĐš (ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ) ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ОдĐŊĐ¸Ņ… и Ņ‚ĐĩŅ… ĐļĐĩ Ņ‚Đ¸ĐŋОв Python, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ŅŽŅ‚ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅƒŅŽ ĐŋОддĐĩŅ€ĐļĐē҃ в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ ĐēОда, ĐŋĐžĐēаСаĐģĐ°ŅŅŒ ĐŧĐŊĐĩ ĐąĐģĐĩŅŅ‚ŅŅ‰ĐĩĐš. -ĐŸĐžŅĐģĐĩ Đ´ĐžĐģĐŗĐ¸Ņ… ĐŋĐžĐ¸ŅĐēОв ҁҀĐĩди ĐŋĐžŅ…ĐžĐļĐ¸Ņ… Đ´Ņ€ŅƒĐŗ ĐŊа Đ´Ņ€ŅƒĐŗĐ° ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв и ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸Ņ Đ¸Ņ… Ņ€Đ°ĐˇĐģĐ¸Ņ‡Đ¸Đš, APIStar ŅŅ‚Đ°Đģ ŅĐ°ĐŧŅ‹Đŧ ĐģŅƒŅ‡ŅˆĐ¸Đŧ Đ˛Ņ‹ĐąĐžŅ€ĐžĐŧ. +ĐŸĐžŅĐģĐĩ Đ´ĐžĐģĐŗĐ¸Ņ… ĐŋĐžĐ¸ŅĐēОв ĐŋĐžŅ…ĐžĐļĐĩĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа и Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ APIStar ĐąŅ‹Đģ ĐģŅƒŅ‡ŅˆĐ¸Đŧ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐŧ. -Но APIStar ĐŋĐĩŅ€ĐĩŅŅ‚Đ°Đģ ĐąŅ‹Ņ‚ŅŒ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ вĐĩĐą-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐˇĐ°Ņ‚Đž ĐŋĐžŅĐ˛Đ¸ĐģŅŅ Starlette, ĐŊĐžĐ˛Đ°Ņ и ĐģŅƒŅ‡ŅˆĐ°Ņ ĐžŅĐŊОва Đ´ĐģŅ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐ¸Ņ ĐŋОдОйĐŊҋ҅ ŅĐ¸ŅŅ‚ĐĩĐŧ. -Đ­Ņ‚Đž ĐąŅ‹Đģа ĐŋĐžŅĐģĐĩĐ´ĐŊŅŅ ĐēаĐŋĐģŅ, ҁĐŋĐžĐ´Đ˛Đ¸ĐŗĐŊŅƒĐ˛ŅˆĐ°Ņ ĐŊа ŅĐžĐˇĐ´Đ°ĐŊиĐĩ **FastAPI**. +Đ—Đ°Ņ‚ĐĩĐŧ APIStar ĐŋĐĩŅ€ĐĩŅŅ‚Đ°Đģ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐē ҁĐĩŅ€Đ˛ĐĩŅ€, а ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ Starlette — ĐŊĐžĐ˛Đ°Ņ и ĐģŅƒŅ‡ŅˆĐ°Ņ ĐžŅĐŊОва Đ´ĐģŅ Ņ‚Đ°ĐēОК ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹. Đ­Ņ‚Đž ŅŅ‚Đ°ĐģĐž ĐžĐēĐžĐŊŅ‡Đ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ Đ˛Đ´ĐžŅ…ĐŊОвĐĩĐŊиĐĩĐŧ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ **FastAPI**. -Đ¯ ŅŅ‡Đ¸Ņ‚Đ°ŅŽ **FastAPI** "Đ´ŅƒŅ…ĐžĐ˛ĐŊŅ‹Đŧ ĐŋŅ€ĐĩĐĩĐŧĐŊиĐēĐžĐŧ" APIStar, ҃ĐģŅƒŅ‡Đ¸Đ˛ŅˆĐ¸Đŧ ĐĩĐŗĐž вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅƒŅ€ĐžĐēаĐŧ, иСвĐģĐĩ҇ґĐŊĐŊŅ‹Đŧ иС Đ˛ŅĐĩŅ… ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚Ņ‹Ņ… Đ˛Ņ‹ŅˆĐĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. +Đ¯ ŅŅ‡Đ¸Ņ‚Đ°ŅŽ **FastAPI** ÂĢĐ´ŅƒŅ…ĐžĐ˛ĐŊŅ‹Đŧ ĐŋŅ€ĐĩĐĩĐŧĐŊиĐēĐžĐŧÂģ APIStar, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҃ĐģŅƒŅ‡ŅˆĐ°ĐĩŅ‚ и Ņ€Đ°ŅŅˆĐ¸Ņ€ŅĐĩŅ‚ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, ŅĐ¸ŅŅ‚ĐĩĐŧ҃ Ņ‚Đ¸ĐŋОв и Đ´Ņ€ŅƒĐŗĐ¸Đĩ Ņ‡Đ°ŅŅ‚Đ¸, ĐžĐŋĐ¸Ņ€Đ°ŅŅŅŒ ĐŊа ŅƒŅ€ĐžĐēи ĐžŅ‚ Đ˛ŅĐĩŅ… ŅŅ‚Đ¸Ņ… ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. /// -## Đ§Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в **FastAPI** +## Đ§Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в **FastAPI** { #used-by-fastapi } -### Pydantic +### Pydantic { #pydantic } -Pydantic - ŅŅ‚Đž йийĐģĐ¸ĐžŅ‚ĐĩĐēа Đ´ĐģŅ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ JSON Schema), ĐžŅĐŊĐžĐ˛Ņ‹Đ˛Đ°ŅŅŅŒ ĐŊа ĐŋĐžĐ´ŅĐēаСĐēĐ°Ņ… Ņ‚Đ¸ĐŋОв Python, Ņ‡Ņ‚Đž Đ´ĐĩĐģаĐĩŅ‚ ĐĩĐŗĐž ҇ҀĐĩĐˇĐ˛Ņ‹Ņ‡Đ°ĐšĐŊĐž иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊŅ‹Đŧ. +Pydantic — ŅŅ‚Đž йийĐģĐ¸ĐžŅ‚ĐĩĐēа Đ´ĐģŅ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ (ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ JSON Schema) ĐŊа ĐžŅĐŊОвĐĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đš Ņ‚Đ¸ĐŋОв Python. -Đ•ĐŗĐž ĐŧĐžĐļĐŊĐž ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ ҁ Marshmallow, Ņ…ĐžŅ‚Ņ в ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēĐ°Ņ… Pydantic ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ, ҇ĐĩĐŧ Marshmallow. -И ĐžĐŊ ĐžŅĐŊОваĐŊ ĐŊа Ņ‚ĐĩŅ… ĐļĐĩ ĐŋĐžĐ´ŅĐēаСĐēĐ°Ņ… Ņ‚Đ¸ĐŋОв, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐž ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Đŧи ĐēОда. +БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃ ĐžĐŊ ҇ҀĐĩĐˇĐ˛Ņ‹Ņ‡Đ°ĐšĐŊĐž иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐĩĐŊ. -/// check | **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Pydantic +Đ•ĐŗĐž ĐŧĐžĐļĐŊĐž ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ ҁ Marshmallow. ĐĨĐžŅ‚Ņ в ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēĐ°Ņ… ĐžĐŊ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ Marshmallow. И ĐŋĐžŅĐēĐžĐģҌĐē҃ ĐžĐŊ ĐžŅĐŊОваĐŊ ĐŊа Ņ‚ĐĩŅ… ĐļĐĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŅ… Ņ‚Đ¸ĐŋОв Python, ĐŋОддĐĩŅ€ĐļĐēа в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ ĐēОда ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐ°Ņ. -ДĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅ и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŧОдĐĩĐģĐĩĐš (ĐŊа ĐžŅĐŊОвĐĩ JSON Schema). +/// check | **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐĩĐŗĐž Đ´ĐģŅ -Đ—Đ°Ņ‚ĐĩĐŧ **FastAPI** ĐąĐĩҀґ҂ ŅŅ‚Đ¸ ҁ҅ĐĩĐŧŅ‹ JSON и ĐŋĐžĐŧĐĩŅ‰Đ°ĐĩŅ‚ Đ¸Ņ… в ҁ҅ĐĩĐŧ҃ OpenAPI, ĐŊĐĩ ĐēĐ°ŅĐ°ŅŅŅŒ Đ´Ņ€ŅƒĐŗĐ¸Ņ… вĐĩ҉ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžĐŊ Đ´ĐĩĐģаĐĩŅ‚. +ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи Đ˛ŅĐĩĐš ваĐģĐ¸Đ´Đ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ даĐŊĐŊҋ҅ и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŧОдĐĩĐģĐĩĐš (ĐŊа ĐžŅĐŊОвĐĩ JSON Schema). + +Đ—Đ°Ņ‚ĐĩĐŧ **FastAPI** ĐąĐĩҀґ҂ ŅŅ‚Đ¸ даĐŊĐŊŅ‹Đĩ JSON Schema и ĐŋĐžĐŧĐĩŅ‰Đ°ĐĩŅ‚ Đ¸Ņ… в OpenAPI, ĐŋĐžĐŧиĐŧĐž Đ˛ŅĐĩŅ… ĐŋŅ€ĐžŅ‡Đ¸Ņ… Ņ„ŅƒĐŊĐēŅ†Đ¸Đš. /// -### Starlette +### Starlette { #starlette } -Starlette - ŅŅ‚Đž ĐģĐĩĐŗĐēОвĐĩҁĐŊŅ‹Đš ASGI ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē/ĐŊĐ°ĐąĐžŅ€ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš идĐĩаĐģĐĩĐŊ Đ´ĐģŅ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐ¸Ņ Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ ҁĐĩŅ€Đ˛Đ¸ŅĐžĐ˛. +Starlette — ŅŅ‚Đž ĐģŅ‘ĐŗĐēиК ASGI ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē/ĐŊĐ°ĐąĐžŅ€ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, идĐĩаĐģҌĐŊĐž ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰Đ¸Đš Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ asyncioâ€‘ŅĐĩŅ€Đ˛Đ¸ŅĐžĐ˛. -Starlette ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚ĐžĐš и иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊŅ‹Đš. -ОĐŊ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊ Ņ‚Đ°ĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐąŅ‹Ņ‚ŅŒ ĐģĐĩĐŗĐēĐž Ņ€Đ°ŅŅˆĐ¸Ņ€ŅĐĩĐŧŅ‹Đŧ и иĐŧĐĩŅ‚ŅŒ ĐŧĐžĐ´ŅƒĐģҌĐŊŅ‹Đĩ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊ҂ҋ. +ОĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚ĐžĐš и иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊŅ‹Đš. ĐĄĐŋŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊ Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ ĐĩĐŗĐž ĐąŅ‹ĐģĐž ĐģĐĩĐŗĐēĐž Ņ€Đ°ŅŅˆĐ¸Ņ€ŅŅ‚ŅŒ, и Ņ‡Ņ‚ĐžĐąŅ‹ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊ҂ҋ ĐąŅ‹Đģи ĐŧĐžĐ´ŅƒĐģҌĐŊŅ‹Đŧи. В ĐŊŅ‘Đŧ ĐĩŅŅ‚ŅŒ: * ВĐŋĐĩŅ‡Đ°Ņ‚ĐģŅŅŽŅ‰Đ°Ņ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. -* ПоддĐĩŅ€ĐļĐēа вĐĩĐą-ŅĐžĐēĐĩŅ‚ĐžĐ˛. -* ФОĐŊĐžĐ˛Ņ‹Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸. -* ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ŅĐžĐąŅ‹Ņ‚Đ¸Đš ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ и Ņ„Đ¸ĐŊĐ¸ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. -* ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đš ĐēĐģиĐĩĐŊŅ‚ ĐŊа ĐžŅĐŊОвĐĩ HTTPX. -* ПоддĐĩŅ€ĐļĐēа CORS, ҁĐļĐ°Ņ‚Đ¸Đĩ GZip, ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹, ĐŋĐžŅ‚ĐžĐēĐžĐ˛Đ°Ņ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ° даĐŊĐŊҋ҅. -* ПоддĐĩŅ€ĐļĐēа ҁĐĩŅŅĐ¸Đš и Đē҃Đēи. +* ПоддĐĩŅ€ĐļĐēа WebSocket. +* ФОĐŊĐžĐ˛Ņ‹Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸, Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩĐŧŅ‹Đĩ в Ņ‚ĐžĐŧ ĐļĐĩ ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ. +* ĐĄĐžĐąŅ‹Ņ‚Đ¸Ņ СаĐŋ҃ҁĐēа и СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ. +* ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đš ĐēĐģиĐĩĐŊŅ‚ ĐŊа йаСĐĩ HTTPX. +* CORS, GZip, ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹, ĐŋĐžŅ‚ĐžĐēĐžĐ˛Ņ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ. +* ПоддĐĩŅ€ĐļĐēа ҁĐĩŅŅĐ¸Đš и cookie. * 100% ĐŋĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи. -* 100% аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ĐēОд. -* НĐĩҁĐēĐžĐģҌĐēĐž Đļґҁ҂ĐēĐ¸Ņ… ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. +* 100% ĐēОдОвОК ĐąĐ°ĐˇŅ‹ ҁ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв. +* МаĐģĐž Đļґҁ҂ĐēĐ¸Ņ… ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. -В ĐŊĐ°ŅŅ‚ĐžŅŅ‰ĐĩĐĩ Đ˛Ņ€ĐĩĐŧŅ Starlette ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ ŅĐ°ĐŧŅƒŅŽ Đ˛Ņ‹ŅĐžĐēŅƒŅŽ ҁĐēĐžŅ€ĐžŅŅ‚ŅŒ ҁҀĐĩди Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв в Ņ‚ĐĩŅŅ‚ĐžĐ˛Ņ‹Ņ… СаĐŧĐĩŅ€Đ°Ņ…. -Đ‘Ņ‹ŅŅ‚Ņ€ĐĩĐĩ Ņ‚ĐžĐģҌĐēĐž Uvicorn, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ, а ĐŊĐĩ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ. +В ĐŊĐ°ŅŅ‚ĐžŅŅ‰ĐĩĐĩ Đ˛Ņ€ĐĩĐŧŅ Starlette — ŅĐ°ĐŧŅ‹Đš ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đš иС ĐŋŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв. Đ•ĐŗĐž ĐŋŅ€ĐĩĐ˛ĐžŅŅ…ĐžĐ´Đ¸Ņ‚ Ņ‚ĐžĐģҌĐēĐž Uvicorn, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŊĐĩ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, а ҁĐĩŅ€Đ˛ĐĩŅ€. -Starlette ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ вĐĩҁҌ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģ ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đēа, ĐŊĐž ĐŊĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ. +Starlette ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ вĐĩҁҌ ĐąĐ°ĐˇĐžĐ˛Ņ‹Đš Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģ вĐĩĐą-ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đēа. -**FastAPI** дОйавĐģŅĐĩŅ‚ ŅŅ‚Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв Python и Pydantic. -Đ•Ņ‰Ņ‘ **FastAPI** дОйавĐģŅĐĩŅ‚ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸ŅŽ ҁ҅ĐĩĐŧŅ‹ OpenAPI и Ņ‚.Đ´. +Но ĐžĐŊ ĐŊĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ иĐģи Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ. + +Đ­Ņ‚Đž ОдĐŊа иС ĐŗĐģавĐŊҋ҅ вĐĩ҉ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ **FastAPI** дОйавĐģŅĐĩŅ‚ ĐŋОвĐĩҀ҅, Đ˛ŅŅ‘ ĐŊа ĐžŅĐŊОвĐĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đš Ņ‚Đ¸ĐŋОв Python (ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Pydantic). ПĐģŅŽŅ ŅĐ¸ŅŅ‚ĐĩĐŧа вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš, ŅƒŅ‚Đ¸ĐģĐ¸Ņ‚Ņ‹ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Ņ ҁ҅ĐĩĐŧŅ‹ OpenAPI и Ņ‚. Đ´. /// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи -ASGI - ŅŅ‚Đž ĐŊĐžĐ˛Ņ‹Đš "ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚" Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊĐŊŅ‹Đš ŅƒŅ‡Đ°ŅŅ‚ĐŊиĐēаĐŧи ĐēĐžĐŧаĐŊĐ´Ņ‹ Django. -ОĐŊ ĐŋĐžĐēа Ņ‡Ņ‚Đž ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ "ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐŧ в Python" (Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐŋŅ€Đ¸ĐŊŅŅ‚Ņ‹Đŧ PEP), ĐŊĐž ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŋŅ€Đ¸ĐŊŅŅ‚Đ¸Ņ СаĐŋŅƒŅ‰ĐĩĐŊ. +ASGI — ŅŅ‚Đž ĐŊĐžĐ˛Ņ‹Đš ÂĢŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Âģ, Ņ€Đ°ĐˇŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩĐŧŅ‹Đš ŅƒŅ‡Đ°ŅŅ‚ĐŊиĐēаĐŧи core-ĐēĐžĐŧаĐŊĐ´Ņ‹ Django. ОĐŊ Đ˛ŅŅ‘ Đĩ҉ґ ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ÂĢŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐŧ PythonÂģ (PEP), Ņ…ĐžŅ‚Ņ ĐŋŅ€ĐžŅ†Đĩҁҁ Đ¸Đ´Ņ‘Ņ‚. -ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ ĐžĐŊ ҃ĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ "ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ°" ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи. -Đ­Ņ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž ҃ĐģŅƒŅ‡ŅˆĐ°ĐĩŅ‚ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐžŅŅ‚ŅŒ, ĐŋĐžŅĐēĐžĐģҌĐē҃ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ ҁ Uvicorn ĐŊа ĐģŅŽĐąĐžĐš Đ´Ņ€ŅƒĐŗĐžĐš ASGI-ҁĐĩŅ€Đ˛ĐĩŅ€ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Daphne иĐģи Hypercorn) иĐģи Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ASGI-ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, Ņ‚Đ°ĐēиĐĩ ĐēаĐē `python-socketio`. +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ ĐĩĐŗĐž ҃ĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ĐēаĐē ÂĢŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Âģ ĐŊĐĩҁĐēĐžĐģҌĐēĐž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. Đ­Ņ‚Đž ŅĐ¸ĐģҌĐŊĐž ҃ĐģŅƒŅ‡ŅˆĐ°ĐĩŅ‚ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐžŅŅ‚ŅŒ: Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŧĐĩĐŊĐ¸Ņ‚ŅŒ Uvicorn ĐŊа ĐģŅŽĐąĐžĐš Đ´Ņ€ŅƒĐŗĐžĐš ASGI-ҁĐĩŅ€Đ˛ĐĩŅ€ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Daphne иĐģи Hypercorn) иĐģи Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đĩ ҁ ASGI иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, Ņ‚Đ°ĐēиĐĩ ĐēаĐē `python-socketio`. /// -/// check | **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Starlette +/// check | **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐĩĐŗĐž Đ´ĐģŅ -В ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ŅĐ´Ņ€Đ° вĐĩĐą-ҁĐĩŅ€Đ˛Đ¸ŅĐ° Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи СаĐŋŅ€ĐžŅĐžĐ˛, дОйавив ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ŅĐ˛ĐĩŅ€Ņ…Ņƒ. +ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи Đ˛ŅĐĩŅ… ĐžŅĐŊОвĐŊҋ҅ вĐĩĐą-Ņ‡Đ°ŅŅ‚ĐĩĐš. ДобавĐģŅŅ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ĐŋОвĐĩҀ҅. -КĐģĐ°ŅŅ `FastAPI` ĐŊĐ°ŅĐģĐĩĐ´ŅƒĐĩŅ‚ŅŅ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ĐžŅ‚ ĐēĐģĐ°ŅŅĐ° `Starlette`. +КĐģĐ°ŅŅ `FastAPI` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ĐŊĐ°ŅĐģĐĩĐ´ŅƒĐĩŅ‚ŅŅ ĐžŅ‚ ĐēĐģĐ°ŅŅĐ° `Starlette`. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ˛ŅŅ‘ Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŧĐžĐŗĐģи Đ´ĐĩĐģĐ°Ņ‚ŅŒ ŅĐž Starlette, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐĩĐģĐ°Ņ‚ŅŒ ҁ **FastAPI**, ĐŋĐž ŅŅƒŅ‚Đ¸ ŅŅ‚Đž ĐŋŅ€ĐžĐēĐ°Ņ‡Đ°ĐŊĐŊŅ‹Đš Starlette. +ĐĸаĐē Ņ‡Ņ‚Đž Đ˛ŅŅ‘, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅĐž Starlette, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ҁ **FastAPI**, ĐŋĐž ŅŅƒŅ‚Đ¸ ŅŅ‚Đž ÂĢStarlette ĐŊа ҁ҂ĐĩŅ€ĐžĐ¸Đ´Đ°Ņ…Âģ. /// -### Uvicorn +### Uvicorn { #uvicorn } -Uvicorn - ŅŅ‚Đž ĐŧĐžĐģĐŊиĐĩĐŊĐžŅĐŊŅ‹Đš ASGI-ҁĐĩŅ€Đ˛ĐĩŅ€, ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đš ĐŊа uvloop и httptools. +Uvicorn — ĐŧĐžĐģĐŊиĐĩĐŊĐžŅĐŊŅ‹Đš ASGI-ҁĐĩŅ€Đ˛ĐĩŅ€, ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đš ĐŊа uvloop и httptools. -Uvicorn ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ, а ĐŊĐĩ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ. -НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐŊ ĐŊĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ СаĐŋŅ€ĐžŅĐžĐ˛ ĐŋĐž Ņ€ĐĩŅŅƒŅ€ŅĐ°Đŧ. -ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐŊ҃ĐļĐŊа ĐŊĐ°Đ´ŅŅ‚Ņ€ĐžĐšĐēа, Ņ‚Đ°ĐēĐ°Ņ ĐēаĐē Starlette (иĐģи **FastAPI**). +Đ­Ņ‚Đž ĐŊĐĩ вĐĩĐą-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, а ҁĐĩŅ€Đ˛ĐĩŅ€. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐŊ ĐŊĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Đ´ĐģŅ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ ĐŋĐž ĐŋŅƒŅ‚ŅĐŧ. Đ­Ņ‚Đž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ŅĐ˛ĐĩŅ€Ņ…Ņƒ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, Ņ‚Đ°ĐēОК ĐēаĐē Starlette (иĐģи **FastAPI**). -ОĐŊ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩŅ‚ŅŅ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Đ´ĐģŅ Starlette и **FastAPI**. +Đ­Ņ‚Đž Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩĐŧŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ Đ´ĐģŅ Starlette и **FastAPI**. -/// check | **FastAPI** Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩŅ‚ ĐĩĐŗĐž +/// check | **FastAPI** Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩŅ‚ ĐĩĐŗĐž ĐēаĐē -КаĐē ĐžŅĐŊОвĐŊОК ҁĐĩŅ€Đ˛ĐĩŅ€ Đ´ĐģŅ СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI**. +ĐžŅĐŊОвĐŊОК вĐĩĐą-ҁĐĩŅ€Đ˛ĐĩŅ€ Đ´ĐģŅ СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК **FastAPI**. -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠĐĩдиĐŊĐ¸Ņ‚ŅŒ ĐĩĐŗĐž ҁ Gunicorn, Ņ‡Ņ‚ĐžĐąŅ‹ иĐŧĐĩŅ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐŊĐžĐŗĐžĐŋŅ€ĐžŅ†ĐĩҁҁĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€. +ĐĸаĐēĐļĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ†Đ¸ŅŽ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--workers`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐŧĐŊĐžĐŗĐžĐŋŅ€ĐžŅ†ĐĩҁҁĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€. -ĐŖĐˇĐŊĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ Đ´ĐĩŅ‚Đ°ĐģĐĩĐš ĐŧĐžĐļĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ](deployment/index.md){.internal-link target=_blank}. +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ҁĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ [Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ](deployment/index.md){.internal-link target=_blank}. /// -## ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đĩ СаĐŧĐĩҀҋ и ҁĐēĐžŅ€ĐžŅŅ‚ŅŒ +## БĐĩĐŊ҇ĐŧĐ°Ņ€Đēи и ҁĐēĐžŅ€ĐžŅŅ‚ŅŒ { #benchmarks-and-speed } -Đ§Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŊŅŅ‚ŅŒ, ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ и ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Ņ€Đ°ĐˇĐŊĐ¸Ņ†Ņƒ ĐŧĐĩĐļĐ´Ņƒ Uvicorn, Starlette и FastAPI, ОСĐŊаĐēĐžĐŧŅŒŅ‚ĐĩҁҌ ҁ Ņ€Đ°ĐˇĐ´ĐĩĐģĐžĐŧ [ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đĩ СаĐŧĐĩҀҋ](benchmarks.md){.internal-link target=_blank}. +Đ§Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŊŅŅ‚ŅŒ, ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ и ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Ņ€Đ°ĐˇĐŊĐ¸Ņ†Ņƒ ĐŧĐĩĐļĐ´Ņƒ Uvicorn, Starlette и FastAPI, ҁĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ Đž [БĐĩĐŊ҇ĐŧĐ°Ņ€ĐēĐ°Ņ…](benchmarks.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/async.md b/docs/ru/docs/async.md index 6c5d982df..15d4e108a 100644 --- a/docs/ru/docs/async.md +++ b/docs/ru/docs/async.md @@ -1,18 +1,18 @@ -# КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ и async / await +# КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ и async / await { #concurrency-and-async-await } -ЗдĐĩҁҌ ĐŋŅ€Đ¸Đ˛ĐĩĐ´ĐĩĐŊа ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐ°Ņ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Ой Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° `async def` ĐŋŅ€Đ¸ ĐŊаĐŋĐ¸ŅĐ°ĐŊии *Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸*, а Ņ‚Đ°ĐēĐļĐĩ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€ĐĩĐŊŅ‹ ĐžŅĐŊĐžĐ˛Ņ‹ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚Đ¸ и ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа. +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ Đž ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐĩ `async def` Đ´ĐģŅ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đš-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв ĐŋŅƒŅ‚Đ¸* и ĐŊĐĩĐŧĐŊĐžĐŗĐž Ņ„ĐžĐŊа Ой Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŧ ĐēОдĐĩ, ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚Đ¸ и ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧĐĩ. -## НĐĩŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи? +## НĐĩŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи? { #in-a-hurry } -TL;DR: +TL;DR: -ДоĐŋŅƒŅŅ‚Đ¸Đŧ, Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ŅŅ‚ĐžŅ€ĐžĐŊŅŽŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ҂ҀĐĩĐąŅƒĐĩŅ‚ Đ˛Ņ‹ĐˇĐžĐ˛Đ° ҁ ĐēĐģŅŽŅ‡ĐĩĐ˛Ņ‹Đŧ ҁĐģОвОĐŧ `await`: +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ŅŅ‚ĐžŅ€ĐžĐŊĐŊиĐĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ҁ `await`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: ```Python results = await some_library() ``` -В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° `async def`: +ĐĸĐžĐŗĐ´Đ° ĐžĐąŅŠŅĐ˛ĐģŅĐšŅ‚Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸* ҁ `async def`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: ```Python hl_lines="2" @app.get('/') @@ -21,18 +21,15 @@ async def read_results(): return results ``` -/// note +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ -`await` ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊҋ҅ ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `async def`. +`await` ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊҋ҅ ҁ `async def`. /// --- -Đ•ŅĐģи Đ˛Ņ‹ ĐžĐąŅ€Đ°Ņ‰Đ°ĐĩŅ‚ĐĩҁҌ Đē ŅŅ‚ĐžŅ€ĐžĐŊĐŊĐĩĐš йийĐģĐ¸ĐžŅ‚ĐĩĐēĐĩ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ҁ ҇ĐĩĐŧ-Ņ‚Đž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ŅƒĐĩŅ‚ -(ҁ йаСОК даĐŊĐŊҋ҅, API, Ņ„Đ°ĐšĐģОвОК ŅĐ¸ŅŅ‚ĐĩĐŧОК и Ņ‚. Đ´.), и ĐŊĐĩ иĐŧĐĩĐĩŅ‚ ĐŋОддĐĩŅ€ĐļĐēи ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° `await` -(Ņ‡Ņ‚Đž ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ ҁĐĩĐšŅ‡Đ°Ņ Đē йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Ņƒ йийĐģĐ¸ĐžŅ‚ĐĩĐē Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ йаСаĐŧи даĐŊĐŊҋ҅), Ņ‚Đž -ĐžĐąŅŠŅĐ˛ĐģŅĐšŅ‚Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `def`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ŅŅ‚ĐžŅ€ĐžĐŊĐŊŅŽŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃, ĐēĐžŅ‚ĐžŅ€Đ°Ņ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ŅƒĐĩŅ‚ ҁ ҇ĐĩĐŧ-Ņ‚Đž (йаСа даĐŊĐŊҋ҅, API, Ņ„Đ°ĐšĐģĐžĐ˛Đ°Ņ ŅĐ¸ŅŅ‚ĐĩĐŧа и Ņ‚.Đ´.) и ĐŊĐĩ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `await` (ҁĐĩĐšŅ‡Đ°Ņ ŅŅ‚Đž ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Ņƒ йийĐģĐ¸ĐžŅ‚ĐĩĐē Đ´ĐģŅ БД), Ņ‚ĐžĐŗĐ´Đ° ĐžĐąŅŠŅĐ˛ĐģŅĐšŅ‚Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸* ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐž, ĐŋŅ€ĐžŅŅ‚Đž ҁ `def`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: ```Python hl_lines="2" @app.get('/') @@ -43,310 +40,283 @@ def results(): --- -Đ•ŅĐģи Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ (ŅŅ‚Ņ€Đ°ĐŊĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ) ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐŊи ҁ ҇ĐĩĐŧ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ и, ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ĐĩĐŊĐŊĐž, -ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚Đ°, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `async def`. +Đ•ŅĐģи Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ (ĐŋĐž ĐēаĐēОК-Ņ‚Đž ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊĐĩ) ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐŊи ҁ ҇ĐĩĐŧ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ и ĐļĐ´Đ°Ņ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚Đ°, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `async def`, даĐļĐĩ ĐĩҁĐģи вĐŊŅƒŅ‚Ņ€Đ¸ ĐŊĐĩ ĐŊ҃ĐļĐĩĐŊ `await`. --- -Đ•ŅĐģи Đ˛Ņ‹ ĐŊĐĩ ŅƒĐ˛ĐĩŅ€ĐĩĐŊŅ‹, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ `def`. +Đ•ŅĐģи Đ˛Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž ĐŊĐĩ ŅƒĐ˛ĐĩŅ€ĐĩĐŊŅ‹, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš `def`. --- -**ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ**: ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ ĐŧĐžĐļĐŊĐž ҁĐŧĐĩŅˆĐ¸Đ˛Đ°Ņ‚ŅŒ `def` и `async def` в *Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ… ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* -и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в ĐēаĐļĐ´ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŊаийОĐģĐĩĐĩ ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰Đ¸Đš ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ. А FastAPI ŅĐ´ĐĩĐģаĐĩŅ‚ ҁ ŅŅ‚Đ¸Đŧ Đ˛ŅŅ‘, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž. +**ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ**: Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҁĐŧĐĩŅˆĐ¸Đ˛Đ°Ņ‚ŅŒ `def` и `async def` в *Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ…-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐ°Ņ… ĐŋŅƒŅ‚Đ¸* ŅŅ‚ĐžĐģҌĐēĐž, ҁĐēĐžĐģҌĐēĐž ĐŊ҃ĐļĐŊĐž, и ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐēаĐļĐ´ŅƒŅŽ Ņ‚Đ°Đē, ĐēаĐē ĐģŅƒŅ‡ŅˆĐĩ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ҁĐģŅƒŅ‡Đ°Ņ. FastAPI ŅĐ´ĐĩĐģаĐĩŅ‚ ҁ ĐŊиĐŧи Đ˛ŅŅ‘ ĐēаĐē ĐŊадО. -В ĐģŅŽĐąĐžĐŧ иС ĐžĐŋĐ¸ŅĐ°ĐŊĐŊҋ҅ ҁĐģŅƒŅ‡Đ°Đĩв FastAPI Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐž и ĐžŅ‡ĐĩĐŊҌ ĐąŅ‹ŅŅ‚Ņ€Đž. +В ĐģŅŽĐąĐžĐŧ иС ҁĐģŅƒŅ‡Đ°Đĩв Đ˛Ņ‹ŅˆĐĩ FastAPI Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐž и ĐžŅ‡ĐĩĐŊҌ ĐąŅ‹ŅŅ‚Ņ€Đž. -ОдĐŊаĐēĐž ĐŋŅ€Đ¸Đ´ĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŅŅŒ ҃ĐēаСаĐŊĐŊҋ҅ ŅĐžĐ˛ĐĩŅ‚ĐžĐ˛, ĐŧĐžĐļĐŊĐž ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ ĐžĐŋŅ‚Đ¸ĐŧĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸. +Но ҁĐģĐĩĐ´ŅƒŅ ŅŅ‚Đ¸Đŧ ŅˆĐ°ĐŗĐ°Đŧ, ĐžĐŊ ҁĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžĐŋŅ‚Đ¸ĐŧĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸. -## ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ +## ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ { #technical-details } -ĐĄĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ Python ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đē҃ Ņ‚Đ°Đē ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧĐžĐŗĐž **"Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐēОда"** ĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐžĐŧ ĐŊаĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ **"ŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ"** ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° **`async` и `await`**. +ĐĄĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ Python ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ **ÂĢĐ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОдÂģ** ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **ÂĢŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧÂģ** (coroutines) и ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° **`async` и `await`**. -НиĐļĐĩ Ņ€Đ°ĐˇĐąĐĩҀґĐŧ ŅŅ‚Ņƒ Ņ„Ņ€Đ°ĐˇŅƒ ĐŋĐž Ņ‡Đ°ŅŅ‚ŅĐŧ: +РаСйĐĩҀґĐŧ ŅŅ‚Ņƒ Ņ„Ņ€Đ°ĐˇŅƒ ĐŋĐž Ņ‡Đ°ŅŅ‚ŅĐŧ в Ņ€Đ°ĐˇĐ´ĐĩĐģĐ°Ņ… ĐŊиĐļĐĩ: * **ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд** * **`async` и `await`** * **ĐĄĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹** -## ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд +## ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд { #asynchronous-code } -ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž в ŅĐˇŅ‹ĐēĐĩ đŸ’Ŧ ĐĩŅŅ‚ŅŒ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ŅĐžĐžĐąŅ‰Đ¸Ņ‚ŅŒ ĐŧĐ°ŅˆĐ¸ĐŊĐĩ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ 🤖, -Ņ‡Ņ‚Đž в ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊОК Ņ‚ĐžŅ‡ĐēĐĩ ĐēОда ĐĩĐš 🤖 ĐŊ҃ĐļĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ *҇ĐĩĐŗĐž-Ņ‚Đž Đĩ҉ґ* в Đ´Ņ€ŅƒĐŗĐžĐŧ ĐŧĐĩҁ҂Đĩ. ДоĐŋŅƒŅŅ‚Đ¸Đŧ ŅŅ‚Đž *Ņ‡Ņ‚Đž-Ņ‚Đž Đĩ҉ґ* ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ "ĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đš Ņ„Đ°ĐšĐģ" 📝. +ĐŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž в ŅĐˇŅ‹ĐēĐĩ đŸ’Ŧ ĐĩŅŅ‚ŅŒ ҁĐŋĐžŅĐžĐą ҁĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Ņƒ/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ 🤖, Ņ‡Ņ‚Đž в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐŧĐĩĐŊŅ‚ ĐēОда ĐĩĐŧ҃ 🤖 ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ, ĐŋĐžĐēа *Ņ‡Ņ‚Đž-Ņ‚Đž Đĩ҉ґ* ĐŗĐ´Đĩ-Ņ‚Đž в Đ´Ņ€ŅƒĐŗĐžĐŧ ĐŧĐĩҁ҂Đĩ СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŅ. ĐĐ°ĐˇĐžĐ˛Ņ‘Đŧ ŅŅ‚Đž *Ņ‡Ņ‚Đž-Ņ‚Đž Đĩ҉ґ* ÂĢĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đš Ņ„Đ°ĐšĐģÂģ 📝. -И ĐŋĐžĐēа ĐŧŅ‹ ĐļĐ´Ņ‘Đŧ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ "ĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đŧ Ņ„Đ°ĐšĐģĐžĐŧ" 📝, ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ ĐŧĐžĐļĐĩŅ‚ ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ Đ´ĐģŅ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐˇĐ°Đ´Đ°Ņ‡. +И ĐŋĐžĐēа ĐŧŅ‹ ĐļĐ´Ņ‘Đŧ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ÂĢĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đ¸ Ņ„Đ°ĐšĐģĐžĐŧÂģ 📝, ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ ĐŧĐžĐļĐĩŅ‚ СаĐŊŅŅ‚ŅŒŅŅ Đ´Ņ€ŅƒĐŗĐžĐš Ņ€Đ°ĐąĐžŅ‚ĐžĐš. -Но ĐŋŅ€Đ¸ ĐēаĐļдОК вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа 🤖 ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ ĐžĐąŅ€Đ°Ņ‚ĐŊĐž. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ĐžĐŊ 🤖 ĐžĐŋŅŅ‚ŅŒ ĐžĐēаĐļĐĩŅ‚ŅŅ в Ņ€ĐĩĐļиĐŧĐĩ ĐžĐļидаĐŊĐ¸Ņ, иĐģи ĐēĐžĐŗĐ´Đ° СаĐēĐžĐŊŅ‡Đ¸Ņ‚ Đ˛ŅŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ. В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ 🤖 ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚, ĐŊĐĩ СавĐĩŅ€ŅˆĐĩĐŊа Đģи ĐēаĐēĐ°Ņ-ĐŊĐ¸ĐąŅƒĐ´ŅŒ иС Ņ‚ĐĩĐēŅƒŅ‰Đ¸Ņ… ĐˇĐ°Đ´Đ°Ņ‡. +Đ—Đ°Ņ‚ĐĩĐŧ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа 🤖 ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ, ĐēĐžĐŗĐ´Đ° ĐŋĐžŅĐ˛Đ¸Ņ‚ŅŅ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ (ĐŋĐžĐēа ҁĐŊОва ĐŗĐ´Đĩ-Ņ‚Đž Đ¸Đ´Ņ‘Ņ‚ ĐžĐļидаĐŊиĐĩ), иĐģи ĐēĐžĐŗĐ´Đ° 🤖 СавĐĩŅ€ŅˆĐ¸Ņ‚ Đ˛ŅŅŽ Ņ‚ĐĩĐēŅƒŅ‰ŅƒŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ. И ĐžĐŊ 🤖 ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚, ĐŊĐĩ СавĐĩŅ€ŅˆĐ¸ĐģĐ°ŅŅŒ Đģи ĐēаĐēĐ°Ņ-ĐģийО иС ĐˇĐ°Đ´Đ°Ņ‡, ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžĐŊ ĐļдаĐģ, и ŅĐ´ĐĩĐģаĐĩŅ‚ Ņ‚Đž, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž. -ĐŸĐžŅ‚ĐžĐŧ ĐžĐŊ 🤖 ĐąĐĩҀґ҂ ĐŋĐĩŅ€Đ˛ŅƒŅŽ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐŊŅƒŅŽ ĐˇĐ°Đ´Đ°Ņ‡Ņƒ (Đ´ĐžĐŋŅƒŅŅ‚Đ¸Đŧ, ĐŊĐ°Ņˆ "ĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đš Ņ„Đ°ĐšĐģ" 📝) и ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Ņƒ, ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Ņ ҁ ĐŊĐĩĐš ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ. +ДаĐģĐĩĐĩ ĐžĐŊ 🤖 Đ˛ĐžĐˇŅŒĐŧґ҂ ĐŋĐĩŅ€Đ˛ŅƒŅŽ СавĐĩŅ€ŅˆĐ¸Đ˛ŅˆŅƒŅŽŅŅ ĐˇĐ°Đ´Đ°Ņ‡Ņƒ (ҁĐēаĐļĐĩĐŧ, ĐŊĐ°Ņˆ ÂĢĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đš Ņ„Đ°ĐšĐģÂģ 📝) и ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ Đ´ĐĩĐģĐ°Ņ‚ŅŒ ҁ ĐŊĐĩĐš Ņ‚Đž, Ņ‡Ņ‚Đž ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ. -Đ’Ņ‹ŅˆĐĩ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚ĐžĐĩ "Ņ‡Ņ‚Đž-Ņ‚Đž Đĩ҉ґ", СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž "ĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹Đŧ" ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧ I/O (ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ŅĐž ҁĐēĐžŅ€ĐžŅŅ‚ŅŒŅŽ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° и ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸), ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: +Đ­Ņ‚Đž ÂĢĐžĐļидаĐŊиĐĩ ҇ĐĩĐŗĐž-Ņ‚Đž Đĩ҉ґÂģ ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧ I/O, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž ÂĢĐŧĐĩĐ´ĐģĐĩĐŊĐŊŅ‹ĐĩÂģ (ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ŅĐž ҁĐēĐžŅ€ĐžŅŅ‚ŅŒŅŽ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° и ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸), ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐžĐļидаĐŊиĐĩ: -* ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēа даĐŊĐŊҋ҅ ĐžŅ‚ ĐēĐģиĐĩĐŊŅ‚Đ° ĐŋĐž ҁĐĩŅ‚Đ¸ -* ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ даĐŊĐŊҋ҅, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊҋ҅ Đ˛Đ°ŅˆĐĩĐš ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК ĐŋĐž ҁĐĩŅ‚Đ¸ -* ҇҂ĐĩĐŊиĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧОК ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž Ņ„Đ°ĐšĐģа ҁ Đ´Đ¸ŅĐēа и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ° ŅŅ‚Đ¸Ņ… даĐŊĐŊҋ҅ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ -* СаĐŋĐ¸ŅŅŒ ĐŊа Đ´Đ¸ŅĐē даĐŊĐŊҋ҅, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐŋĐĩŅ€ĐĩдаĐģа ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ -* ĐžĐąŅ€Đ°Ņ‰ĐĩĐŊиĐĩ Đē ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐžĐŧ҃ API -* ĐžĐļидаĐŊиĐĩ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ҁ йаСОК даĐŊĐŊҋ҅ -* ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ĐžĐ˛ СаĐŋŅ€ĐžŅĐ° Đē йаСĐĩ даĐŊĐŊҋ҅ -* и Ņ‚. Đ´. +* ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēи даĐŊĐŊҋ҅ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ ĐŋĐž ҁĐĩŅ‚Đ¸ +* ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ даĐŊĐŊҋ҅, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊҋ҅ Đ˛Đ°ŅˆĐĩĐš ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК ĐŋĐž ҁĐĩŅ‚Đ¸ +* ҇҂ĐĩĐŊĐ¸Ņ ŅĐ¸ŅŅ‚ĐĩĐŧОК ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž Ņ„Đ°ĐšĐģа ĐŊа Đ´Đ¸ŅĐēĐĩ и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ ŅŅ‚Đ¸Ņ… даĐŊĐŊҋ҅ Đ˛Đ°ŅˆĐĩĐš ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ +* СаĐŋĐ¸ŅĐ¸ ĐŊа Đ´Đ¸ŅĐē ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐŗĐž, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Đ°ŅˆĐ° ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐŋĐĩŅ€ĐĩдаĐģа ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ +* ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐžĐŗĐž API +* СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ +* Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‚Đ° Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ĐžĐ˛ СаĐŋŅ€ĐžŅĐ° Đē йаСĐĩ даĐŊĐŊҋ҅ +* и Ņ‚.Đ´. -ĐŸĐžŅĐēĐžĐģҌĐē҃ в ĐžŅĐŊОвĐŊĐžĐŧ Đ˛Ņ€ĐĩĐŧŅ Ņ‚Ņ€Đ°Ņ‚Đ¸Ņ‚ŅŅ ĐŊа ĐžĐļидаĐŊиĐĩ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš I/O, -Đ¸Ņ… ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧи, ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đŧи ҁĐēĐžŅ€ĐžŅŅ‚ŅŒŅŽ ввОда-Đ˛Ņ‹Đ˛ĐžĐ´Đ°. +ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐžŅĐŊОвĐŊĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ ŅƒŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа ĐžĐļидаĐŊиĐĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš I/O, Đ¸Ņ… ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧи, ÂĢĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đŧи ввОдОĐŧ-Đ˛Ņ‹Đ˛ĐžĐ´ĐžĐŧÂģ (I/O bound). -Код ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ "Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đŧ", ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Ņƒ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ ĐŊĐĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ "ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ" ҁ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊОК ĐˇĐ°Đ´Đ°Ņ‡ĐĩĐš и, -ĐąŅƒĐ´ŅƒŅ‡Đ¸ в ĐŋŅ€ĐžŅŅ‚ĐžĐĩ, ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ ĐŧĐžĐŧĐĩĐŊŅ‚Đ° ĐĩŅ‘ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ, ҁ Ņ‚ĐĩĐŧ Ņ‡Ņ‚ĐžĐąŅ‹ ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ и ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Ņƒ. +Đ­Ņ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ ÂĢĐ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹ĐŧÂģ, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Ņƒ/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ÂĢŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅÂģ ҁ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊОК ĐˇĐ°Đ´Đ°Ņ‡ĐĩĐš, ĐŋŅ€ĐžŅŅ‚Đ°Đ¸Đ˛Đ°Ņ и Đ˛Ņ‹ĐļĐ¸Đ´Đ°Ņ Ņ‚ĐžŅ‡ĐŊŅ‹Đš ĐŧĐžĐŧĐĩĐŊŅ‚ ĐĩŅ‘ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ и ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Ņƒ. -ВĐŧĐĩŅŅ‚Đž ŅŅ‚ĐžĐŗĐž в "Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊОК" ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ СавĐĩŅ€ŅˆŅ‘ĐŊĐŊĐ°Ņ ĐˇĐ°Đ´Đ°Ņ‡Đ° ĐŧĐžĐļĐĩŅ‚ ĐŊĐĩĐŧĐŊĐžĐŗĐž ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ (ĐąŅƒĐēваĐģҌĐŊĐž ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧиĐēŅ€ĐžŅĐĩĐē҃ĐŊĐ´), -ĐŋĐžĐēа ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа СаĐŊиĐŧаĐĩŅ‚ŅŅ Đ´Ņ€ŅƒĐŗĐ¸Đŧи ваĐļĐŊŅ‹Đŧи вĐĩŅ‰Đ°Đŧи, ҁ Ņ‚ĐĩĐŧ Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžŅ‚ĐžĐŧ вĐĩŅ€ĐŊŅƒŅ‚ŅŒŅŅ, -ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Ņ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ и ĐŊĐ°Ņ‡Đ°Ņ‚ŅŒ Đ¸Ņ… ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ. +ВĐŧĐĩŅŅ‚Đž ŅŅ‚ĐžĐŗĐž, в ÂĢĐ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊОКÂģ ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ, ҃ĐļĐĩ СавĐĩŅ€ŅˆĐ¸Đ˛ŅˆĐ°ŅŅŅ ĐˇĐ°Đ´Đ°Ņ‡Đ° ĐŧĐžĐļĐĩŅ‚ ĐŊĐĩĐŧĐŊĐžĐŗĐž ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ (ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧиĐēŅ€ĐžŅĐĩĐē҃ĐŊĐ´) в ĐžŅ‡ĐĩŅ€Đĩди, ĐŋĐžĐēа ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа СавĐĩŅ€ŅˆĐ¸Ņ‚ Ņ‚Đž, ҇ĐĩĐŧ СаĐŊиĐŧаĐģŅŅ, и ĐˇĐ°Ņ‚ĐĩĐŧ вĐĩŅ€ĐŊŅ‘Ņ‚ŅŅ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Ņ‹ и ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ ĐŊиĐŧи. -"ХиĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐĩ" Đ¸ŅĐŋĐžĐģĐŊĐĩĐŊиĐĩ (в ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐ˛Đĩҁ "Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŧ҃") Ņ‚Đ°ĐēĐļĐĩ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ "ĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ", -ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ Đ˛ŅĐĩ ҂ҀĐĩĐąŅƒĐĩĐŧŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ Đē ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐš ĐˇĐ°Đ´Đ°Ņ‡Đĩ, -даĐļĐĩ ĐĩҁĐģи в ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐļĐ´Đ°Ņ‚ŅŒ. +ДĐģŅ ÂĢŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐžÂģ (в ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊĐžŅŅ‚ŅŒ ÂĢĐ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŧ҃Âģ) Đ¸ŅĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ Ņ‚ĐĩŅ€ĐŧиĐŊ ÂĢĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊŅ‹ĐšÂģ, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ Đ˛ŅĐĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐž ĐŋĐžŅ€ŅĐ´Đē҃, ĐŋŅ€ĐĩĐļĐ´Đĩ ҇ĐĩĐŧ ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа Đ´Ņ€ŅƒĐŗŅƒŅŽ ĐˇĐ°Đ´Đ°Ņ‡Ņƒ, даĐļĐĩ ĐĩҁĐģи ŅŅ‚Đ¸ ŅˆĐ°ĐŗĐ¸ вĐēĐģŅŽŅ‡Đ°ŅŽŅ‚ ĐžĐļидаĐŊиĐĩ. -### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ и ĐąŅƒŅ€ĐŗĐĩҀҋ +### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ и ĐąŅƒŅ€ĐŗĐĩҀҋ { #concurrency-and-burgers } -ĐĸĐžŅ‚ **Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš** ĐēОд, Đž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ Đ¸Đ´Ņ‘Ņ‚ Ņ€ĐĩŅ‡ŅŒ Đ˛Ņ‹ŅˆĐĩ, иĐŊĐžĐŗĐ´Đ° ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **"ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ"**. ОĐŊа ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ **"ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа"**. +Đĸа идĐĩŅ **Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž** ĐēОда, ĐžĐŋĐ¸ŅĐ°ĐŊĐŊĐ°Ņ Đ˛Ņ‹ŅˆĐĩ, иĐŊĐžĐŗĐ´Đ° Ņ‚Đ°ĐēĐļĐĩ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ **ÂĢĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽÂģ**. ОĐŊа ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ **ÂĢĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧаÂģ**. -Да, **ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ** и **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ** ĐŋĐžĐ´Ņ€Đ°ĐˇŅƒĐŧĐĩĐ˛Đ°ŅŽŅ‚, Ņ‡Ņ‚Đž Ņ€Đ°ĐˇĐŊŅ‹Đĩ вĐĩŅ‰Đ¸ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´ŅŅ‚ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž в ОдĐŊĐž Đ˛Ņ€ĐĩĐŧŅ. +И **ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ**, и **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ** ĐžŅ‚ĐŊĐžŅŅŅ‚ŅŅ Đē ÂĢŅ€Đ°ĐˇĐŊŅ‹Đŧ вĐĩŅ‰Đ°Đŧ, ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´ŅŅ‰Đ¸Đŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžÂģ. -Но вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐĩ ŅƒŅŅ‚Ņ€ĐžĐšŅŅ‚Đ˛Đž **ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚Đ¸** и **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа** дОвОĐģҌĐŊĐž Ņ€Đ°ĐˇĐŊĐžĐĩ. +Но Ņ€Đ°ĐˇĐģĐ¸Ņ‡Đ¸Ņ ĐŧĐĩĐļĐ´Ņƒ *ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ* и *ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧĐžĐŧ* дОвОĐģҌĐŊĐž ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ. -Đ§Ņ‚ĐžĐąŅ‹ ŅŅ‚Đž ĐŋĐžĐŊŅŅ‚ŅŒ, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ Ņ‚Đ°ĐēŅƒŅŽ ĐēĐ°Ņ€Ņ‚Đ¸ĐŊ҃: +Đ§Ņ‚ĐžĐąŅ‹ Đ¸Ņ… ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ ҁĐģĐĩĐ´ŅƒŅŽŅ‰ŅƒŅŽ Đ¸ŅŅ‚ĐžŅ€Đ¸ŅŽ ĐŋŅ€Đž ĐąŅƒŅ€ĐŗĐĩҀҋ: -### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ +### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ { #concurrent-burgers } - +Đ’Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК Са Ņ„Đ°ŅŅ‚Ņ„ŅƒĐ´ĐžĐŧ, Đ˛Ņ‹ ŅŅ‚ĐžĐ¸Ņ‚Đĩ в ĐžŅ‡ĐĩŅ€Đĩди, ĐŋĐžĐēа ĐēĐ°ŅŅĐ¸Ņ€ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ СаĐēĐ°ĐˇŅ‹ ҃ ĐģŅŽĐ´ĐĩĐš ĐŋĐĩŅ€ĐĩĐ´ ваĐŧи. 😍 -Đ’Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 в Ņ„Đ°ŅŅ‚Ņ„ŅƒĐ´ 🍔 и ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ĐĩҁҌ в ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, в ŅŅ‚Đž Đ˛Ņ€ĐĩĐŧŅ ĐēĐ°ŅŅĐ¸Ņ€ 💁 ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ СаĐēĐ°ĐˇŅ‹ ҃ ĐŋĐžŅĐĩŅ‚Đ¸Ņ‚ĐĩĐģĐĩĐš ĐŋĐĩŅ€ĐĩĐ´ ваĐŧи. + -ĐšĐžĐŗĐ´Đ° ĐŊаĐēĐžĐŊĐĩ҆ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, Đ˛Ņ‹ СаĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŋĐ°Ņ€ĐžŅ‡Đē҃ ŅĐ°Đŧҋ҅ вĐē҃ҁĐŊҋ҅ и ĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊҋ҅ ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛ 🍔, ОдиĐŊ Đ´ĐģŅ ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍, а Đ´Ņ€ŅƒĐŗĐžĐš ҁĐĩĐąĐĩ. +НаĐēĐžĐŊĐĩ҆ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ: Đ˛Ņ‹ СаĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ 2 ĐžŅ‡ĐĩĐŊҌ ÂĢĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊҋ҅Âģ ĐąŅƒŅ€ĐŗĐĩŅ€Đ° — Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК и Đ´ĐģŅ ҁĐĩĐąŅ. 🍔🍔 -ĐžŅ‚Đ´Đ°Ņ‘Ņ‚Đĩ Đ´ĐĩĐŊŅŒĐŗĐ¸ 💸. + -ĐšĐ°ŅŅĐ¸Ņ€ 💁 Ņ‡Ņ‚Đž-Ņ‚Đž ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ ĐŋĐžĐ˛Đ°Ņ€Đ°Đŧ ĐŊа ĐēŅƒŅ…ĐŊĐĩ đŸ‘¨â€đŸŗ, Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐžĐŊи СĐŊĐ°ŅŽŅ‚, ĐēаĐēиĐĩ ĐąŅƒŅ€ĐŗĐĩҀҋ ĐŊ҃ĐļĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ŅŒ 🍔 -(ĐŊĐž ĐŋĐžĐēа ĐžĐŊи СаĐŊŅŅ‚Ņ‹ ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛). +ĐšĐ°ŅŅĐ¸Ņ€ ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Ņ‡Ņ‚Đž-Ņ‚Đž ĐŋĐžĐ˛Đ°Ņ€Ņƒ ĐŊа ĐēŅƒŅ…ĐŊĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊи СĐŊаĐģи, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ŅŒ Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ (Ņ…ĐžŅ‚Ņ ҁĐĩĐšŅ‡Đ°Ņ ĐžĐŊи ĐŗĐžŅ‚ĐžĐ˛ŅŅ‚ ĐąŅƒŅ€ĐŗĐĩҀҋ Đ´ĐģŅ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛). -ĐšĐ°ŅŅĐ¸Ņ€ 💁 ĐžŅ‚Đ´Đ°Ņ‘Ņ‚ ваĐŧ ҇ĐĩĐē ҁ ĐŊĐžĐŧĐĩŅ€ĐžĐŧ СаĐēаСа. + -В ĐžĐļидаĐŊии ĐĩĐ´Ņ‹ Đ˛Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ ŅŅ‚ĐžĐģиĐē, ŅĐ°Đ´Đ¸Ņ‚ĐĩҁҌ и дОвОĐģҌĐŊĐž ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ ĐžĐąŅ‰Đ°ĐĩŅ‚ĐĩҁҌ 😍 -(ĐŋĐžŅĐēĐžĐģҌĐē҃ Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ ŅĐ°ĐŧŅ‹Đĩ ĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊŅ‹Đĩ, ĐŗĐžŅ‚ĐžĐ˛ŅŅ‚ŅŅ ĐžĐŊи ĐŊĐĩ Ņ‚Đ°Đē ĐąŅ‹ŅŅ‚Ņ€Đž ✨🍔✨). +Đ’Ņ‹ ĐŋĐģĐ°Ņ‚Đ¸Ņ‚Đĩ. 💸 -ĐĄĐ¸Đ´Ņ Са ŅŅ‚ĐžĐģиĐēĐžĐŧ ҁ вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 в ĐžĐļидаĐŊии ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛ 🍔, Đ˛Ņ‹ ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐž ĐŋŅ€ĐžĐ˛ĐžĐ´Đ¸Ņ‚Đĩ Đ˛Ņ€ĐĩĐŧŅ, -Đ˛ĐžŅŅ…Đ¸Ņ‰Đ°ŅŅŅŒ ĐĩŅ‘ вĐĩĐģиĐēĐžĐģĐĩĐŋиĐĩĐŧ, ĐēŅ€Đ°ŅĐžŅ‚ĐžĐš и ҃ĐŧĐžĐŧ ✨😍✨. +ĐšĐ°ŅŅĐ¸Ņ€ Đ˛Ņ‹Đ´Đ°Ņ‘Ņ‚ ваĐŧ ĐŊĐžĐŧĐĩŅ€ Đ˛Đ°ŅˆĐĩĐš ĐžŅ‡ĐĩŅ€Đĩди. -Đ’ŅŅ‘ Đĩ҉ґ ĐžĐļĐ¸Đ´Đ°Ņ СаĐēаС и йОĐģŅ‚Đ°Ņ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍, Đ˛Ņ€ĐĩĐŧŅ ĐžŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи Đ˛Ņ‹ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚Đĩ, -ĐēаĐēОК ĐŊĐžĐŧĐĩŅ€ ĐŗĐžŅ€Đ¸Ņ‚ ĐŊад ĐŋŅ€Đ¸ĐģавĐēĐžĐŧ, и ĐŊĐĩ ĐŋĐžĐ´ĐžŅˆĐģа Đģи ҃ĐļĐĩ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ. + -И Đ˛ĐžŅ‚ ĐŊаĐēĐžĐŊĐĩ҆ ĐŊĐ°ŅŅ‚Đ°Ņ‘Ņ‚ ŅŅ‚ĐžŅ‚ ĐŧĐžĐŧĐĩĐŊŅ‚, и Đ˛Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ Đē ŅŅ‚ĐžĐšĐēĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔 и вĐĩŅ€ĐŊŅƒŅ‚ŅŒŅŅ Са ŅŅ‚ĐžĐģиĐē. +ПоĐēа Đ˛Ņ‹ ĐļĐ´Ņ‘Ņ‚Đĩ, Đ˛Ņ‹ вĐŧĐĩҁ҂Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК Đ¸Đ´Ņ‘Ņ‚Đĩ и Đ˛Ņ‹ĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ ŅŅ‚ĐžĐģиĐē, ŅĐ°Đ´Đ¸Ņ‚ĐĩҁҌ и Đ´ĐžĐģĐŗĐž йОĐģŅ‚Đ°ĐĩŅ‚Đĩ (Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ ĐžŅ‡ĐĩĐŊҌ ÂĢĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊŅ‹ĐĩÂģ, ĐŋĐžŅŅ‚ĐžĐŧ҃ иĐŧ ĐŊ҃ĐļĐŊĐž Đ˛Ņ€ĐĩĐŧŅ ĐŊа ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛ĐģĐĩĐŊиĐĩ). -Đ’Ņ‹ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 ĐĩĐ´Đ¸Ņ‚Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔 и ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐž ĐŋŅ€ĐžĐ˛ĐžĐ´Đ¸Ņ‚Đĩ Đ˛Ņ€ĐĩĐŧŅ ✨. +ĐĄĐ¸Đ´Ņ Са ŅŅ‚ĐžĐģиĐēĐžĐŧ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК в ĐžĐļидаĐŊии ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅŅ‚Đ¸ ŅŅ‚Đž Đ˛Ņ€ĐĩĐŧŅ, Đ˛ĐžŅŅ…Đ¸Ņ‰Đ°ŅŅŅŒ Ņ‚ĐĩĐŧ, ĐēаĐēĐ°Ņ ĐžĐŊа ĐēĐģĐ°ŅŅĐŊĐ°Ņ, ĐŧиĐģĐ°Ņ и ҃ĐŧĐŊĐ°Ņ ✨😍✨. + + + +ПоĐēа Đ˛Ņ‹ ĐļĐ´Ņ‘Ņ‚Đĩ и Ņ€Đ°ĐˇĐŗĐžĐ˛Đ°Ņ€Đ¸Đ˛Đ°ĐĩŅ‚Đĩ, Đ˛Ņ€ĐĩĐŧŅ ĐžŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи Đ˛Ņ‹ ĐŋĐžĐŗĐģŅĐ´Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŊа ĐŊĐžĐŧĐĩŅ€ ĐŊа Ņ‚Đ°ĐąĐģĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŊŅŅ‚ŅŒ, ĐŊĐĩ ĐŋĐžĐ´ĐžŅˆĐģа Đģи ҃ĐļĐĩ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ. + +И Đ˛ĐžŅ‚ в ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ ĐŊĐ°ŅŅ‚ŅƒĐŋаĐĩŅ‚. Đ’Ņ‹ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚Đĩ Đē ŅŅ‚ĐžĐšĐēĐĩ, ĐˇĐ°ĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ ŅĐ˛ĐžĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ĐĩҁҌ Đē ŅŅ‚ĐžĐģиĐē҃. + + + +Đ’Ņ‹ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК ĐĩĐ´Đ¸Ņ‚Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ и ĐžŅ‚ĐģĐ¸Ņ‡ĐŊĐž ĐŋŅ€ĐžĐ˛ĐžĐ´Đ¸Ņ‚Đĩ Đ˛Ņ€ĐĩĐŧŅ. ✨ + + + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐŸŅ€ĐĩĐēŅ€Đ°ŅĐŊŅ‹Đĩ иĐģĐģŅŽŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ ĐžŅ‚ Ketrina Thompson. 🎨 + +/// --- -А Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž в ŅŅ‚ĐžĐš ĐŊĐĩйОĐģŅŒŅˆĐžĐš Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ Đ˛Ņ‹ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа 🤖. +ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž в ŅŅ‚ĐžĐš Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ Đ˛Ņ‹ — ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа 🤖. -В ĐžŅ‡ĐĩŅ€Đĩди Đ˛Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž ĐŗĐģаСĐĩĐĩŅ‚Đĩ ĐŋĐž ŅŅ‚ĐžŅ€ĐžĐŊаĐŧ 😴, ĐļĐ´Ņ‘Ņ‚Đĩ и ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐžŅĐžĐąĐž "ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊĐžĐŗĐž" ĐŊĐĩ Đ´ĐĩĐģаĐĩŅ‚Đĩ. -Но ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ двиĐļĐĩŅ‚ŅŅ дОвОĐģҌĐŊĐž ĐąŅ‹ŅŅ‚Ņ€Đž, ĐŋĐžŅĐēĐžĐģҌĐē҃ ĐēĐ°ŅŅĐ¸Ņ€ 💁 Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ СаĐēĐ°ĐˇŅ‹ (а ĐŊĐĩ СаĐŊиĐŧаĐĩŅ‚ŅŅ ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛ĐģĐĩĐŊиĐĩĐŧ ĐĩĐ´Ņ‹), Ņ‚Đ°Đē Ņ‡Ņ‚Đž ĐŊĐ¸Ņ‡ĐĩĐŗĐž ŅŅ‚Ņ€Đ°ŅˆĐŊĐžĐŗĐž. +ПоĐēа Đ˛Ņ‹ ŅŅ‚ĐžĐ¸Ņ‚Đĩ в ĐžŅ‡ĐĩŅ€Đĩди, Đ˛Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž ĐąĐĩСдĐĩĐšŅŅ‚Đ˛ŅƒĐĩŅ‚Đĩ 😴, ĐļĐ´Ņ‘Ņ‚Đĩ ŅĐ˛ĐžĐĩĐš ĐžŅ‡ĐĩŅ€Đĩди и ĐŊĐĩ Đ´ĐĩĐģаĐĩŅ‚Đĩ ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐžŅĐžĐąĐž ÂĢĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊĐžĐŗĐžÂģ. Но ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ двиĐļĐĩŅ‚ŅŅ ĐąŅ‹ŅŅ‚Ņ€Đž, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēĐ°ŅŅĐ¸Ņ€ Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ СаĐēĐ°ĐˇŅ‹ (а ĐŊĐĩ ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ Đ¸Ņ…), Ņ‚Đ°Đē Ņ‡Ņ‚Đž ŅŅ‚Đž ĐŊĐžŅ€ĐŧаĐģҌĐŊĐž. -ĐšĐžĐŗĐ´Đ° ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ Đ˛Ņ‹ ĐŊаĐēĐžĐŊĐĩ҆ ĐŋŅ€ĐĩĐ´ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚Đĩ "ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊŅ‹Đĩ" Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ 🤓: ĐŋŅ€ĐžŅĐŧĐ°Ņ‚Ņ€Đ¸Đ˛Đ°ĐĩŅ‚Đĩ ĐŧĐĩĐŊŅŽ, Đ˛Ņ‹ĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ в ĐŊŅ‘Đŧ Ņ‡Ņ‚Đž-Ņ‚Đž, ŅƒĐˇĐŊĐ°Ņ‘Ņ‚Đĩ, Ņ‡Ņ‚Đž Ņ…ĐžŅ‡ĐĩŅ‚ Đ˛Đ°ŅˆĐ° вОСĐģŅŽĐąĐģĐĩĐŊĐŊĐ°Ņ 😍, ŅĐžĐąĐ¸Ņ€Đ°ĐĩŅ‚ĐĩҁҌ ĐžĐŋĐģĐ°Ņ‚Đ¸Ņ‚ŅŒ 💸, ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ, ĐēаĐēŅƒŅŽ Đ´ĐžŅŅ‚Đ°Đģи ĐēĐ°Ņ€Ņ‚Ņƒ, ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ҁ Đ˛Đ°Ņ ҁĐŋĐ¸ŅĐ°Đģи вĐĩŅ€ĐŊŅƒŅŽ ҁ҃ĐŧĐŧ҃, и Ņ‡Ņ‚Đž в СаĐēаСĐĩ Đ˛ŅŅ‘ вĐĩŅ€ĐŊĐž и Ņ‚. Đ´. +ĐšĐžĐŗĐ´Đ° ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, Đ˛Ņ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚Đĩ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ÂĢĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊŅƒŅŽÂģ Ņ€Đ°ĐąĐžŅ‚Ņƒ: ĐŋŅ€ĐžŅĐŧĐ°Ņ‚Ņ€Đ¸Đ˛Đ°ĐĩŅ‚Đĩ ĐŧĐĩĐŊŅŽ, Ņ€ĐĩŅˆĐ°ĐĩŅ‚Đĩ, ҇ĐĩĐŗĐž Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ Đ˛Ņ‹ĐąĐžŅ€ ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК, ĐŋĐģĐ°Ņ‚Đ¸Ņ‚Đĩ, ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž даĐģи ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊŅƒŅŽ Đē҃ĐŋŅŽŅ€Ņƒ/ĐēĐ°Ņ€Ņ‚Ņƒ, Ņ‡Ņ‚Đž ҁ҃ĐŧĐŧа ҁĐŋĐ¸ŅĐ°ĐŊа ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž, Ņ‡Ņ‚Đž в СаĐēаСĐĩ вĐĩŅ€ĐŊŅ‹Đĩ ĐŋĐžĐˇĐ¸Ņ†Đ¸Đ¸ и Ņ‚.Đ´. -И Ņ…ĐžŅ‚Ņ Đ˛Ņ‹ Đ˛ŅŅ‘ Đĩ҉ґ ĐŊĐĩ ĐŋĐžĐģŅƒŅ‡Đ¸Đģи ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔, Đ˛Đ°ŅˆĐ° Ņ€Đ°ĐąĐžŅ‚Đ° ҁ ĐēĐ°ŅŅĐ¸Ņ€ĐžĐŧ 💁 ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŅ "ĐŊа ĐŋĐ°ŅƒĐˇŅƒ" ⏸, -ĐŋĐžŅĐēĐžĐģҌĐē҃ Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐŊ҃ĐļĐŊĐž ĐļĐ´Đ°Ņ‚ŅŒ 🕙, ĐēĐžĐŗĐ´Đ° СаĐēаС ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛ŅŅ‚. +Но ĐˇĐ°Ņ‚ĐĩĐŧ, Ņ…ĐžŅ‚Ņ ҃ Đ˛Đ°Ņ Đĩ҉ґ ĐŊĐĩŅ‚ ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛, Đ˛Đ°ŅˆĐ° ÂĢŅ€Đ°ĐąĐžŅ‚Đ°Âģ ҁ ĐēĐ°ŅŅĐ¸Ņ€ĐžĐŧ ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊа ÂĢĐŊа ĐŋĐ°ŅƒĐˇŅƒÂģ ⏸, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ 🕙, ĐŋĐžĐēа ĐąŅƒŅ€ĐŗĐĩҀҋ ĐąŅƒĐ´ŅƒŅ‚ ĐŗĐžŅ‚ĐžĐ˛Ņ‹. -Но ĐžŅ‚ĐžĐšĐ´Ņ ҁ ĐŊĐžĐŧĐĩŅ€ĐēĐžĐŧ ĐžŅ‚ ĐŋŅ€Đ¸ĐģавĐēа, Đ˛Ņ‹ ŅĐ°Đ´Đ¸Ņ‚ĐĩҁҌ Са ŅŅ‚ĐžĐģиĐē и ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ 🔀 вĐŊиĐŧаĐŊиĐĩ -ĐŊа ŅĐ˛ĐžŅŽ вОСĐģŅŽĐąĐģĐĩĐŊĐŊŅƒŅŽ 😍 и "Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ" ⏯ 🤓 ҃ĐļĐĩ ĐŊад ŅŅ‚Đ¸Đŧ. И Đ˛ĐžŅ‚ Đ˛Ņ‹ ҁĐŊОва ĐžŅ‡ĐĩĐŊҌ -"ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊŅ‹" 🤓, ĐŧиĐģĐž йОĐģŅ‚Đ°ĐĩŅ‚Đĩ Đ˛Đ´Đ˛ĐžŅ‘Đŧ и Đ˛ŅŅ‘ Ņ‚Đ°ĐēĐžĐĩ 😍. +Но, ĐžŅ‚ĐžĐšĐ´Ņ ĐžŅ‚ ŅŅ‚ĐžĐšĐēи и ҁĐĩв Са ŅŅ‚ĐžĐģиĐē ҁ ĐŊĐžĐŧĐĩŅ€ĐēĐžĐŧ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ 🔀 вĐŊиĐŧаĐŊиĐĩ ĐŊа ŅĐ˛ĐžŅŽ вОСĐģŅŽĐąĐģĐĩĐŊĐŊŅƒŅŽ и ÂĢĐŋĐžŅ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒÂģ ⏯ 🤓 ĐŊад ŅŅ‚Đ¸Đŧ. ĐĄĐŊОва ĐžŅ‡ĐĩĐŊҌ ÂĢĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊĐžÂģ — Ņ„ĐģĐ¸Ņ€Ņ‚ ҁ Đ˛Đ°ŅˆĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍. -В ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ĐēĐ°ŅŅĐ¸Ņ€ 💁 ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ ĐŊа Ņ‚Đ°ĐąĐģĐž Đ˛Đ°Ņˆ ĐŊĐžĐŧĐĩŅ€, ĐŋĐžĐ´Ņ€Đ°ĐˇŅƒĐŧĐĩĐ˛Đ°Ņ, Ņ‡Ņ‚Đž ĐąŅƒŅ€ĐŗĐĩҀҋ ĐŗĐžŅ‚ĐžĐ˛Ņ‹ 🍔, ĐŊĐž Đ˛Ņ‹ ĐŊĐĩ ŅŅ‚Đ°ĐŊĐĩŅ‚Đĩ ĐŋĐžĐ´ŅĐēаĐēĐ¸Đ˛Đ°Ņ‚ŅŒ ĐēаĐē ҃ĐŧаĐģĐ¸ŅˆŅ‘ĐŊĐŊŅ‹Đš, ĐģĐ¸ŅˆŅŒ Ņ‚ĐžĐģҌĐēĐž ŅƒĐ˛Đ¸Đ´Đĩв ĐŊа ŅĐēŅ€Đ°ĐŊĐĩ ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ. Đ’Ņ‹ ŅƒĐ˛ĐĩŅ€ĐĩĐŊŅ‹, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔 ĐŊиĐēŅ‚Đž ĐŊĐĩ ŅƒŅ‚Đ°Ņ‰Đ¸Ņ‚, вĐĩĐ´ŅŒ ҃ Đ˛Đ°Ņ ŅĐ˛ĐžĐš ĐŊĐžĐŧĐĩŅ€ĐžĐē, а ҃ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ŅĐ˛ĐžĐš. +ĐŸĐžŅ‚ĐžĐŧ ĐēĐ°ŅŅĐ¸Ņ€ 💁 ÂĢĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚Âģ: ÂĢĐ¯ СаĐēĐžĐŊŅ‡Đ¸Đģ Đ´ĐĩĐģĐ°Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋÂģ, — Đ˛Ņ‹Đ˛ĐžĐ´Ņ Đ˛Đ°Ņˆ ĐŊĐžĐŧĐĩŅ€ ĐŊа Ņ‚Đ°ĐąĐģĐž, ĐŊĐž Đ˛Ņ‹ ĐŊĐĩ ĐŋОдĐŋŅ€Ņ‹ĐŗĐ¸Đ˛Đ°ĐĩŅ‚Đĩ ĐēаĐē ҁ҃ĐŧĐ°ŅŅˆĐĩĐ´ŅˆĐ¸Đš в Ņ‚Ņƒ ĐļĐĩ ҁĐĩĐē҃ĐŊĐ´Ņƒ, ĐēаĐē Ņ‚ĐžĐģҌĐēĐž ĐŊĐžĐŧĐĩŅ€ ҁĐŧĐĩĐŊиĐģŅŅ ĐŊа Đ˛Đ°Ņˆ. Đ’Ņ‹ СĐŊаĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ ĐŊиĐēŅ‚Đž ĐŊĐĩ ҃ĐēŅ€Đ°Đ´Ņ‘Ņ‚, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐŊĐžĐŧĐĩŅ€ Đ˛Đ°ŅˆĐĩĐš ĐžŅ‡ĐĩŅ€Đĩди, а ҃ Đ´Ņ€ŅƒĐŗĐ¸Ņ… — Đ¸Ņ…. -ĐŸĐžŅŅ‚ĐžĐŧ҃ Đ˛Ņ‹ ĐŋОдОĐļĐ´Ņ‘Ņ‚Đĩ, ĐŋĐžĐēа вОСĐģŅŽĐąĐģĐĩĐŊĐŊĐ°Ņ 😍 СаĐēĐžĐŊŅ‡Đ¸Ņ‚ Ņ€Đ°ŅŅĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ Đ¸ŅŅ‚ĐžŅ€Đ¸ŅŽ (СаĐēĐžĐŊŅ‡Đ¸Ņ‚Đĩ Ņ‚ĐĩĐēŅƒŅ‰ŅƒŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ ⏯ / ĐˇĐ°Đ´Đ°Ņ‡Ņƒ в ĐžĐąŅ€Đ°ĐąĐžŅ‚ĐēĐĩ 🤓), -и ĐŧиĐģĐž ҃ĐģŅ‹ĐąĐŊŅƒĐ˛ŅˆĐ¸ŅŅŒ, ҁĐēаĐļĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž Đ¸Đ´Ņ‘Ņ‚Đĩ ĐˇĐ°ĐąĐ¸Ņ€Đ°Ņ‚ŅŒ СаĐēаС ⏸. +ĐŸĐžŅŅ‚ĐžĐŧ҃ Đ˛Ņ‹ Đ´ĐžĐļидаĐĩŅ‚ĐĩҁҌ, ĐŋĐžĐēа Đ˛Đ°ŅˆĐ° вОСĐģŅŽĐąĐģĐĩĐŊĐŊĐ°Ņ СаĐēĐžĐŊŅ‡Đ¸Ņ‚ Đ¸ŅŅ‚ĐžŅ€Đ¸ŅŽ (СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŅ Ņ‚ĐĩĐēŅƒŅ‰Đ°Ņ Ņ€Đ°ĐąĐžŅ‚Đ° ⏯ / Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩĐŧĐ°Ņ ĐˇĐ°Đ´Đ°Ņ‡Đ° 🤓), ĐŧŅĐŗĐēĐž ҃ĐģŅ‹ĐąĐ°ĐĩŅ‚ĐĩҁҌ и ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ¸Đ´Ņ‘Ņ‚Đĩ Са ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи ⏸. -И Đ˛ĐžŅ‚ Đ˛Ņ‹ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚Đĩ Đē ŅŅ‚ĐžĐšĐēĐĩ 🔀, Đē ĐŋĐĩŅ€Đ˛ĐžĐŊĐ°Ņ‡Đ°ĐģҌĐŊОК ĐˇĐ°Đ´Đ°Ņ‡Đĩ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ҃ĐļĐĩ СавĐĩŅ€ŅˆĐĩĐŊа ⏯, ĐąĐĩҀґ҂Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔, ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚Đĩ ҁĐŋĐ°ŅĐ¸ĐąĐž и ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚Đĩ СаĐēаС Са ŅŅ‚ĐžĐģиĐē. На ŅŅ‚ĐžĐŧ СаĐēаĐŊŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ŅŅ ŅŅ‚Đ°Đŋ / ĐˇĐ°Đ´Đ°Ņ‡Đ° вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ҁ ĐēĐ°ŅŅĐžĐš ⏚. -В ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ ĐŋĐžŅ€ĐžĐļдаĐĩŅ‚ŅŅ ĐˇĐ°Đ´Đ°Ņ‡Đ° "ĐŋĐžĐĩдаĐŊиĐĩ ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛" 🔀 ⏯, ĐŊĐž ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ°Ņ ("ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛") СавĐĩŅ€ŅˆĐĩĐŊа ⏚. +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ Đē ŅŅ‚ĐžĐšĐēĐĩ 🔀, Đē Đ¸ŅŅ…ĐžĐ´ĐŊОК ĐˇĐ°Đ´Đ°Ņ‡Đĩ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Ņ‚ĐĩĐŋĐĩŅ€ŅŒ СавĐĩŅ€ŅˆĐĩĐŊа ⏯, ĐˇĐ°ĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ, ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Đ¸Ņ‚Đĩ и ĐŊĐĩҁґ҂Đĩ Đ¸Ņ… Đē ŅŅ‚ĐžĐģиĐē҃. На ŅŅ‚ĐžĐŧ ŅˆĐ°Đŗ/ĐˇĐ°Đ´Đ°Ņ‡Đ° вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ŅĐž ŅŅ‚ĐžĐšĐēОК СавĐĩŅ€ŅˆŅ‘ĐŊ ⏚. Đ­Ņ‚Đž, в ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ ĐŊĐžĐ˛ŅƒŅŽ ĐˇĐ°Đ´Đ°Ņ‡Ņƒ — ÂĢĐĩŅŅ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋÂģ 🔀 ⏯, ĐŊĐž ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ°Ņ ÂĢĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋÂģ — СавĐĩŅ€ŅˆĐĩĐŊа ⏚. -### ĐŸĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ +### ĐŸĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ { #parallel-burgers } -ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž вĐŧĐĩŅŅ‚Đž ĐąŅƒŅ€ĐŗĐĩŅ€ĐŊОК "КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ" Đ˛Ņ‹ Ņ€ĐĩŅˆĐ¸Đģи ŅŅ…ĐžĐ´Đ¸Ņ‚ŅŒ в "ĐŸĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ". +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛Đ¸Đŧ, Ņ‡Ņ‚Đž ŅŅ‚Đž ĐŊĐĩ ÂĢКоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋÂģ, а ÂĢĐŸĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋÂģ. -И Đ˛ĐžŅ‚ Đ˛Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 ĐžŅ‚Đ˛ĐĩĐ´Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐžĐŗĐž Ņ„Đ°ŅŅ‚Ņ„ŅƒĐ´Đ° 🍔. +Đ’Ņ‹ Đ¸Đ´Ņ‘Ņ‚Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК Са ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đŧ Ņ„Đ°ŅŅ‚Ņ„ŅƒĐ´ĐžĐŧ. -Đ’Ņ‹ ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ĐĩҁҌ в ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ ĐŋĐžĐēа ĐŊĐĩҁĐēĐžĐģҌĐēĐž (ĐŋŅƒŅŅ‚ŅŒ ĐąŅƒĐ´ĐĩŅ‚ 8) ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐž ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Ņ‚ĐĩĐģŅŒŅŅ‚Đ˛Ņƒ Đĩ҉ґ и ĐŋĐžĐ˛Đ°Ņ€Ņ‹ đŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗ, ĐŋŅ€Đ¸ĐŊиĐŧĐ°ŅŽŅ‚ СаĐēĐ°ĐˇŅ‹ ҃ ĐŋĐžŅĐĩŅ‚Đ¸Ņ‚ĐĩĐģĐĩĐš ĐŋĐĩŅ€ĐĩĐ´ ваĐŧи. +Đ’Ņ‹ ŅŅ‚ĐžĐ¸Ņ‚Đĩ в ĐžŅ‡ĐĩŅ€Đĩди, ĐŋĐžĐēа ĐŊĐĩҁĐēĐžĐģҌĐēĐž (ҁĐēаĐļĐĩĐŧ, 8) ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž ŅĐ˛ĐģŅŅŽŅ‚ŅŅ ĐŋĐžĐ˛Đ°Ņ€Đ°Đŧи, ĐŋŅ€Đ¸ĐŊиĐŧĐ°ŅŽŅ‚ СаĐēĐ°ĐˇŅ‹ ҃ ĐģŅŽĐ´ĐĩĐš ĐŋĐĩŅ€ĐĩĐ´ ваĐŧи. -ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐēĐģиĐĩĐŊ҂ҋ ĐŊĐĩ ĐžŅ‚Ņ…ĐžĐ´ŅŅ‚ ĐžŅ‚ ŅŅ‚ĐžĐšĐēи и ĐļĐ´ŅƒŅ‚ 🕙 ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ĐĩĐ´Ņ‹, ĐŋĐžŅĐēĐžĐģҌĐē҃ ĐēаĐļĐ´Ņ‹Đš -иС 8 ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛ Đ¸Đ´Ņ‘Ņ‚ ĐŊа ĐēŅƒŅ…ĐŊŅŽ ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔, а Ņ‚ĐžĐģҌĐēĐž ĐŋĐžŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đš СаĐēаС. +Đ’ŅĐĩ ĐŋĐĩŅ€ĐĩĐ´ ваĐŧи ĐļĐ´ŅƒŅ‚, ĐŋĐžĐēа Đ¸Ņ… ĐąŅƒŅ€ĐŗĐĩҀҋ ĐąŅƒĐ´ŅƒŅ‚ ĐŗĐžŅ‚ĐžĐ˛Ņ‹, ĐŊĐĩ ĐžŅ‚Ņ…ĐžĐ´Ņ ĐžŅ‚ ŅŅ‚ĐžĐšĐēи, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐēаĐļĐ´Ņ‹Đš иС 8 ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛ ŅŅ€Đ°ĐˇŅƒ Đ¸Đ´Ņ‘Ņ‚ ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩŅ€ ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŋŅ€Đ¸ĐŊŅŅ‚ŅŒ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đš СаĐēаС. -НаĐēĐžĐŊĐĩ҆ ĐŊĐ°ŅŅ‚Đ°Ņ‘Ņ‚ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, и Đ˛Ņ‹ ĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ два ŅĐ°Đŧҋ҅ ĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊҋ҅ ĐąŅƒŅ€ĐŗĐĩŅ€Đ° 🍔, ОдиĐŊ Đ´ĐģŅ даĐŧŅ‹ ҁĐĩŅ€Đ´Ņ†Đ° 😍, а Đ´Ņ€ŅƒĐŗĐžĐš ҁĐĩĐąĐĩ. + -Ни Đž ҇ґĐŧ ĐŊĐĩ ĐļаĐģĐĩŅ, Ņ€Đ°ŅĐŋĐģĐ°Ņ‡Đ¸Đ˛Đ°ĐĩŅ‚ĐĩҁҌ 💸. +НаĐēĐžĐŊĐĩ҆ Đ˛Đ°ŅˆĐ° ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ: Đ˛Ņ‹ СаĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ 2 ĐžŅ‡ĐĩĐŊҌ ÂĢĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊҋ҅Âģ ĐąŅƒŅ€ĐŗĐĩŅ€Đ° — Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК и Đ´ĐģŅ ҁĐĩĐąŅ. -И ĐēĐ°ŅŅĐ¸Ņ€ ŅƒŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа ĐēŅƒŅ…ĐŊŅŽ đŸ‘¨â€đŸŗ. +Đ’Ņ‹ ĐŋĐģĐ°Ņ‚Đ¸Ņ‚Đĩ 💸. -ВаĐŧ ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐļĐ´Đ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐ´ ŅŅ‚ĐžĐšĐēОК 🕙, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊиĐēŅ‚Đž ĐŋĐž ҁĐģŅƒŅ‡Đ°ĐšĐŊĐžŅŅ‚Đ¸ ĐŊĐĩ ĐˇĐ°ĐąŅ€Đ°Đģ Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔, вĐĩĐ´ŅŒ ĐŊиĐēаĐēĐ¸Ņ… ĐŊĐžĐŧĐĩŅ€ĐēОв ҃ Đ˛Đ°Ņ ĐŊĐĩŅ‚. + -ĐŸĐžŅĐēĐžĐģҌĐē҃ Đ˛Ņ‹ ҁ вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ СаĐēаС Đ˛ĐžĐ˛Ņ€ĐĩĐŧŅ 🕙, и ҁĐģĐĩĐ´Đ¸Ņ‚Đĩ Са Ņ‚ĐĩĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊиĐēŅ‚Đž ĐŊĐĩ вĐēĐģиĐŊиĐģŅŅ в ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, -҃ Đ˛Đ°Ņ ĐŊĐĩ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ŅŅ ŅƒĐ´ĐĩĐģŅŅ‚ŅŒ Đ´ĐžĐģĐļĐŊĐžĐŗĐž вĐŊиĐŧаĐŊиĐĩ ŅĐ˛ĐžĐĩĐš даĐŧĐĩ ҁĐĩŅ€Đ´Ņ†Đ° 😞. +ĐšĐ°ŅŅĐ¸Ņ€ ŅƒŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа ĐēŅƒŅ…ĐŊŅŽ. -Đ­Ņ‚Đž "ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐ°Ņ" Ņ€Đ°ĐąĐžŅ‚Đ°, Đ˛Ņ‹ "ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹" ҁ ĐēĐ°ŅŅĐ¸Ņ€ĐžĐŧ/ĐŋĐžĐ˛Đ°Ņ€ĐžĐŧ đŸ‘¨â€đŸŗ. ĐŸŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐļĐ´Đ°Ņ‚ŅŒ 🕙 ҃ ŅŅ‚ĐžĐšĐēи, -ĐēĐžĐŗĐ´Đ° ĐēĐ°ŅŅĐ¸Ņ€/ĐŋĐžĐ˛Đ°Ņ€ đŸ‘¨â€đŸŗ СаĐēĐžĐŊŅ‡Đ¸Ņ‚ Đ´ĐĩĐģĐ°Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋ 🍔 и Đ˛Ņ€ŅƒŅ‡Đ¸Ņ‚ ваĐŧ СаĐēаС, иĐŊĐ°Ņ‡Đĩ ĐĩĐŗĐž ҁĐģŅƒŅ‡Đ°ĐšĐŊĐž ĐŧĐžĐļĐĩŅ‚ ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ ĐēŅ‚Đž-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐžĐš. +Đ’Ņ‹ ĐļĐ´Ņ‘Ņ‚Đĩ, ŅŅ‚ĐžŅ ҃ ŅŅ‚ĐžĐšĐēи 🕙, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊиĐēŅ‚Đž ĐŊĐĩ ĐˇĐ°ĐąŅ€Đ°Đģ Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ Ņ€Đ°ĐŊҌ҈Đĩ Đ˛Đ°Ņ, Ņ‚Đ°Đē ĐēаĐē ĐŊиĐēаĐēĐ¸Ņ… ĐŊĐžĐŧĐĩŅ€ĐēОв ĐŊĐĩŅ‚. -НаĐēĐžĐŊĐĩ҆ ĐēĐ°ŅŅĐ¸Ņ€/ĐŋĐžĐ˛Đ°Ņ€ đŸ‘¨â€đŸŗ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ ҁ ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи 🍔 ĐŋĐžŅĐģĐĩ ĐŊĐĩĐ˛Ņ‹ĐŊĐžŅĐ¸ĐŧĐž Đ´ĐžĐģĐŗĐžĐŗĐž ĐžĐļидаĐŊĐ¸Ņ 🕙 Са ŅŅ‚ĐžĐšĐēОК. + -Đ’Ņ‹ ҁĐēĐžŅ€ĐĩĐĩ ĐˇĐ°ĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ СаĐēаС 🍔 и Đ¸Đ´Ņ‘Ņ‚Đĩ ҁ вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 Са ŅŅ‚ĐžĐģиĐē. +ĐĸаĐē ĐēаĐē Đ˛Ņ‹ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК СаĐŊŅŅ‚Ņ‹ Ņ‚ĐĩĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊиĐēŅ‚Đž ĐŊĐĩ Đ˛ŅŅ‚Đ°Đģ ĐŋĐĩŅ€ĐĩĐ´ ваĐŧи и ĐŊĐĩ ĐˇĐ°ĐąŅ€Đ°Đģ Đ˛Đ°ŅˆĐ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ, ĐēаĐē Ņ‚ĐžĐģҌĐēĐž ĐžĐŊи ĐŋĐžŅĐ˛ŅŅ‚ŅŅ, Đ˛Ņ‹ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒĐ´ĐĩĐģĐ¸Ņ‚ŅŒ вĐŊиĐŧаĐŊиĐĩ ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК. 😞 -ĐĸаĐŧ Đ˛Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž ĐĩĐ´Đ¸Ņ‚Đĩ ŅŅ‚Đ¸ ĐąŅƒŅ€ĐŗĐĩҀҋ, и ĐŊа ŅŅ‚ĐžĐŧ Đ˛ŅŅ‘ 🍔 ⏚. +Đ­Ņ‚Đž ÂĢŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐ°ŅÂģ Ņ€Đ°ĐąĐžŅ‚Đ°, Đ˛Ņ‹ ÂĢŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹Âģ ҁ ĐēĐ°ŅŅĐ¸Ņ€ĐžĐŧ/ĐŋĐžĐ˛Đ°Ņ€ĐžĐŧ đŸ‘¨â€đŸŗ. ВаĐŧ ĐŊ҃ĐļĐŊĐž ĐļĐ´Đ°Ņ‚ŅŒ 🕙 и ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŒŅŅ Ņ‚Đ°Đŧ в Ņ‚ĐžŅ‡ĐŊŅ‹Đš ĐŧĐžĐŧĐĩĐŊŅ‚, ĐēĐžĐŗĐ´Đ° ĐēĐ°ŅŅĐ¸Ņ€/ĐŋĐžĐ˛Đ°Ņ€ đŸ‘¨â€đŸŗ СаĐēĐžĐŊŅ‡Đ¸Ņ‚ ĐąŅƒŅ€ĐŗĐĩҀҋ и Đ˛Ņ€ŅƒŅ‡Đ¸Ņ‚ Đ¸Ņ… ваĐŧ, иĐŊĐ°Ņ‡Đĩ Đ¸Ņ… ĐŧĐžĐļĐĩŅ‚ ĐˇĐ°ĐąŅ€Đ°Ņ‚ŅŒ ĐēŅ‚Đž-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐžĐš. -ВаĐŧ ĐŊĐĩ ĐžŅĐžĐąĐž ŅƒĐ´Đ°ĐģĐžŅŅŒ ĐŋĐžĐžĐąŅ‰Đ°Ņ‚ŅŒŅŅ, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž йОĐģŅŒŅˆŅƒŅŽ Ņ‡Đ°ŅŅ‚ŅŒ Đ˛Ņ€ĐĩĐŧĐĩĐŊи 🕙 ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐŋŅ€ĐžĐ˛ĐĩŅŅ‚Đ¸ ҃ ĐēĐ°ŅŅŅ‹ 😞. + + +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Đ°Ņˆ ĐēĐ°ŅŅĐ¸Ņ€/ĐŋĐžĐ˛Đ°Ņ€ đŸ‘¨â€đŸŗ ĐŊаĐēĐžĐŊĐĩ҆ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ŅŅ ҁ Đ˛Đ°ŅˆĐ¸Đŧи ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи, ĐŋĐžŅĐģĐĩ Đ´ĐžĐģĐŗĐžĐŗĐž ĐžĐļидаĐŊĐ¸Ņ 🕙 ҃ ŅŅ‚ĐžĐšĐēи. + + + +Đ’Ņ‹ ĐąĐĩҀґ҂Đĩ ĐąŅƒŅ€ĐŗĐĩҀҋ и Đ¸Đ´Ņ‘Ņ‚Đĩ ŅĐž ŅĐ˛ĐžĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК Đē ŅŅ‚ĐžĐģиĐē҃. + +Đ’Ņ‹ ĐŋŅ€ĐžŅŅ‚Đž Đ¸Ņ… ҁҊĐĩдаĐĩŅ‚Đĩ — и Đ˛ŅŅ‘. ⏚ + + + +Đ Đ°ĐˇĐŗĐžĐ˛ĐžŅ€ĐžĐ˛ и Ņ„ĐģĐ¸Ņ€Ņ‚Đ° ĐąŅ‹ĐģĐž ĐŊĐĩĐŧĐŊĐžĐŗĐž, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž йОĐģŅŒŅˆŅƒŅŽ Ņ‡Đ°ŅŅ‚ŅŒ Đ˛Ņ€ĐĩĐŧĐĩĐŊи Đ˛Ņ‹ ĐļдаĐģи 🕙 ҃ ŅŅ‚ĐžĐšĐēи. 😞 + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐŸŅ€ĐĩĐēŅ€Đ°ŅĐŊŅ‹Đĩ иĐģĐģŅŽŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ ĐžŅ‚ Ketrina Thompson. 🎨 + +/// --- -В ĐžĐŋĐ¸ŅĐ°ĐŊĐŊĐžĐŧ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸ Đ˛Ņ‹ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ / ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа 🤖 ҁ Đ´Đ˛ŅƒĐŧŅ Đ¸ŅĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģŅĐŧи (Đ˛Ņ‹ и Đ˛Đ°ŅˆĐ° вОСĐģŅŽĐąĐģĐĩĐŊĐŊĐ°Ņ 😍), -ĐŊа ĐŋŅ€ĐžŅ‚ŅĐļĐĩĐŊии Đ´ĐžĐģĐŗĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи 🕙 Đ˛Ņ‹ Ойа ŅƒĐ´ĐĩĐģŅĐĩŅ‚Đĩ Đ˛ŅŅ‘ вĐŊиĐŧаĐŊиĐĩ ⏯ ĐˇĐ°Đ´Đ°Ņ‡Đĩ "ĐļĐ´Đ°Ņ‚ŅŒ ĐŊа ĐēĐ°ŅŅĐĩ". +В ŅŅ‚ĐžĐŧ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸ ÂĢĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊҋ҅ ĐąŅƒŅ€ĐŗĐĩŅ€ĐžĐ˛Âģ Đ˛Ņ‹ — ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа 🤖 ҁ Đ´Đ˛ŅƒĐŧŅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°Đŧи (Đ˛Ņ‹ и Đ˛Đ°ŅˆĐ° вОСĐģŅŽĐąĐģĐĩĐŊĐŊĐ°Ņ), Ойа ĐļĐ´ŅƒŅ‚ 🕙 и ŅƒĐ´ĐĩĐģŅŅŽŅ‚ вĐŊиĐŧаĐŊиĐĩ ⏯ Ņ‚ĐžĐŧ҃, Ņ‡Ņ‚ĐžĐąŅ‹ ÂĢĐļĐ´Đ°Ņ‚ŅŒ ҃ ŅŅ‚ĐžĐšĐēиÂģ 🕙 Đ´ĐžĐģĐŗĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ. -В ŅŅ‚ĐžĐŧ Ņ€ĐĩŅŅ‚ĐžŅ€Đ°ĐŊĐĩ ĐąŅ‹ŅŅ‚Ņ€ĐžĐŗĐž ĐŋĐ¸Ņ‚Đ°ĐŊĐ¸Ņ 8 Đ¸ŅĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģĐĩĐš (ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛/ĐŋĐžĐ˛Đ°Ņ€ĐžĐ˛) đŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗ. -ĐĨĐžŅ‚Ņ в ĐąŅƒŅ€ĐŗĐĩŅ€ĐŊОК ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžĐŗĐž Ņ‚Đ¸Đŋа ĐąŅ‹ĐģĐž Đ˛ŅĐĩĐŗĐž два (ОдиĐŊ ĐēĐ°ŅŅĐ¸Ņ€ и ОдиĐŊ ĐŋĐžĐ˛Đ°Ņ€) 💁 đŸ‘¨â€đŸŗ. +В Ņ€ĐĩŅŅ‚ĐžŅ€Đ°ĐŊĐĩ 8 ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐžĐ˛ (ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛/ĐŋĐžĐ˛Đ°Ņ€ĐžĐ˛). ĐĸĐžĐŗĐ´Đ° ĐēаĐē в ÂĢĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊҋ҅ ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Ņ…Âģ ĐŧĐžĐŗĐģĐž ĐąŅ‹Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž 2 (ОдиĐŊ ĐēĐ°ŅŅĐ¸Ņ€ и ОдиĐŊ ĐŋĐžĐ˛Đ°Ņ€). -НĐĩҁĐŧĐžŅ‚Ņ€Ņ ĐŊа ОйиĐģиĐĩ Ņ€Đ°ĐąĐžŅ‚ĐŊиĐēОв, ĐžĐŋҋ҂ в Đ¸Ņ‚ĐžĐŗĐĩ ĐŋĐžĐģŅƒŅ‡Đ¸ĐģŅŅ ĐŊĐĩ иС ĐģŅƒŅ‡ŅˆĐ¸Ņ… 😞. +И Đ˛ŅŅ‘ ĐļĐĩ Ņ„Đ¸ĐŊаĐģҌĐŊŅ‹Đš ĐžĐŋҋ҂ — ĐŊĐĩ ŅĐ°ĐŧŅ‹Đš ĐģŅƒŅ‡ŅˆĐ¸Đš. 😞 --- -ĐĸаĐē ĐąŅ‹ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩĐģ аĐŊаĐģĐžĐŗ Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ ĐŋŅ€Đž ĐąŅƒŅ€ĐŗĐĩŅ€ĐŊŅƒŅŽ 🍔 в "ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐžĐŧ" ĐŧĐ¸Ņ€Đĩ. +Đ­Ņ‚Đž ĐąŅ‹Đģа ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐ°Ņ вĐĩŅ€ŅĐ¸Ņ Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ ĐŋŅ€Đž ĐąŅƒŅ€ĐŗĐĩҀҋ. 🍔 -Đ’ĐžŅ‚ йОĐģĐĩĐĩ Ņ€ĐĩаĐģĐ¸ŅŅ‚Đ¸Ņ‡ĐŊŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€. ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ ҁĐĩĐąĐĩ йаĐŊĐē. +ДĐģŅ йОĐģĐĩĐĩ ÂĢĐļиСĐŊĐĩĐŊĐŊĐžĐŗĐžÂģ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ йаĐŊĐē. -До ĐŊĐĩдавĐŊĐ¸Ņ… ĐŋĐžŅ€ в йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ йаĐŊĐēОв ĐąŅ‹ĐģĐž ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛ 👨‍đŸ’ŧ👨‍đŸ’ŧ👨‍đŸ’ŧ👨‍đŸ’ŧ и Đ´ĐģиĐŊĐŊŅ‹Đĩ ĐžŅ‡ĐĩŅ€Đĩди 🕙🕙🕙🕙🕙🕙🕙🕙. +До ĐŊĐĩдавĐŊĐĩĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи в йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ йаĐŊĐēОв ĐąŅ‹ĐģĐž ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛ 👨‍đŸ’ŧ👨‍đŸ’ŧ👨‍đŸ’ŧ👨‍đŸ’ŧ и Đ´ĐģиĐŊĐŊĐ°Ņ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ 🕙🕙🕙🕙🕙🕙🕙🕙. -КаĐļĐ´Ņ‹Đš ĐēĐ°ŅŅĐ¸Ņ€ ĐžĐąŅĐģ҃ĐļиваĐģ ОдĐŊĐžĐŗĐž ĐēĐģиĐĩĐŊŅ‚Đ°, ĐŋĐžŅ‚ĐžĐŧ ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŗĐž 👨‍đŸ’ŧ⏯. +Đ’ŅĐĩ ĐēĐ°ŅŅĐ¸Ņ€Ņ‹ Đ´ĐĩĐģĐ°ŅŽŅ‚ Đ˛ŅŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ ОдĐŊиĐŧ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ Са Đ´Ņ€ŅƒĐŗĐ¸Đŧ 👨‍đŸ’ŧ⏯. -ĐŅƒĐļĐŊĐž ĐąŅ‹ĐģĐž Đ´ĐžĐģĐŗĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ 🕙 ŅŅ‚ĐžŅŅ‚ŅŒ ĐŋĐĩŅ€ĐĩĐ´ ĐžĐēĐžŅˆĐēĐžĐŧ вĐŧĐĩҁ҂Đĩ ŅĐž Đ˛ŅĐĩĐŧи, иĐŊĐ°Ņ‡Đĩ ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸ŅˆŅŒ ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ. +И ваĐŧ ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ Đ´ĐžĐģĐŗĐž 🕙 ŅŅ‚ĐžŅŅ‚ŅŒ в ĐžŅ‡ĐĩŅ€Đĩди, иĐŊĐ°Ņ‡Đĩ Đ˛Ņ‹ ĐŋĐžŅ‚ĐĩŅ€ŅĐĩŅ‚Đĩ ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ. -ĐĄĐžĐŧĐŊĐĩĐ˛Đ°ŅŽŅŅŒ, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐąŅ‹ вОСĐŊиĐēĐģĐž ĐļĐĩĐģаĐŊиĐĩ ĐŋŅ€Đ¸ĐšŅ‚Đ¸ ҁ вОСĐģŅŽĐąĐģĐĩĐŊĐŊОК 😍 в йаĐŊĐē đŸĻ ĐžĐŋĐģĐ°Ņ‡Đ¸Đ˛Đ°Ņ‚ŅŒ ĐŊаĐģĐžĐŗĐ¸. +Đ’Ņ‹ Đ˛Ņ€ŅĐ´ Đģи ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛ĐˇŅŅ‚ŅŒ ŅĐ˛ĐžŅŽ вОСĐģŅŽĐąĐģĐĩĐŊĐŊŅƒŅŽ 😍 ҁ ŅĐžĐąĐžĐš, Ņ‡Ņ‚ĐžĐąŅ‹ СаĐŊŅŅ‚ŅŒŅŅ Đ´ĐĩĐģаĐŧи в йаĐŊĐēĐĩ đŸĻ. -### Đ’Ņ‹Đ˛ĐžĐ´Ņ‹ Đž ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Ņ… +### Đ’Ņ‹Đ˛ĐžĐ´ ĐŋŅ€Đž ĐąŅƒŅ€ĐŗĐĩҀҋ { #burger-conclusion } -В ĐŊĐ°ŅˆĐĩĐš Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ ĐŋŅ€Đž ĐŋĐžŅ…ĐžĐ´ в Ņ„Đ°ŅŅ‚Ņ„ŅƒĐ´ Са ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐŧĐŊĐžĐŗĐž ĐļĐ´Đ°Ņ‚ŅŒ 🕙, -ĐŋĐžŅŅ‚ĐžĐŧ҃ иĐŧĐĩĐĩŅ‚ ҁĐŧҋҁĐģ ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ â¸đŸ”€â¯. +В ŅŅ‚ĐžĐŧ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸ ÂĢŅ„Đ°ŅŅ‚Ņ„ŅƒĐ´Đ° ҁ Đ˛Đ°ŅˆĐĩĐš вОСĐģŅŽĐąĐģĐĩĐŊĐŊОКÂģ, Ņ‚Đ°Đē ĐēаĐē ĐŧĐŊĐžĐŗĐž ĐžĐļидаĐŊĐ¸Ņ 🕙, ĐŗĐžŅ€Đ°ĐˇĐ´Đž ĐģĐžĐŗĐ¸Ņ‡ĐŊĐĩĐĩ иĐŧĐĩŅ‚ŅŒ ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ â¸đŸ”€â¯. -И Ņ‚Đž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ ҁ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛ĐžĐŧ вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. +ĐĸаĐē ĐžĐąŅŅ‚ĐžĐ¸Ņ‚ Đ´ĐĩĐģĐž и ҁ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛ĐžĐŧ вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. -ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš ĐžŅ‡ĐĩĐŊҌ ĐŧĐŊĐžĐŗĐž, ĐŊĐž Đ˛Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž Đ˛Ņ‹ĐŊ҃ĐļĐ´ĐĩĐŊ ĐļĐ´Đ°Ņ‚ŅŒ 🕙 СаĐŋŅ€ĐžŅŅ‹ ĐŋĐž Đ¸Ņ… ҁĐģайОĐŧ҃ иĐŊŅ‚ĐĩŅ€ĐŊĐĩŅ‚-ŅĐžĐĩдиĐŊĐĩĐŊĐ¸ŅŽ. +ĐžŅ‡ĐĩĐŊҌ ĐŧĐŊĐžĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš, ĐŊĐž Đ˛Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ ĐļĐ´Ņ‘Ņ‚ 🕙, ĐŋĐžĐēа Đ¸Ņ… ĐŊĐĩ ŅĐ°ĐŧĐžĐĩ Ņ…ĐžŅ€ĐžŅˆĐĩĐĩ ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ Đ¸Ņ… СаĐŋŅ€ĐžŅŅ‹. -ĐŸĐžŅ‚ĐžĐŧ ҁĐŊОва ĐļĐ´Đ°Ņ‚ŅŒ 🕙, ĐŋĐžĐēа вĐĩŅ€ĐŊŅ‘Ņ‚ŅŅ ĐžŅ‚Đ˛ĐĩŅ‚. +А ĐˇĐ°Ņ‚ĐĩĐŧ ҁĐŊОва ĐļĐ´Ņ‘Ņ‚ 🕙, ĐŋĐžĐēа ĐžŅ‚ĐŋŅ€Đ°Đ˛ŅŅ‚ŅŅ ĐžŅ‚Đ˛Đĩ҂ҋ. - -Đ­Ņ‚Đž ĐžĐļидаĐŊиĐĩ 🕙 иСĐŧĐĩŅ€ŅĐĩŅ‚ŅŅ ĐŧиĐēŅ€ĐžŅĐĩĐē҃ĐŊдаĐŧи, ĐŊĐž ĐĩҁĐģи Đ˛ŅŅ‘ ҁĐģĐžĐļĐ¸Ņ‚ŅŒ, Ņ‚Đž ĐŊайĐĩĐŗĐ°ĐĩŅ‚ дОвОĐģҌĐŊĐž ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи. +Đ­Ņ‚Đž ÂĢĐžĐļидаĐŊиĐĩÂģ 🕙 иСĐŧĐĩŅ€ŅĐĩŅ‚ŅŅ ĐŧиĐēŅ€ĐžŅĐĩĐē҃ĐŊдаĐŧи, ĐŊĐž ĐĩҁĐģи Đ˛ŅŅ‘ ҁĐģĐžĐļĐ¸Ņ‚ŅŒ, Ņ‚Đž в ҁ҃ĐŧĐŧĐĩ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ŅŅ ĐŧĐŊĐžĐŗĐž ĐžĐļидаĐŊĐ¸Ņ. -Đ’ĐžŅ‚ ĐŋĐžŅ‡ĐĩĐŧ҃ ĐĩŅŅ‚ŅŒ ҁĐŧҋҁĐģ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐĩ â¸đŸ”€â¯ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€Đ¸ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊии вĐĩĐą-API. +Đ’ĐžŅ‚ ĐŋĐžŅ‡ĐĩĐŧ҃ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš â¸đŸ”€â¯ ĐēОд ĐžŅ‡ĐĩĐŊҌ ҃ĐŧĐĩҁ҂ĐĩĐŊ Đ´ĐģŅ вĐĩĐą-API. -БоĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв (вĐēĐģŅŽŅ‡Đ°Ņ Flask и Django) ŅĐžĐˇĐ´Đ°Đ˛Đ°ĐģĐ¸ŅŅŒ -Đ´Đž ĐŋĐžŅĐ˛ĐģĐĩĐŊĐ¸Ņ в Python ĐŊĐžĐ˛Ņ‹Ņ… вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. ĐŸĐžŅŅ‚ĐžĐŧ҃ -Đ¸Ņ… ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐ˛ĐžŅ€Đ°Ņ‡Đ¸Đ˛Đ°Ņ‚ŅŒ ҁ ĐŋОддĐĩŅ€ĐļĐēОК ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐžĐŗĐž Đ¸ŅĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ иĐģи Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž -ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ ŅŅ‚Đ°Ņ€ĐžĐŗĐž Ņ‚Đ¸Đŋа, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŊĐĩ ĐŊĐ°ŅŅ‚ĐžĐģҌĐēĐž ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊĐž. +ИĐŧĐĩĐŊĐŊĐž Ņ‚Đ°ĐēĐ°Ņ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžŅŅ‚ŅŒ ŅĐ´ĐĩĐģаĐģа NodeJS ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊŅ‹Đŧ (Ņ…ĐžŅ‚Ņ NodeJS — ĐŊĐĩ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đš), и ŅŅ‚Đž ŅĐ¸ĐģҌĐŊĐ°Ņ ŅŅ‚ĐžŅ€ĐžĐŊа Go ĐēаĐē ŅĐˇŅ‹Đēа ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. -ĐŸŅ€Đ¸ Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐžŅĐŊОвĐŊĐ°Ņ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ Python ҁ вĐĩĐą-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ -(ASGI) -ĐąŅ‹Đģа Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊа ĐēĐžĐŧаĐŊдОК Django Đ´ĐģŅ вĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐŋОддĐĩŅ€ĐļĐēи вĐĩĐą-ŅĐžĐēĐĩŅ‚ĐžĐ˛. +ĐĸĐžĐŗĐž ĐļĐĩ ŅƒŅ€ĐžĐ˛ĐŊŅ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ ҁ **FastAPI**. -ИĐŧĐĩĐŊĐŊĐž Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžŅŅ‚ŅŒ ŅĐ´ĐĩĐģаĐģа NodeJS Ņ‚Đ°ĐēиĐŧ ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊŅ‹Đŧ (ĐŊĐĩҁĐŧĐžŅ‚Ņ€Ņ ĐŊа Ņ‚Đž, Ņ‡Ņ‚Đž ĐžĐŊ ĐŊĐĩ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊŅ‹Đš), -и в ŅŅ‚ĐžĐŧ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đž Go ĐēаĐē ŅĐˇŅ‹Đēа ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. +А Ņ‚Đ°Đē ĐēаĐē ĐŧĐžĐļĐŊĐž ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ и Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžŅŅ‚ŅŒ, Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ Đ˛Ņ‹ŅˆĐĩ, ҇ĐĩĐŧ ҃ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đ° ĐŋŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв ĐŊа NodeJS и ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ Go, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš — ĐēĐžĐŧĐŋиĐģĐ¸Ņ€ŅƒĐĩĐŧŅ‹Đš ŅĐˇŅ‹Đē, ĐąĐģиĐļĐĩ Đē C (Đ˛ŅŅ‘ ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ Starlette). -И Ņ‚ĐžŅ‚ ĐļĐĩ ŅƒŅ€ĐžĐ˛ĐĩĐŊҌ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ Đ´Đ°Ņ‘Ņ‚ **FastAPI**. +### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа? { #is-concurrency-better-than-parallelism } -ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа и Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžŅŅ‚Đ¸ вĐŧĐĩҁ҂Đĩ, -Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ ĐģŅƒŅ‡ŅˆĐĩ, ҇ĐĩĐŧ ҃ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đ° ĐŋŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ NodeJS ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв -и ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ҁ Go, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ĐēĐžĐŧĐŋиĐģĐ¸Ņ€ŅƒĐĩĐŧŅ‹Đŧ ŅĐˇŅ‹ĐēĐžĐŧ ĐąĐģиСĐēиĐŧ Đē C (Đ˛ŅŅ‘ ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ Starlette). +НĐĩŅ‚! ĐœĐžŅ€Đ°ĐģҌ Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ ĐŊĐĩ в ŅŅ‚ĐžĐŧ. -### ПоĐģŅƒŅ‡Đ°ĐĩŅ‚ŅŅ, ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа? +КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа. И ĐžĐŊа ĐģŅƒŅ‡ŅˆĐĩ в **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅** ҁ҆ĐĩĐŊĐ°Ņ€Đ¸ŅŅ…, ĐŗĐ´Đĩ ĐŧĐŊĐžĐŗĐž ĐžĐļидаĐŊĐ¸Ņ. ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐŋŅ€Đ¸ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК ĐžĐŊа ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊаĐŧĐŊĐžĐŗĐž ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа. Но ĐŊĐĩ вО Đ˛ŅŅ‘Đŧ. -НĐĩŅ‚! ĐœĐžŅ€Đ°ĐģҌ Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ ŅĐžĐ˛ŅĐĩĐŧ ĐŊĐĩ в ŅŅ‚ĐžĐŧ. +Đ§Ņ‚ĐžĐąŅ‹ ŅƒŅ€Đ°Đ˛ĐŊОвĐĩŅĐ¸Ņ‚ŅŒ ŅŅ‚Đž, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ Ņ‚Đ°ĐēŅƒŅŽ ĐēĐžŅ€ĐžŅ‚ĐēŅƒŅŽ Đ¸ŅŅ‚ĐžŅ€Đ¸ŅŽ: -КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа. ОĐŊа ĐģŅƒŅ‡ŅˆĐĩ в **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅** ҁĐģŅƒŅ‡Đ°ŅŅ…, ĐŗĐ´Đĩ ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐŊа ĐžĐļидаĐŊиĐĩ. -Đ’ĐžŅ‚ ĐŋĐžŅ‡ĐĩĐŧ҃ ĐžĐŊа ĐˇĐ°Ņ‡Đ°ŅŅ‚ŅƒŅŽ ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа ĐŋŅ€Đ¸ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. Но ŅŅ‚Đž ĐŊĐĩ СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ ĐģŅƒŅ‡ŅˆĐĩ в ĐģŅŽĐąŅ‹Ņ… ҁ҆ĐĩĐŊĐ°Ņ€Đ¸ŅŅ…. - -Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ҁ Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ Ņ‚Đ°ĐēŅƒŅŽ ĐēĐ°Ņ€Ņ‚Đ¸ĐŊ҃: - -> ВаĐŧ ĐŊ҃ĐļĐŊĐž ŅƒĐąŅ€Đ°Ņ‚ŅŒŅŅ в йОĐģŅŒŅˆĐžĐŧ ĐŗŅ€ŅĐˇĐŊĐžĐŧ Đ´ĐžĐŧĐĩ. +> ВаĐŧ ĐŊ҃ĐļĐŊĐž ŅƒĐąŅ€Đ°Ņ‚ŅŒ йОĐģŅŒŅˆĐžĐš ĐŗŅ€ŅĐˇĐŊŅ‹Đš Đ´ĐžĐŧ. *Да, ŅŅ‚Đž Đ˛ŅŅ Đ¸ŅŅ‚ĐžŅ€Đ¸Ņ*. --- -ĐĸŅƒŅ‚ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐŊĐ¸ĐŗĐ´Đĩ ĐļĐ´Đ°Ņ‚ŅŒ 🕙, ĐŋŅ€ĐžŅŅ‚Đž ĐĩŅŅ‚ŅŒ ĐēŅƒŅ‡Đ° Ņ€Đ°ĐąĐžŅ‚Ņ‹ в Ņ€Đ°ĐˇĐŊҋ҅ Ņ‡Đ°ŅŅ‚ŅŅ… Đ´ĐžĐŧа. +ЗдĐĩҁҌ ĐŊĐ¸ĐŗĐ´Đĩ ĐŊĐĩŅ‚ ĐžĐļидаĐŊĐ¸Ņ 🕙, ĐŋŅ€ĐžŅŅ‚Đž ĐžŅ‡ĐĩĐŊҌ ĐŧĐŊĐžĐŗĐž Ņ€Đ°ĐąĐžŅ‚Ņ‹ в Ņ€Đ°ĐˇĐŊҋ҅ ĐŧĐĩŅŅ‚Đ°Ņ… Đ´ĐžĐŧа. -МоĐļĐŊĐž ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ ĐēаĐē в ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ҁ ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи, ҁĐŊĐ°Ņ‡Đ°Đģа ĐŗĐžŅŅ‚Đ¸ĐŊĐ°Ņ, ĐŋĐžŅ‚ĐžĐŧ ĐēŅƒŅ…ĐŊŅ, -ĐŊĐž ŅŅ‚Đž ĐŊи ĐŊа Ņ‡Ņ‚Đž ĐŊĐĩ ĐŋОвĐģĐ¸ŅĐĩŅ‚, ĐŋĐžŅĐēĐžĐģҌĐē҃ Đ˛Ņ‹ ĐŊĐ¸ĐŗĐ´Đĩ ĐŊĐĩ ĐļĐ´Ņ‘Ņ‚Đĩ 🕙, а ĐŋŅ€ĐžŅŅ‚Đž ҂Ҁґ҂Đĩ да ĐŧĐžĐĩŅ‚Đĩ. +МоĐļĐŊĐž ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ÂĢĐžŅ‡ĐĩŅ€ĐĩдиÂģ ĐēаĐē в ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ҁ ĐąŅƒŅ€ĐŗĐĩŅ€Đ°Đŧи — ҁĐŊĐ°Ņ‡Đ°Đģа ĐŗĐžŅŅ‚Đ¸ĐŊĐ°Ņ, ĐŋĐžŅ‚ĐžĐŧ ĐēŅƒŅ…ĐŊŅ, — ĐŊĐž Ņ‚Đ°Đē ĐēаĐē Đ˛Ņ‹ ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩ ĐļĐ´Ņ‘Ņ‚Đĩ 🕙, а ĐŋŅ€ĐžŅŅ‚Đž ŅƒĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ и ŅƒĐąĐ¸Ņ€Đ°ĐĩŅ‚Đĩ, ĐžŅ‡ĐĩŅ€Đĩди ĐŊи ĐŊа Ņ‡Ņ‚Đž ĐŊĐĩ ĐŋОвĐģĐ¸ŅŅŽŅ‚. -И ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ ОдиĐŊаĐēОвОĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž Đ˛Ņ€ĐĩĐŧĐĩĐŊи ҁ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒŅŽ (ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ) и ĐąĐĩС ĐŊĐĩŅ‘, -и Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐąŅƒĐ´ĐĩŅ‚ ŅĐ´ĐĩĐģаĐŊĐž Ņ‚ĐžĐļĐĩ ОдиĐŊаĐēОвОĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž. +На СавĐĩŅ€ŅˆĐĩĐŊиĐĩ ŅƒĐšĐ´Ņ‘Ņ‚ ОдиĐŊаĐēОвОĐĩ Đ˛Ņ€ĐĩĐŧŅ — ҁ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅĐŧи (ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ) и ĐąĐĩС ĐŊĐ¸Ņ… — и ĐžĐąŅŠŅ‘Đŧ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐŊОК Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐąŅƒĐ´ĐĩŅ‚ ОдиĐŊаĐēĐžĐ˛Ņ‹Đŧ. -ОдĐŊаĐēĐž в ҁĐģŅƒŅ‡Đ°Đĩ, ĐĩҁĐģи ĐąŅ‹ Đ˛Ņ‹ ĐŧĐžĐŗĐģи ĐŋŅ€Đ¸Đ˛ĐĩŅŅ‚Đ¸ 8 ĐąŅ‹Đ˛ŅˆĐ¸Ņ… ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛/ĐŋĐžĐ˛Đ°Ņ€ĐžĐ˛, а ĐŊŅ‹ĐŊĐĩ ŅƒĐąĐžŅ€Ņ‰Đ¸ĐēОв đŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗđŸ‘Šâ€đŸŗđŸ‘¨â€đŸŗ, -и ĐēаĐļĐ´Ņ‹Đš иС ĐŊĐ¸Ņ… (вĐŧĐĩҁ҂Đĩ ҁ ваĐŧи) Đ˛ĐˇŅĐģŅŅ ĐąŅ‹ Са ŅĐ˛ĐžĐš ŅƒŅ‡Đ°ŅŅ‚ĐžĐē Đ´ĐžĐŧа, -ҁ Ņ‚Đ°ĐēОК ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Đ˛Ņ‹ ĐąŅ‹ СаĐēĐžĐŊŅ‡Đ¸Đģи ĐŊаĐŧĐŊĐžĐŗĐž ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ, Đ´ĐĩĐģĐ°Ņ Đ˛ŅŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž**. +Но в ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ, ĐĩҁĐģи ĐąŅ‹ Đ˛Ņ‹ ĐŧĐžĐŗĐģи ĐŋŅ€Đ¸Đ˛ĐĩŅŅ‚Đ¸ 8 ĐąŅ‹Đ˛ŅˆĐ¸Ņ… ĐēĐ°ŅŅĐ¸Ņ€ĐžĐ˛/ĐŋĐžĐ˛Đ°Ņ€ĐžĐ˛, а Ņ‚ĐĩĐŋĐĩŅ€ŅŒ — ŅƒĐąĐžŅ€Ņ‰Đ¸ĐēОв, и ĐēаĐļĐ´Ņ‹Đš иС ĐŊĐ¸Ņ… (ĐŋĐģŅŽŅ Đ˛Ņ‹) Đ˛ĐˇŅĐģ ĐąŅ‹ ŅĐ˛ĐžŅŽ СОĐŊ҃ Đ´ĐžĐŧа Đ´ĐģŅ ŅƒĐąĐžŅ€Đēи, Đ˛Ņ‹ ĐŧĐžĐŗĐģи ĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ Đ˛ŅŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž**, ҁ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊОК ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ, и СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŒ ĐŗĐžŅ€Đ°ĐˇĐ´Đž ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ. -В ĐžĐŋĐ¸ŅĐ°ĐŊĐŊĐžĐŧ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸ ĐēаĐļĐ´Ņ‹Đš ŅƒĐąĐžŅ€Ņ‰Đ¸Đē (вĐēĐģŅŽŅ‡Đ°Ņ Đ˛Đ°Ņ) ĐąŅ‹Đģ ĐąŅ‹ Đ¸ŅĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģĐĩĐŧ, СаĐŊŅŅ‚Ņ‹Đŧ ĐŊа ŅĐ˛ĐžŅ‘Đŧ ŅƒŅ‡Đ°ŅŅ‚ĐēĐĩ Ņ€Đ°ĐąĐžŅ‚Ņ‹. +В ŅŅ‚ĐžĐŧ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸ ĐēаĐļĐ´Ņ‹Đš ŅƒĐąĐžŅ€Ņ‰Đ¸Đē (вĐēĐģŅŽŅ‡Đ°Ņ Đ˛Đ°Ņ) ĐąŅ‹Đģ ĐąŅ‹ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐžĐŧ, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‰Đ¸Đŧ ŅĐ˛ĐžŅŽ Ņ‡Đ°ŅŅ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Ņ‹. -И ĐŋĐžŅĐēĐžĐģҌĐē҃ йОĐģŅŒŅˆŅƒŅŽ Ņ‡Đ°ŅŅ‚ŅŒ Đ˛Ņ€ĐĩĐŧĐĩĐŊи Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ СаĐŊиĐŧаĐĩŅ‚ Ņ€ĐĩаĐģҌĐŊĐ°Ņ Ņ€Đ°ĐąĐžŅ‚Đ° (а ĐŊĐĩ ĐžĐļидаĐŊиĐĩ), -а Ņ€Đ°ĐąĐžŅ‚Ņƒ в ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ Đ´ĐĩĐģаĐĩŅ‚ ĐĻП, -Ņ‚Đ°ĐēиĐĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đŧи ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒŅŽ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°. +И Ņ‚Đ°Đē ĐēаĐē ĐžŅĐŊОвĐŊĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ ŅƒŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа Ņ€ĐĩаĐģҌĐŊŅƒŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ (а ĐŊĐĩ ĐžĐļидаĐŊиĐĩ), а Ņ€Đ°ĐąĐžŅ‚Ņƒ в ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ CPU, Ņ‚Đ°ĐēиĐĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ÂĢĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đŧи ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐžĐŧÂģ (CPU bound). --- -ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Ņƒ ĐŋŅ€ĐžŅĐ˛ĐģŅĐĩŅ‚ŅŅ в ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŅ…, ĐŗĐ´Đĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ ҁĐģĐžĐļĐŊŅ‹Đĩ ĐŧĐ°Ņ‚ĐĩĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ. +ĐĸиĐŋĐ¸Ņ‡ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ CPU-bound ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš — Ņ‚Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҂ҀĐĩĐąŅƒŅŽŅ‚ ҁĐģĐžĐļĐŊОК ĐŧĐ°Ņ‚ĐĩĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи. НаĐŋŅ€Đ¸ĐŧĐĩŅ€: -* ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа **ĐˇĐ˛ŅƒĐēа** иĐģи **Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиК**. -* **КоĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ĐŊĐžĐĩ ĐˇŅ€ĐĩĐŊиĐĩ**: Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиĐĩ ŅĐžŅŅ‚ĐžĐ¸Ņ‚ иС ĐŧиĐģĐģиОĐŊОв ĐŋиĐēҁĐĩĐģĐĩĐš, в ĐēаĐļĐ´ĐžĐŧ ĐŋиĐēҁĐĩĐģĐĩ 3 ŅĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Ņ… Ņ†Đ˛ĐĩŅ‚Đ°, -ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ĐžĐąŅ‹Ņ‡ĐŊĐž ҂ҀĐĩĐąŅƒĐĩŅ‚ ĐŋŅ€ĐžĐ˛ĐĩĐ´ĐĩĐŊĐ¸Ņ Ņ€Đ°ŅŅ‡Ņ‘Ņ‚ĐžĐ˛ ĐŋĐž Đ˛ŅĐĩĐŧ ĐŋиĐēҁĐĩĐģŅĐŧ ŅŅ€Đ°ĐˇŅƒ. -* **ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ**: СдĐĩҁҌ ĐžĐąŅ‹Ņ‡ĐŊĐž ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ ҃ĐŧĐŊĐžĐļĐĩĐŊиĐĩ "ĐŧĐ°Ņ‚Ņ€Đ¸Ņ†" и "вĐĩĐēŅ‚ĐžŅ€ĐžĐ˛". -ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ ĐŗĐ¸ĐŗĐ°ĐŊ҂ҁĐēŅƒŅŽ Ņ‚Đ°ĐąĐģĐ¸Ņ†Ņƒ ҁ Ņ‡Đ¸ŅĐģаĐŧи в Đ­ĐēҁĐĩĐģĐĩ, и Đ˛ŅĐĩ Đ¸Ņ… ĐŊадО ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž ĐŋĐĩŅ€ĐĩĐŧĐŊĐžĐļĐ¸Ņ‚ŅŒ. -* **ГĐģŅƒĐąĐžĐēĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ**: ŅŅ‚Đž ОйĐģĐ°ŅŅ‚ŅŒ *ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ*, ĐŋĐžŅŅ‚ĐžĐŧ҃ ŅŅŽĐ´Đ° ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ Ņ‚Đž ĐļĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ. -ĐŸŅ€ĐžŅŅ‚Đž ҃ Đ˛Đ°Ņ ĐąŅƒĐ´ĐĩŅ‚ ĐŊĐĩ ОдĐŊа Ņ‚Đ°ĐąĐģĐ¸Ņ†Đ° в Đ­ĐēҁĐĩĐģĐĩ, а ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž. В Ņ€ŅĐ´Đĩ ҁĐģŅƒŅ‡Đ°Đĩв Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ -ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ и / иĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐŊҋ҅ Ņ‚Đ°ĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ĐŧОдĐĩĐģĐĩĐš. +* ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа **Đ°ŅƒĐ´Đ¸Đž** иĐģи **Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиК**. +* **КоĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ĐŊĐžĐĩ ĐˇŅ€ĐĩĐŊиĐĩ**: Đ¸ĐˇĐžĐąŅ€Đ°ĐļĐĩĐŊиĐĩ ŅĐžŅŅ‚ĐžĐ¸Ņ‚ иС ĐŧиĐģĐģиОĐŊОв ĐŋиĐēҁĐĩĐģĐĩĐš, ĐēаĐļĐ´Ņ‹Đš ĐŋиĐēҁĐĩĐģҌ иĐŧĐĩĐĩŅ‚ 3 СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ/Ņ†Đ˛ĐĩŅ‚Đ°; ĐžĐąŅ‹Ņ‡ĐŊĐž ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐ¸Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž Đ´ĐģŅ Đ˛ŅĐĩŅ… ŅŅ‚Đ¸Ņ… ĐŋиĐēҁĐĩĐģĐĩĐš ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž. +* **ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ**: ĐžĐąŅ‹Ņ‡ĐŊĐž ҂ҀĐĩĐąŅƒĐĩŅ‚ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° ҃ĐŧĐŊĐžĐļĐĩĐŊиК ÂĢĐŧĐ°Ņ‚Ņ€Đ¸Ņ†Âģ и ÂĢвĐĩĐēŅ‚ĐžŅ€ĐžĐ˛Âģ. ĐŸŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ ĐžĐŗŅ€ĐžĐŧĐŊŅƒŅŽ Ņ‚Đ°ĐąĐģĐ¸Ņ†Ņƒ ҁ Ņ‡Đ¸ŅĐģаĐŧи и ҃ĐŧĐŊĐžĐļĐĩĐŊиĐĩ Đ˛ŅĐĩŅ… ŅŅ‚Đ¸Ņ… Ņ‡Đ¸ŅĐĩĐģ ÂĢОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐžÂģ. +* **ГĐģŅƒĐąĐžĐēĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ**: ŅŅ‚Đž ĐŋОдĐŋĐžĐģĐĩ ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ, Ņ‚Đ°Đē Ņ‡Ņ‚Đž Đ˛ŅŅ‘ Đ˛Ņ‹ŅˆĐĩҁĐēаСаĐŊĐŊĐžĐĩ ĐŋŅ€Đ¸ĐŧĐĩĐŊиĐŧĐž. ĐŸŅ€ĐžŅŅ‚Đž ŅŅ‚Đž ĐŊĐĩ ОдĐŊа Ņ‚Đ°ĐąĐģĐ¸Ņ†Đ° Ņ‡Đ¸ŅĐĩĐģ, а Đ¸Ņ… ĐžĐŗŅ€ĐžĐŧĐŊŅ‹Đš ĐŊĐ°ĐąĐžŅ€, и вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ и/иĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đ°ĐēиĐĩ ĐŧОдĐĩĐģи. -### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ + ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ: ВĐĩĐą + ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ +### КоĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ + ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ: ВĐĩĐą + ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐĩ ĐžĐąŅƒŅ‡ĐĩĐŊиĐĩ { #concurrency-parallelism-web-machine-learning } -**FastAPI** ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ĐēĐžĐŊĐēŅƒŅ€ĐĩŅ‚ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, -ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐžŅ‡ĐĩĐŊҌ Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊĐĩĐŊĐž в вĐĩĐą-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ (иĐŧĐĩĐŊĐŊĐž ŅŅ‚Đ¸Đŧ ҁĐģĐ°Đ˛Đ¸Ņ‚ŅŅ NodeJS). +ĐĄ **FastAPI** Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚Đ¸, Ņ‡Ņ‚Đž ĐžŅ‡ĐĩĐŊҌ Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊĐĩĐŊĐž в вĐĩĐą-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ (ŅŅ‚Đž Ņ‚Đ° ĐļĐĩ ĐžŅĐŊОвĐŊĐ°Ņ ÂĢŅ„Đ¸ŅˆĐēаÂģ NodeJS). -ĐšŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа и -ĐŧĐŊĐžĐŗĐžĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐŊĐžŅŅ‚Đ¸ (ĐēĐžĐŗĐ´Đ° ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž), -ĐĩҁĐģи Ņ€Đ°ĐąĐžŅ‡Đ°Ņ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚ **ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Ņƒ**, -ĐēаĐē, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ… ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ. +Но Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛Ņ‹ĐŗĐžĐ´Ņ‹ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа и ĐŧĐŊĐžĐŗĐžĐŋŅ€ĐžŅ†ĐĩҁҁĐŊĐžŅŅ‚Đ¸ (ĐēĐžĐŗĐ´Đ° ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž) Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‡Đ¸Ņ… ĐŊĐ°ĐŗŅ€ŅƒĐˇĐžĐē, **ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐžĐŧ** (CPU bound), ĐēаĐē в ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ… ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ. -НĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž Ņ‚Đ°ĐēĐļĐĩ ĐžŅ‚ĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž Python ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ĐŗĐģавĐŊŅ‹Đŧ ŅĐˇŅ‹ĐēĐžĐŧ в ОйĐģĐ°ŅŅ‚Đ¸ -**Đ´Đ°Ņ‚Đ°-ŅĐ°ĐšĐĩĐŊҁ**, -ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ и, ĐžŅĐžĐąĐĩĐŊĐŊĐž, ĐŗĐģŅƒĐąĐžĐēĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ. Đ’ŅŅ‘ ŅŅ‚Đž Đ´ĐĩĐģаĐĩŅ‚ FastAPI -ĐžŅ‚ĐģĐ¸Ņ‡ĐŊŅ‹Đŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐŧ (ҁҀĐĩди ĐŧĐŊĐžĐŗĐ¸Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ…) Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи вĐĩĐą-API и ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК -в ОйĐģĐ°ŅŅ‚Đ¸ Đ´Đ°Ņ‚Đ°-ŅĐ°ĐšĐĩĐŊҁ / ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ. +ПĐģŅŽŅ Đē ŅŅ‚ĐžĐŧ҃ ĐŋŅ€ĐžŅŅ‚ĐžĐš Ņ„Đ°ĐēŅ‚, Ņ‡Ņ‚Đž Python — ĐžŅĐŊОвĐŊОК ŅĐˇŅ‹Đē Đ´ĐģŅ **Data Science**, ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ и ĐžŅĐžĐąĐĩĐŊĐŊĐž ГĐģŅƒĐąĐžĐēĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ, Đ´ĐĩĐģаĐĩŅ‚ FastAPI ĐžŅ‡ĐĩĐŊҌ Ņ…ĐžŅ€ĐžŅˆĐ¸Đŧ Đ˛Ņ‹ĐąĐžŅ€ĐžĐŧ Đ´ĐģŅ вĐĩĐą-API и ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК в ОйĐģĐ°ŅŅ‚Đ¸ Data Science / ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ (ҁҀĐĩди ĐŧĐŊĐžĐŗĐ¸Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ…). -КаĐē Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ Ņ‚Đ°ĐēĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа в ŅĐēҁĐŋĐģŅƒĐ°Ņ‚Đ°Ņ†Đ¸Đ¸ ĐžĐŋĐ¸ŅĐ°ĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ](deployment/index.md){.internal-link target=_blank}. +КаĐē Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ Ņ‚Đ°ĐēĐžĐŗĐž ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧа в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ, ҁĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ [Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ](deployment/index.md){.internal-link target=_blank}. -## `async` и `await` +## `async` и `await` { #async-and-await } -В ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊҋ҅ вĐĩŅ€ŅĐ¸ŅŅ… Python Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐēОда Ņ€ĐĩаĐģиСОваĐŊа ĐžŅ‡ĐĩĐŊҌ иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐž. -ОĐŊ Đ˛Ņ‹ĐŗĐģŅĐ´Đ¸Ņ‚ ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš "ĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš" ĐēОд и ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ "ĐžĐļидаĐŊиĐĩ", ĐēĐžĐŗĐ´Đ° ŅŅ‚Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž. +В ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊҋ҅ вĐĩŅ€ŅĐ¸ŅŅ… Python ĐĩŅŅ‚ŅŒ ĐžŅ‡ĐĩĐŊҌ иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊŅ‹Đš ҁĐŋĐžŅĐžĐą ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд. Đ­Ņ‚Đž Đ´ĐĩĐģаĐĩŅ‚ ĐĩĐŗĐž ĐŋĐžŅ…ĐžĐļиĐŧ ĐŊа ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš ÂĢĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊŅ‹ĐšÂģ ĐēОд, а ÂĢĐžĐļидаĐŊиĐĩÂģ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ Са Đ˛Đ°Ņ в ĐŊ҃ĐļĐŊŅ‹Đĩ ĐŧĐžĐŧĐĩĐŊ҂ҋ. -Đ•ŅĐģи ĐŊĐĩĐēĐ°Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ҂ҀĐĩĐąŅƒĐĩŅ‚ ĐžĐļидаĐŊĐ¸Ņ ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē вĐĩŅ€ĐŊŅƒŅ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚, и -ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Python, ĐēОд ĐŧĐžĐļĐŊĐž ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ: +ĐšĐžĐŗĐ´Đ° ĐĩŅŅ‚ŅŒ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ, ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŊ҃ĐļĐŊĐž ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē вĐĩŅ€ĐŊŅƒŅ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚, и ĐžĐŊа ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ ŅŅ‚Đ¸ ĐŊĐžĐ˛Ņ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Python, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ Ņ‚Đ°Đē: ```Python burgers = await get_burgers(2) ``` -ГĐģавĐŊĐžĐĩ СдĐĩҁҌ ҁĐģОвО `await`. ОĐŊĐž ŅĐžĐžĐąŅ‰Đ°ĐĩŅ‚ иĐŊŅ‚ĐĩŅ€ĐŋŅ€ĐĩŅ‚Đ°Ņ‚ĐžŅ€Ņƒ, Ņ‡Ņ‚Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž Đ´ĐžĐļĐ´Đ°Ņ‚ŅŒŅŅ ⏸ -ĐŋĐžĐēа `get_burgers(2)` СаĐēĐžĐŊŅ‡Đ¸Ņ‚ ŅĐ˛ĐžĐ¸ Đ´ĐĩĐģа 🕙, и Ņ‚ĐžĐģҌĐēĐž ĐŋĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ŅĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ в `burgers`. -ЗĐŊĐ°Ņ ŅŅ‚Đž, Python ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐēа ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐˇĐ°Đ´Đ°Ņ‡ 🔀 ⏯ -(ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŗĐž СаĐŋŅ€ĐžŅĐ°). +КĐģŅŽŅ‡ СдĐĩҁҌ — `await`. ОĐŊ ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Python, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ ⏸, ĐŋĐžĐēа `get_burgers(2)` СаĐēĐžĐŊŅ‡Đ¸Ņ‚ ŅĐ˛ĐžŅ‘ Đ´ĐĩĐģĐž 🕙, ĐŋŅ€ĐĩĐļĐ´Đĩ ҇ĐĩĐŧ ŅĐžŅ…Ņ€Đ°ĐŊŅŅ‚ŅŒ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ в `burgers`. БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃ Python ĐąŅƒĐ´ĐĩŅ‚ СĐŊĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Са ŅŅ‚Đž Đ˛Ņ€ĐĩĐŧŅ ĐŧĐžĐļĐŊĐž СаĐŊŅŅ‚ŅŒŅŅ ҇ĐĩĐŧ-Ņ‚Đž Đĩ҉ґ 🔀 ⏯ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€Đ¸ĐŊŅŅ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš СаĐŋŅ€ĐžŅ). -Đ§Ņ‚ĐžĐąŅ‹ ĐēĐģŅŽŅ‡ĐĩвОĐĩ ҁĐģОвО `await` ŅŅ€Đ°ĐąĐžŅ‚Đ°ĐģĐž, ĐžĐŊĐž Đ´ĐžĐģĐļĐŊĐž ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŒŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, -ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžŅŅ‚ŅŒ. ДĐģŅ ŅŅ‚ĐžĐŗĐž ваĐŧ ĐŋŅ€ĐžŅŅ‚Đž ĐŊ҃ĐļĐŊĐž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐĩŅ‘ ĐēаĐē `async def`: +Đ§Ņ‚ĐžĐąŅ‹ `await` Ņ€Đ°ĐąĐžŅ‚Đ°Đģ, ĐžĐŊ Đ´ĐžĐģĐļĐĩĐŊ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŒŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ Ņ‚Đ°ĐēŅƒŅŽ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžŅŅ‚ŅŒ. ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐŋŅ€ĐžŅŅ‚Đž ĐžĐąŅŠŅĐ˛Đ¸Ņ‚Đĩ ĐĩŅ‘ ҁ `async def`: ```Python hl_lines="1" async def get_burgers(number: int): - # Đ“ĐžŅ‚ĐžĐ˛Đ¸Đŧ ĐąŅƒŅ€ĐŗĐĩҀҋ ĐŋĐž ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊĐžĐŧ҃ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŧ҃ Ņ€Đĩ҆ĐĩĐŋŅ‚Ņƒ + # ĐĄĐ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋ return burgers ``` @@ -355,26 +325,22 @@ async def get_burgers(number: int): ```Python hl_lines="2" # Đ­Ņ‚Đž ĐŊĐĩ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд def get_sequential_burgers(number: int): - # Đ“ĐžŅ‚ĐžĐ˛Đ¸Đŧ ĐąŅƒŅ€ĐŗĐĩҀҋ ĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊĐž ĐŋĐž ŅˆĐ°ĐŗĐ°Đŧ + # ĐĄĐ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž ĐŋĐžŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊĐžĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€Đ¸ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ŅŒ ĐąŅƒŅ€ĐŗĐĩҀҋ return burgers ``` -ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊиĐĩ `async def` ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ иĐŊŅ‚ĐĩŅ€ĐŋŅ€ĐĩŅ‚Đ°Ņ‚ĐžŅ€Ņƒ, Ņ‡Ņ‚Đž вĐŊŅƒŅ‚Ņ€Đ¸ ŅŅ‚ĐžĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ -ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ Đ˛Ņ‹Ņ€Đ°ĐļĐĩĐŊиК `await`, и Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ĐŋĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ Ņ‚Đ°ĐēОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŊа "ĐŋĐ°ŅƒĐˇŅƒ" ⏸ и -ĐŋĐĩŅ€ĐĩĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ 🔀, ҁ Ņ‚ĐĩĐŧ Ņ‡Ņ‚ĐžĐąŅ‹ вĐĩŅ€ĐŊŅƒŅ‚ŅŒŅŅ ŅŅŽĐ´Đ° ĐŋОСĐļĐĩ. +ĐĄ `async def` Python СĐŊаĐĩŅ‚, Ņ‡Ņ‚Đž вĐŊŅƒŅ‚Ņ€Đ¸ ŅŅ‚ĐžĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŊ҃ĐļĐŊĐž ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ Đ˛Ņ‹Ņ€Đ°ĐļĐĩĐŊĐ¸Ņ `await` и Ņ‡Ņ‚Đž Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ Ņ‚Đ°ĐēОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŧĐžĐļĐŊĐž ÂĢĐŋŅ€Đ¸ĐžŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒÂģ ⏸ и Đ¸Đ´Ņ‚Đ¸ Đ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž Đĩ҉ґ 🔀, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžŅ‚ĐžĐŧ вĐĩŅ€ĐŊŅƒŅ‚ŅŒŅŅ. -Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ ҁ `async def`, ваĐŧ ĐŊ҃ĐļĐŊĐž "ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ" ĐĩŅ‘. -ĐŸĐžŅŅ‚ĐžĐŧ҃ Ņ‚Đ°ĐēĐžĐĩ ĐŊĐĩ ŅŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚: +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅƒŅŽ ҁ `async def`, ĐŊ҃ĐļĐŊĐž ĐĩŅ‘ ÂĢĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒÂģ. ĐŸĐžŅŅ‚ĐžĐŧ҃ Đ˛ĐžŅ‚ Ņ‚Đ°Đē ĐŊĐĩ ŅŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚: ```Python -# Đ­Ņ‚Đž ĐŊĐĩ ĐˇĐ°Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚, ĐŋĐžŅĐēĐžĐģҌĐē҃ get_burgers ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊа ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ async def +# Đ­Ņ‚Đž ĐŊĐĩ ŅŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž get_burgers ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊа ҁ: async def burgers = get_burgers(2) ``` --- -Đ•ŅĐģи ŅŅ‚ĐžŅ€ĐžĐŊĐŊŅŅ йийĐģĐ¸ĐžŅ‚ĐĩĐēа ҂ҀĐĩĐąŅƒĐĩŅ‚ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ĐĩŅ‘ ҁ ĐēĐģŅŽŅ‡ĐĩĐ˛Ņ‹Đŧ ҁĐģОвОĐŧ `await`, -ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž ĐŋĐ¸ŅĐ°Ņ‚ŅŒ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `async def`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: +Đ˜Ņ‚Đ°Đē, ĐĩҁĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŧĐžĐļĐŊĐž Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ҁ `await`, ваĐŧ ĐŊ҃ĐļĐŊĐž ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ *Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐĩŅ‘ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚, ҁ `async def`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: ```Python hl_lines="2-3" @app.get('/burgers') @@ -383,129 +349,96 @@ async def read_burgers(): return burgers ``` -### ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ +### БоĐģĐĩĐĩ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ { #more-technical-details } -КаĐē Đ˛Ņ‹ ĐŧĐžĐŗĐģи СаĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ, `await` ĐŧĐžĐļĐĩŅ‚ ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅ‚ŅŒŅŅ Ņ‚ĐžĐģҌĐēĐž в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŅ…, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊҋ҅ ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `async def`. +Đ’Ņ‹ ĐŧĐžĐŗĐģи СаĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž `await` ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ҁ `async def`. - -Но Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ Ņ‚Đ°ĐēОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž "ĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒ" ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `await`. -Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐĩŅ‘ ĐŧĐžĐļĐŊĐž Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž иС Đ´Ņ€ŅƒĐŗĐžĐš Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Ņ‚ĐžĐļĐĩ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊа ҁ `async def`. +Но ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đĩ ҁ `async def`, ĐŊ҃ĐļĐŊĐž ÂĢĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒÂģ. ЗĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ҁ `async def` Ņ‚ĐžĐļĐĩ ĐŧĐžĐļĐŊĐž Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž иС Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ҁ `async def`. -Но ĐēаĐē ĐļĐĩ Ņ‚ĐžĐŗĐ´Đ° ĐŋĐžŅĐ˛Đ¸ĐģĐ°ŅŅŒ ĐŋĐĩŅ€Đ˛Đ°Ņ ĐēŅƒŅ€Đ¸Ņ†Đ°? В ҁĐŧҋҁĐģĐĩ... ĐēаĐē ĐŊаĐŧ Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ ĐŋĐĩŅ€Đ˛ŅƒŅŽ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ? +ĐĸаĐē Ņ‡Ņ‚Đž ĐļĐĩ ҁ ÂĢŅĐšŅ†ĐžĐŧ и ĐēŅƒŅ€Đ¸Ņ†ĐĩĐšÂģ — ĐēаĐē Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ ĐŋĐĩŅ€Đ˛ŅƒŅŽ `async` Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ? -ĐŸŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ **FastAPI** ĐŋŅ€ĐžŅŅ‚Đž ĐŊĐĩ Đ´ŅƒĐŧĐ°ĐšŅ‚Đĩ Ой ŅŅ‚ĐžĐŧ, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž "ĐŋĐĩŅ€Đ˛ĐžĐš" Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Đ˛Đ°ŅˆĐ° *Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸*, -и даĐģҌ҈Đĩ ҁ ŅŅ‚Đ¸Đŧ Ņ€Đ°ĐˇĐąĐĩŅ€Ņ‘Ņ‚ŅŅ FastAPI. +Đ•ŅĐģи Đ˛Ņ‹ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚Đĩ ҁ **FastAPI**, ваĐŧ ĐŊĐĩ Đž ҇ĐĩĐŧ ĐąĐĩҁĐŋĐžĐēĐžĐ¸Ņ‚ŅŒŅŅ, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ŅŅ‚ĐžĐš ÂĢĐŋĐĩŅ€Đ˛ĐžĐšÂģ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš ĐąŅƒĐ´ĐĩŅ‚ Đ˛Đ°ŅˆĐ° *Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸*, а FastAPI СĐŊаĐĩŅ‚, ĐēаĐē ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ Đ˛ŅŅ‘ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž. -ĐšŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž, ĐĩҁĐģи Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ `async` / `await` и ĐąĐĩС FastAPI. +Но ĐĩҁĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `async` / `await` ĐąĐĩС FastAPI, Đ˛Ņ‹ Ņ‚ĐžĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ŅŅ‚Đž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ. -### ĐŸĐ¸ŅˆĐ¸Ņ‚Đĩ ŅĐ˛ĐžĐš Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд +### ĐŸĐ¸ŅˆĐ¸Ņ‚Đĩ ŅĐ˛ĐžĐš Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд { #write-your-own-async-code } -Starlette (и **FastAPI**) ĐžŅĐŊОваĐŊŅ‹ ĐŊа AnyIO, Ņ‡Ņ‚Đž Đ´ĐĩĐģаĐĩŅ‚ Đ¸Ņ… ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧи ĐēаĐē ŅĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊОК йийĐģĐ¸ĐžŅ‚ĐĩĐēОК asyncio в Python, Ņ‚Đ°Đē и ҁ Trio. +Starlette (и **FastAPI**) ĐžŅĐŊОваĐŊŅ‹ ĐŊа AnyIO, Ņ‡Ņ‚Đž Đ´ĐĩĐģаĐĩŅ‚ Đ¸Ņ… ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧи и ŅĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊОК йийĐģĐ¸ĐžŅ‚ĐĩĐēОК Python asyncio, и ҁ Trio. -В Ņ‡Đ°ŅŅ‚ĐŊĐžŅŅ‚Đ¸, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ AnyIO в Ņ‚ĐĩŅ… ĐŋŅ€ĐžĐĩĐēŅ‚Đ°Ņ…, ĐŗĐ´Đĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ йОĐģĐĩĐĩ ҁĐģĐžĐļĐŊĐ°Ņ ĐģĐžĐŗĐ¸Đēа Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ. +В Ņ‡Đ°ŅŅ‚ĐŊĐžŅŅ‚Đ¸, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ AnyIO Đ´ĐģŅ ĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Ņ‹Ņ… ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đĩв ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚Đ¸, ĐŗĐ´Đĩ в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ ĐŊ҃ĐļĐŊŅ‹ йОĐģĐĩĐĩ ҁĐģĐžĐļĐŊŅ‹Đĩ ĐŋĐ°Ņ‚Ņ‚ĐĩŅ€ĐŊŅ‹. -ДаĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐ¸ŅĐ°Ņ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ AnyIO, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊи ĐąŅ‹Đģи ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧи и ĐŋĐžĐģŅƒŅ‡Đ°Đģи ĐĩĐŗĐž ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ *ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€ĐŊŅƒŅŽ ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ*). +И даĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐ¸ŅĐ°Ņ‚ŅŒ ŅĐ˛ĐžĐ¸ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ҁ AnyIO, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊи ĐąŅ‹Đģи ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧи и ĐŋĐžĐģŅƒŅ‡Đ°Đģи ĐĩĐŗĐž ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, *ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€ĐŊŅƒŅŽ ĐēĐžĐŊĐēŅƒŅ€ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒ*). -### Đ”Ņ€ŅƒĐŗĐ¸Đĩ Đ˛Đ¸Đ´Ņ‹ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ +Đ¯ ŅĐžĐˇĐ´Đ°Đģ Đĩ҉ґ ОдĐŊ҃ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃ ĐŋОвĐĩҀ҅ AnyIO, Ņ‚ĐžĐŊĐēиК ҁĐģОК, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊĐĩĐŧĐŊĐžĐŗĐž ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚ŅŒ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв и ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ йОĐģĐĩĐĩ ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ **Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ**, **ĐžŅˆĐ¸ĐąĐēи ĐŋŅ€ŅĐŧĐž в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đĩ** и Ņ‚.Đ´. ĐĸаĐŧ Ņ‚Đ°ĐēĐļĐĩ ĐĩŅŅ‚ŅŒ Đ´Ņ€ŅƒĐļĐĩĐģŅŽĐąĐŊĐžĐĩ ввĐĩĐ´ĐĩĐŊиĐĩ и Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŧĐžŅ‡ŅŒ ваĐŧ **ĐŋĐžĐŊŅŅ‚ŅŒ** и ĐŋĐ¸ŅĐ°Ņ‚ŅŒ **ŅĐ˛ĐžĐš ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đš Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд**: Asyncer. ОĐŊа ĐžŅĐžĐąĐĩĐŊĐŊĐž ĐŋĐžĐģĐĩСĐŊа, ĐĩҁĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž **ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОд ҁ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ** (ĐąĐģĐžĐēĐ¸Ņ€ŅƒŅŽŅ‰Đ¸Đŧ/ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đŧ) ĐēОдОĐŧ. -ĐĄŅ‚Đ¸ĐģҌ ĐŊаĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ ĐēОда ҁ `async` и `await` ĐŋĐžŅĐ˛Đ¸ĐģŅŅ в ŅĐˇŅ‹ĐēĐĩ Python ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŊĐĩдавĐŊĐž. +### Đ”Ņ€ŅƒĐŗĐ¸Đĩ Ņ„ĐžŅ€ĐŧŅ‹ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐēОда { #other-forms-of-asynchronous-code } -Но ĐžĐŊ ŅĐ¸ĐģҌĐŊĐž ОйĐģĐĩĐŗŅ‡Đ°ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đŧ ĐēОдОĐŧ. +ĐĸаĐēОК ŅŅ‚Đ¸ĐģҌ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ `async` и `await` ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŊĐžĐ˛Ņ‹Đš в ŅĐˇŅ‹ĐēĐĩ. -РОвĐŊĐž Ņ‚Đ°ĐēОК ĐļĐĩ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ (ĐŊ҃ иĐģи ĐŋĐžŅ‡Ņ‚Đ¸ Ņ‚Đ°ĐēОК ĐļĐĩ) ĐŊĐĩдавĐŊĐž ĐąŅ‹Đģ вĐēĐģŅŽŅ‡Ņ‘ĐŊ в ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ JavaScript (в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đĩ и NodeJS). +Но ĐžĐŊ ŅĐ¸ĐģҌĐŊĐž ҃ĐŋŅ€ĐžŅ‰Đ°ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đŧ ĐēОдОĐŧ. -До ŅŅ‚ĐžĐŗĐž ĐŋОддĐĩŅ€ĐļĐēа Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐēОда ĐąŅ‹Đģа Ņ€ĐĩаĐģиСОваĐŊа ĐŊаĐŧĐŊĐžĐŗĐž ҁĐģĐžĐļĐŊĐĩĐĩ, и ĐĩĐŗĐž ĐąŅ‹ĐģĐž Ņ‚Ņ€ŅƒĐ´ĐŊĐĩĐĩ Đ˛ĐžŅĐŋŅ€Đ¸ĐŊиĐŧĐ°Ņ‚ŅŒ. +ĐĸаĐēОК ĐļĐĩ (иĐģи ĐŋĐžŅ‡Ņ‚Đ¸ Ņ‚Đ°ĐēОК ĐļĐĩ) ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ ĐŊĐĩдавĐŊĐž ĐŋĐžŅĐ˛Đ¸ĐģŅŅ в ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊҋ҅ вĐĩŅ€ŅĐ¸ŅŅ… JavaScript (в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đĩ и NodeJS). -В ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… вĐĩŅ€ŅĐ¸ŅŅ… Python Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐ¸ŅŅŒ ĐŋĐžŅ‚ĐžĐēи иĐģи Gevent. Но Ņ‚Đ°ĐēОК ĐēОд ĐŊаĐŧĐŊĐžĐŗĐž ҁĐģĐžĐļĐŊĐĩĐĩ ĐŋĐžĐŊиĐŧĐ°Ņ‚ŅŒ, ĐžŅ‚ĐģаĐļĐ¸Đ˛Đ°Ņ‚ŅŒ и ĐŧҋҁĐģĐĩĐŊĐŊĐž ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅŅ‚ŅŒ. +До ŅŅ‚ĐžĐŗĐž Ņ€Đ°ĐąĐžŅ‚Đ° ҁ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đŧ ĐēОдОĐŧ ĐąŅ‹Đģа СаĐŧĐĩŅ‚ĐŊĐž ҁĐģĐžĐļĐŊĐĩĐĩ и Ņ‚Ņ€ŅƒĐ´ĐŊĐĩĐĩ Đ´ĐģŅ ĐŋĐžĐŊиĐŧаĐŊĐ¸Ņ. -Đ§Ņ‚Đž ĐēĐ°ŅĐ°ĐĩŅ‚ŅŅ JavaScript (в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đĩ и NodeJS), Ņ€Đ°ĐŊҌ҈Đĩ Ņ‚Đ°Đŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи Đ´ĐģŅ ŅŅ‚ĐžĐš ҆ĐĩĐģи -"ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đĩ Đ˛Ņ‹ĐˇĐžĐ˛Ņ‹". Đ§Ņ‚Đž Đ˛Ņ‹ĐģиваĐģĐžŅŅŒ в -ад ĐžĐąŅ€Đ°Ņ‚ĐŊҋ҅ Đ˛Ņ‹ĐˇĐžĐ˛ĐžĐ˛. +В ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… вĐĩŅ€ŅĐ¸ŅŅ… Python ĐŧĐžĐļĐŊĐž ĐąŅ‹ĐģĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžŅ‚ĐžĐēи иĐģи Gevent. Но Ņ‚Đ°ĐēОК ĐēОд ĐŗĐžŅ€Đ°ĐˇĐ´Đž ҁĐģĐžĐļĐŊĐĩĐĩ ĐŋĐžĐŊиĐŧĐ°Ņ‚ŅŒ, ĐžŅ‚ĐģаĐļĐ¸Đ˛Đ°Ņ‚ŅŒ и Đ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ в ĐŗĐžĐģОвĐĩ. -## ĐĄĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ +В ĐŋŅ€ĐĩĐļĐŊĐ¸Ņ… вĐĩŅ€ŅĐ¸ŅŅ… NodeJS/ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ĐŊĐžĐŗĐž JavaScript Đ˛Ņ‹ ĐąŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи ÂĢcallbacksÂģ (ĐžĐąŅ€Đ°Ņ‚ĐŊŅ‹Đĩ Đ˛Ņ‹ĐˇĐžĐ˛Ņ‹), Ņ‡Ņ‚Đž ĐŋŅ€Đ¸Đ˛ĐžĐ´Đ¸Ņ‚ Đē ÂĢcallback hellÂģ (ад ĐžĐąŅ€Đ°Ņ‚ĐŊҋ҅ Đ˛Ņ‹ĐˇĐžĐ˛ĐžĐ˛). -**ĐšĐžŅ€ŅƒŅ‚Đ¸ĖĐŊа** (иĐģи ĐļĐĩ ŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа) — ŅŅ‚Đž ĐēŅ€ŅƒŅ‚ĐžĐĩ ҁĐģОвĐĩ҇ĐēĐž Đ´ĐģŅ иĐŧĐĩĐŊОваĐŊĐ¸Ņ Ņ‚ĐžĐš ŅŅƒŅ‰ĐŊĐžŅŅ‚Đ¸, -ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `async def`. Python СĐŊаĐĩŅ‚, Ņ‡Ņ‚Đž ĐĩŅ‘ ĐŧĐžĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ, ĐēаĐē и ĐžĐąŅ‹Ņ‡ĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ, -ĐŊĐž ĐēŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž ŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ ĐŧĐžĐļĐŊĐž ĐŋĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŊа ĐŋĐ°ŅƒĐˇŅƒ ⏸ в Ņ‚ĐžĐŧ ĐŧĐĩҁ҂Đĩ, ĐŗĐ´Đĩ Đ˛ŅŅ‚Ņ€ĐĩŅ‚Đ¸Ņ‚ŅŅ ҁĐģОвО `await`. +## ĐĄĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ { #coroutines } -Đ’ŅŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `async` и `await` -Ņ‡Đ°ŅŅ‚Đž ĐžĐąĐžĐąŅ‰Đ°ŅŽŅ‚ ҁĐģОвОĐŧ "ĐēĐžŅ€ŅƒŅ‚Đ¸ĐŊŅ‹". ОĐŊи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹ "ĐŗĐžŅ€ŅƒŅ‚Đ¸ĐŊаĐŧ", ĐēĐģŅŽŅ‡ĐĩвОК ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚Đ¸ -ŅĐˇŅ‹Đēа Go. +**ĐĄĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа** (coroutine) — ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž ÂĢĐŊĐ°Đ˛ĐžŅ€ĐžŅ‡ĐĩĐŊĐŊĐžĐĩÂģ ҁĐģОвО Đ´ĐģŅ Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `async def`. Python СĐŊаĐĩŅ‚, Ņ‡Ņ‚Đž ŅŅ‚Đž ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ: ĐĩŅ‘ ĐŧĐžĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ, ĐžĐŊа ĐēĐžĐŗĐ´Đ°-ĐŊĐ¸ĐąŅƒĐ´ŅŒ СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŅ, ĐŊĐž ĐĩŅ‘ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ ĐŋŅ€Đ¸ĐžŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒŅŅ ⏸ вĐŊŅƒŅ‚Ņ€Đ¸, ĐēĐžĐŗĐ´Đ° Đ˛ŅŅ‚Ņ€ĐĩŅ‡Đ°ĐĩŅ‚ŅŅ `await`. -## ЗаĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ +Đ§Đ°ŅŅ‚Đž Đ˛ŅŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐēОда ҁ `async` и `await` ĐēŅ€Đ°Ņ‚ĐēĐž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ÂĢŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧаĐŧиÂģ. Đ­Ņ‚Đž ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸ĐŧĐž ҁ ĐēĐģŅŽŅ‡ĐĩвОК ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚ŅŒŅŽ Go — ÂĢgoroutinesÂģ. -В ŅĐ°ĐŧĐžĐŧ ĐŊĐ°Ņ‡Đ°ĐģĐĩ ĐąŅ‹Đģа Ņ‚Đ°ĐēĐ°Ņ Ņ„Ņ€Đ°ĐˇĐ°: +## ЗаĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ { #conclusion } -> ĐĄĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ Python ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đē҃ Ņ‚Đ°Đē ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧĐžĐŗĐž -**"Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊĐžĐŗĐž ĐēОда"** ĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐžĐŧ ĐŊаĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ **"ŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ"** ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ -ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° **`async` и `await`**. +ВĐĩŅ€ĐŊŅ‘ĐŧŅŅ Đē Ņ‚ĐžĐš ĐļĐĩ Ņ„Ņ€Đ°ĐˇĐĩ: -ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛ŅŅ‘ Đ´ĐžĐģĐļĐŊĐž ĐˇĐ˛ŅƒŅ‡Đ°Ņ‚ŅŒ ĐŋĐžĐŊŅŅ‚ĐŊĐĩĐĩ. ✨ +> ĐĄĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ Python ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ **ÂĢĐ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ĐēОдÂģ** ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **ÂĢŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧÂģ** (coroutines) и ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° **`async` и `await`**. -На ŅŅ‚ĐžĐŧ ĐžŅĐŊОваĐŊа Ņ€Đ°ĐąĐžŅ‚Đ° FastAPI (ĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐžĐŧ Starlette), и иĐŧĐĩĐŊĐŊĐž ŅŅ‚Đž -ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐĩĐŗĐž Đ˛Ņ‹ŅĐžĐēŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. +ĐĸĐĩĐŋĐĩŅ€ŅŒ ŅŅ‚Đž Đ´ĐžĐģĐļĐŊĐž ĐˇĐ˛ŅƒŅ‡Đ°Ņ‚ŅŒ ĐŋĐžĐŊŅŅ‚ĐŊĐĩĐĩ. ✨ -## ĐžŅ‡ĐĩĐŊҌ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ +ИĐŧĐĩĐŊĐŊĐž ŅŅ‚Đž ÂĢдвиĐļĐĩŅ‚Âģ FastAPI (҇ĐĩŅ€ĐĩС Starlette) и ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ŅŅ‚ĐžĐģҌ вĐŋĐĩŅ‡Đ°Ņ‚ĐģŅŅŽŅ‰ŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. -/// warning +## ĐžŅ‡ĐĩĐŊҌ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ { #very-technical-details } -Đ­Ņ‚ĐžŅ‚ Ņ€Đ°ĐˇĐ´ĐĩĐģ Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž. +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ -ЗдĐĩҁҌ ĐŋŅ€Đ¸Đ˛ĐžĐ´ŅŅ‚ŅŅ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐŗĐž ŅƒŅŅ‚Ņ€ĐžĐšŅŅ‚Đ˛Đ° **FastAPI**. +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ŅŅ‚ĐžŅ‚ Ņ€Đ°ĐˇĐ´ĐĩĐģ ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ. -Но ĐĩҁĐģи Đ˛Ņ‹ ОйĐģадаĐĩŅ‚Đĩ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐŧи СĐŊаĐŊĐ¸ŅĐŧи (ĐēĐžŅ€ŅƒŅ‚Đ¸ĐŊŅ‹, ĐŋĐžŅ‚ĐžĐēи, ĐąĐģĐžĐēĐ¸Ņ€ĐžĐ˛Đēа и Ņ‚. Đ´.) -и ваĐŧ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐž, ĐēаĐē FastAPI ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ `async def` в ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚ ĐžĐąŅ‹Ņ‡ĐŊҋ҅ `def`, -Ņ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ даĐģҌ҈Đĩ. +ЗдĐĩҁҌ — ĐžŅ‡ĐĩĐŊҌ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ Đž Ņ‚ĐžĐŧ, ĐēаĐē **FastAPI** Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ÂĢĐŋОд ĐēаĐŋĐžŅ‚ĐžĐŧÂģ. + +Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēĐ¸Ņ… СĐŊаĐŊиК (ŅĐžĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹, ĐŋĐžŅ‚ĐžĐēи, ĐąĐģĐžĐēĐ¸Ņ€ĐžĐ˛Đēи и Ņ‚.Đ´.) и ваĐŧ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐž, ĐēаĐē FastAPI ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ `async def` ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ҁ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def`, — вĐŋĐĩŅ€Ņ‘Đ´. /// -### Đ¤ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸ +### Đ¤ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸ { #path-operation-functions } -ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ҁ ĐēĐģŅŽŅ‡ĐĩĐ˛Ņ‹Đŧ ҁĐģОвОĐŧ `def` -вĐŧĐĩŅŅ‚Đž `async def`, FastAPI ĐžĐļидаĐĩŅ‚ ĐĩŅ‘ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ, СаĐŋŅƒŅŅ‚Đ¸Đ˛ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ вО вĐŊĐĩ҈ĐŊĐĩĐŧ -Đŋ҃ĐģĐĩ ĐŋĐžŅ‚ĐžĐēОв, а ĐŊĐĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (ŅŅ‚Đž ĐąŅ‹ СайĐģĐžĐēĐ¸Ņ€ĐžĐ˛Đ°ĐģĐž ҁĐĩŅ€Đ˛ĐĩŅ€). +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩŅ‚Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸* ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def` вĐŧĐĩŅŅ‚Đž `async def`, ĐžĐŊа СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ вО вĐŊĐĩ҈ĐŊĐĩĐŧ Đŋ҃ĐģĐĩ ĐŋĐžŅ‚ĐžĐēОв, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐˇĐ°Ņ‚ĐĩĐŧ ÂĢĐžĐļидаĐĩŅ‚ŅŅÂģ, вĐŧĐĩŅŅ‚Đž ĐŋŅ€ŅĐŧĐžĐŗĐž Đ˛Ņ‹ĐˇĐžĐ˛Đ° (ĐŋŅ€ŅĐŧОК Đ˛Ņ‹ĐˇĐžĐ˛ СайĐģĐžĐēĐ¸Ņ€ĐžĐ˛Đ°Đģ ĐąŅ‹ ҁĐĩŅ€Đ˛ĐĩŅ€). -Đ•ŅĐģи Ņ€Đ°ĐŊĐĩĐĩ Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи Đ´Ņ€ŅƒĐŗĐžĐš Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊŅ‹Đš ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ иĐŊĐ°Ņ‡Đĩ, -и ĐŋŅ€Đ¸Đ˛Ņ‹ĐēĐģи ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Ņ‹Đĩ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸* ҇ĐĩŅ€ĐĩС `def` Ņ€Đ°Đ´Đ¸ -ĐŊĐĩСĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐŋŅ€Đ¸Ņ€ĐžŅŅ‚Đ° ҁĐēĐžŅ€ĐžŅŅ‚Đ¸ (ĐŋĐžŅ€ŅĐ´Đēа 100 ĐŊаĐŊĐžŅĐĩĐē҃ĐŊĐ´), ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, -Ņ‡Ņ‚Đž ҁ **FastAPI** Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊŅ‹Đš ŅŅ„Ņ„ĐĩĐēŅ‚. В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ йОĐģҌ҈Đĩ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ -`async def`, ĐĩҁĐģи Ņ‚ĐžĐģҌĐēĐž *Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐēОд, ĐŋŅ€Đ¸Đ˛ĐžĐ´ŅŅ‰Đ¸Đš -Đē ĐąĐģĐžĐēĐ¸Ņ€ĐžĐ˛ĐēĐĩ I/O. - +Đ•ŅĐģи Đ˛Ņ‹ ĐŋŅ€Đ¸ŅˆĐģи иС Đ´Ņ€ŅƒĐŗĐžĐŗĐž async-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ иĐŊĐ°Ņ‡Đĩ, и ĐŋŅ€Đ¸Đ˛Ņ‹ĐēĐģи ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ Ņ‚Ņ€Đ¸Đ˛Đ¸Đ°ĐģҌĐŊŅ‹Đĩ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸*, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‰Đ¸Đĩ Ņ‚ĐžĐģҌĐēĐž Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ, ҇ĐĩŅ€ĐĩС ĐŋŅ€ĐžŅŅ‚ĐžĐš `def` Ņ€Đ°Đ´Đ¸ ĐēŅ€ĐžŅˆĐĩ҇ĐŊОК Đ˛Ņ‹ĐŗĐžĐ´Ņ‹ в ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ (ĐžĐēĐžĐģĐž 100 ĐŊаĐŊĐžŅĐĩĐē҃ĐŊĐ´), ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ: в **FastAPI** ŅŅ„Ņ„ĐĩĐēŅ‚ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊŅ‹Đŧ. В Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐģŅƒŅ‡ŅˆĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `async def`, ĐĩҁĐģи Ņ‚ĐžĐģҌĐēĐž Đ˛Đ°ŅˆĐ¸ *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸* ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ĐēОд, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‰Đ¸Đš ĐąĐģĐžĐēĐ¸Ņ€ŅƒŅŽŅ‰Đ¸Đš I/O. - -Но в ĐģŅŽĐąĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ вĐĩĐģиĐēа вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒ, Ņ‡Ņ‚Đž **FastAPI** [ĐžĐēаĐļĐĩŅ‚ŅŅ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ](index.md#_11){.internal-link target=_blank} -Đ´Ņ€ŅƒĐŗĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа (иĐģи Ņ…ĐžŅ‚Ņ ĐąŅ‹ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ҁ ĐŊиĐŧ). +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, в ĐžĐąĐžĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… вĐĩĐģиĐēа вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒ, Ņ‡Ņ‚Đž **FastAPI** [Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ](index.md#performance){.internal-link target=_blank} (иĐģи ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸Đŧ) ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Đŧ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ. -### Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ +### Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ { #dependencies } -ĐĸĐž ĐļĐĩ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧ. Đ•ŅĐģи ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `def`, а ĐŊĐĩ `async def`, -ĐžĐŊа СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ вО вĐŊĐĩ҈ĐŊĐĩĐŧ Đŋ҃ĐģĐĩ ĐŋĐžŅ‚ĐžĐēОв. +ĐĸĐž ĐļĐĩ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē [ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧ](tutorial/dependencies/index.md){.internal-link target=_blank}. Đ•ŅĐģи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ — ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `def`, а ĐŊĐĩ `async def`, ĐžĐŊа СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ вО вĐŊĐĩ҈ĐŊĐĩĐŧ Đŋ҃ĐģĐĩ ĐŋĐžŅ‚ĐžĐēОв. -### ĐŸĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ +### ĐŸĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ { #sub-dependencies } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐąŅŠŅĐ˛Đ¸Ņ‚ŅŒ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ҁҁҋĐģĐ°ŅŽŅ‰Đ¸Ņ…ŅŅ Đ´Ņ€ŅƒĐŗ ĐŊа Đ´Ņ€ŅƒĐŗĐ° ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš и ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš -(в видĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ ĐŋŅ€Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊии Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸). КаĐēиĐĩ-Ņ‚Đž ĐąŅƒĐ´ŅƒŅ‚ ŅĐžĐˇĐ´Đ°ĐŊŅ‹ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `async def`, -Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ҇ĐĩŅ€ĐĩС `def`, и Ņ‚Đ°ĐēĐ°Ņ ҁ҅ĐĩĐŧа вĐŋĐžĐģĐŊĐĩ Ņ€Đ°ĐąĐžŅ‚ĐžŅĐŋĐžŅĐžĐąĐŊа. Đ¤ŅƒĐŊĐēŅ†Đ¸Đ¸, -ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `def` ĐąŅƒĐ´ŅƒŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒŅŅ ĐŊа вĐŊĐĩ҈ĐŊĐĩĐŧ ĐŋĐžŅ‚ĐžĐēĐĩ (иС Đŋ҃Đģа), -а ĐŊĐĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `await`. +ĐŖ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš и [ĐŋĐžĐ´ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank}, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҂ҀĐĩĐąŅƒŅŽŅ‚ Đ´Ņ€ŅƒĐŗ Đ´Ņ€ŅƒĐŗĐ° (в видĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиК Ņ„ŅƒĐŊĐēŅ†Đ¸Đš): Ņ‡Đ°ŅŅ‚ŅŒ иС ĐŊĐ¸Ņ… ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊа ҁ `async def`, а Ņ‡Đ°ŅŅ‚ŅŒ — ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def`. Đ’ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ, а Ņ‚Đĩ, Ņ‡Ņ‚Đž ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊŅ‹ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def`, ĐąŅƒĐ´ŅƒŅ‚ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒŅŅ вО вĐŊĐĩ҈ĐŊĐĩĐŧ ĐŋĐžŅ‚ĐžĐēĐĩ (иС Đŋ҃Đģа), а ĐŊĐĩ ÂĢĐžĐļĐ¸Đ´Đ°Ņ‚ŅŒŅŅÂģ. -### Đ”Ņ€ŅƒĐŗĐ¸Đĩ ҁĐģ҃ĐļĐĩĐąĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ +### Đ”Ņ€ŅƒĐŗĐ¸Đĩ ҁĐģ҃ĐļĐĩĐąĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ { #other-utility-functions } -Đ›ŅŽĐąŅ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ҁĐģ҃ĐļĐĩĐąĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ -ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ `def` иĐģи `async def`. FastAPI ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ вĐģĐ¸ŅŅ‚ŅŒ ĐŊа Ņ‚Đž, ĐēаĐē Đ˛Ņ‹ -Đ¸Ņ… СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ. +Đ›ŅŽĐąŅ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ҁĐģ҃ĐļĐĩĐąĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, ĐŧĐžĐļĐŊĐž ĐžĐąŅŠŅĐ˛ĐģŅŅ‚ŅŒ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ `def` иĐģи `async def`, и FastAPI ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ вĐģĐ¸ŅŅ‚ŅŒ ĐŊа Ņ‚Đž, ĐēаĐē Đ˛Ņ‹ Đ¸Ņ… Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚Đĩ. -Đ­Ņ‚Đ¸Đŧ ĐžĐŊи ĐžŅ‚ĐģĐ¸Ņ‡Đ°ŅŽŅ‚ŅŅ ĐžŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ FastAPI Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž: -*Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋŅƒŅ‚Đ¸* и ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. +В ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ FastAPI Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ Са Đ˛Đ°Ņ: *Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸-ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸* и ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. -Đ•ŅĐģи ҁĐģ҃ĐļĐĩĐąĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊа ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `def`, ĐžĐŊа ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐˇĐ˛Đ°ĐŊа ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ -(ĐēаĐē Đ˛Ņ‹ и ĐŊаĐŋĐ¸ŅĐ°Đģи в ĐēОдĐĩ), а ĐŊĐĩ в ĐžŅ‚Đ´ĐĩĐģҌĐŊĐžĐŧ ĐŋĐžŅ‚ĐžĐēĐĩ. Đ•ŅĐģи ĐļĐĩ ĐžĐŊа ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊа ҁ -ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `async def`, ĐĩŅ‘ Đ˛Ņ‹ĐˇĐžĐ˛ Đ´ĐžĐģĐļĐĩĐŊ ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģŅŅ‚ŅŒŅŅ ҁ ĐžĐļидаĐŊиĐĩĐŧ ҇ĐĩŅ€ĐĩС `await`. +Đ•ŅĐģи ҁĐģ҃ĐļĐĩĐąĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ — ĐžĐąŅ‹Ņ‡ĐŊĐ°Ņ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ҁ `def`, ĐžĐŊа ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐˇĐ˛Đ°ĐŊа ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (ĐēаĐē Đ˛Ņ‹ и ĐŋĐ¸ŅˆĐĩŅ‚Đĩ в ĐēОдĐĩ), ĐŊĐĩ в Đŋ҃ĐģĐĩ ĐŋĐžŅ‚ĐžĐēОв; ĐĩҁĐģи Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊа ҁ `async def`, Ņ‚ĐžĐŗĐ´Đ° ĐŋŅ€Đ¸ ĐĩŅ‘ Đ˛Ņ‹ĐˇĐžĐ˛Đĩ в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ Đ˛Ņ‹ Đ´ĐžĐģĐļĐŊŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `await`. --- - -Đ•Ņ‰Ņ‘ Ņ€Đ°Đˇ ĐŋĐžĐ˛Ņ‚ĐžŅ€Đ¸Đŧ, Ņ‡Ņ‚Đž Đ˛ŅĐĩ ŅŅ‚Đ¸ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ ĐŋĐžĐģĐĩСĐŊŅ‹, Ņ‚ĐžĐģҌĐēĐž ĐĩҁĐģи Đ˛Ņ‹ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊĐž Đ¸Ņ… Đ¸ŅĐēаĐģи. +ĐĄĐŊОва: ŅŅ‚Đž ĐžŅ‡ĐĩĐŊҌ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸, ĐŋĐžĐģĐĩСĐŊŅ‹Đĩ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Ņ‚ĐžĐģҌĐēĐž ĐĩҁĐģи Đ˛Ņ‹ ҆ĐĩĐģĐĩĐŊаĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊĐž Đ¸Ņ… Đ¸Ņ‰ĐĩŅ‚Đĩ. -В ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŋŅ€ĐžŅŅ‚Đž ОСĐŊаĐēĐžĐŧŅŒŅ‚ĐĩҁҌ ҁ ĐžŅĐŊОвĐŊŅ‹Đŧи ĐŋŅ€Đ¸ĐŊŅ†Đ¸ĐŋаĐŧи в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ Đ˛Ņ‹ŅˆĐĩ: НĐĩŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи?. +ИĐŊĐ°Ņ‡Đĩ ваĐŧ Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒŅŅ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´Đ°Ņ†Đ¸ŅĐŧи иС Ņ€Đ°ĐˇĐ´ĐĩĐģа Đ˛Ņ‹ŅˆĐĩ: НĐĩŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи?. diff --git a/docs/ru/docs/benchmarks.md b/docs/ru/docs/benchmarks.md index 259dca8e6..612b39f70 100644 --- a/docs/ru/docs/benchmarks.md +++ b/docs/ru/docs/benchmarks.md @@ -1,37 +1,34 @@ -# ЗаĐŧĐĩҀҋ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ +# БĐĩĐŊ҇ĐŧĐ°Ņ€Đēи (Ņ‚Đĩҁ҂ҋ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸) { #benchmarks } -НĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧŅ‹Đĩ Ņ‚Đĩҁ҂ҋ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК ĐžŅ‚ TechEmpower ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚, Ņ‡Ņ‚Đž **FastAPI** ĐŋОд ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ Uvicorn ОдиĐŊ иС ŅĐ°Đŧҋ҅ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Ņ… Python-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв и ŅƒŅŅ‚ŅƒĐŋаĐĩŅ‚ Ņ‚ĐžĐģҌĐēĐž Starlette и Uvicorn (ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ŅŅ в FastAPI). (*) +НĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧŅ‹Đĩ ĐąĐĩĐŊ҇ĐŧĐ°Ņ€Đēи TechEmpower ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚, Ņ‡Ņ‚Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI** ĐŋОд ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ Uvicorn — ОдĐŊи иС ŅĐ°Đŧҋ҅ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Ņ… Pythonâ€‘Ņ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ŅƒŅŅ‚ŅƒĐŋĐ°ŅŽŅ‰Đ¸Đĩ Ņ‚ĐžĐģҌĐēĐž Starlette и ŅĐ°ĐŧĐžĐŧ҃ Uvicorn (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ FastAPI). -Но ĐŋŅ€Đ¸ ĐŋŅ€ĐžŅĐŧĐžŅ‚Ņ€Đĩ и ŅŅ€Đ°Đ˛ĐŊĐĩĐŊии СаĐŧĐĩŅ€ĐžĐ˛ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ в Đ˛Đ¸Đ´Ņƒ ĐŊиĐļĐĩĐžĐŋĐ¸ŅĐ°ĐŊĐŊĐžĐĩ. +Но ĐŋŅ€Đ¸ ĐŋŅ€ĐžŅĐŧĐžŅ‚Ņ€Đĩ ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēОв и ŅŅ€Đ°Đ˛ĐŊĐĩĐŊиК ҁĐģĐĩĐ´ŅƒĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ в Đ˛Đ¸Đ´Ņƒ ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐĩ. -## ЗаĐŧĐĩҀҋ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ и ҁĐēĐžŅ€ĐžŅŅ‚Đ¸ +## БĐĩĐŊ҇ĐŧĐ°Ņ€Đēи и ҁĐēĐžŅ€ĐžŅŅ‚ŅŒ { #benchmarks-and-speed } -В ĐŋОдОйĐŊҋ҅ Ņ‚ĐĩŅŅ‚Đ°Ņ… Ņ‡Đ°ŅŅ‚Đž ĐŧĐžĐļĐŊĐž ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Ņ€Đ°ĐˇĐŊĐžĐŗĐž Ņ‚Đ¸Đŋа ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ŅŽŅ‚ Đ´Ņ€ŅƒĐŗ ҁ Đ´Ņ€ŅƒĐŗĐžĐŧ, ĐēаĐē аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đĩ. +ĐŸŅ€Đ¸ ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐēĐĩ ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēОв Ņ‡Đ°ŅŅ‚Đž ĐŧĐžĐļĐŊĐž ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Ņ€Đ°ĐˇĐŊҋ҅ Ņ‚Đ¸ĐŋОв ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ŅŽŅ‚ ĐēаĐē ŅĐēвиваĐģĐĩĐŊŅ‚ĐŊŅ‹Đĩ. -В Ņ‡Đ°ŅŅ‚ĐŊĐžŅŅ‚Đ¸, ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ŅŽŅ‚ вĐŧĐĩҁ҂Đĩ Uvicorn, Starlette и FastAPI (ҁҀĐĩди ĐŧĐŊĐžĐŗĐ¸Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛). +В Ņ‡Đ°ŅŅ‚ĐŊĐžŅŅ‚Đ¸, Ņ‡Đ°ŅŅ‚Đž ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ŅŽŅ‚ вĐŧĐĩҁ҂Đĩ Uvicorn, Starlette и FastAPI (ҁҀĐĩди ĐŧĐŊĐžĐŗĐ¸Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛). -ЧĐĩĐŧ ĐŋŅ€ĐžŅ‰Đĩ ĐŋŅ€ĐžĐąĐģĐĩĐŧа, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Ņ€ĐĩŅˆĐ°ĐĩŅ‚ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, Ņ‚ĐĩĐŧ Đ˛Ņ‹ŅˆĐĩ ĐĩĐŗĐž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. И йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Ņ‚ĐĩŅŅ‚ĐžĐ˛ ĐŊĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅŽŅ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ. +ЧĐĩĐŧ ĐŋŅ€ĐžŅ‰Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ°, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Ņ€ĐĩŅˆĐ°ĐĩŅ‚ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, Ņ‚ĐĩĐŧ Đ˛Ņ‹ŅˆĐĩ ĐĩĐŗĐž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. И йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž ĐąĐĩĐŊ҇ĐŧĐ°Ņ€ĐēОв ĐŊĐĩ Ņ‚ĐĩŅŅ‚Đ¸Ņ€ŅƒŅŽŅ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ. -ИĐĩŅ€Đ°Ņ€Ņ…Đ¸Ņ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ иĐŧĐĩĐĩŅ‚ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đš вид: +ИĐĩŅ€Đ°Ņ€Ņ…Đ¸Ņ Đ˛Ņ‹ĐŗĐģŅĐ´Đ¸Ņ‚ Ņ‚Đ°Đē: * **Uvicorn**: ASGI-ҁĐĩŅ€Đ˛ĐĩŅ€ - * **Starlette** (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Uvicorn): вĐĩĐą-ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē - * **FastAPI** (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Starlette): API-ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē ҁ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи Ņ„ŅƒĐŊĐēŅ†Đ¸ŅĐŧи Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API, ҁ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ĐĩĐš даĐŊĐŊҋ҅ и Ņ‚.Đ´. + * **Starlette**: (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Uvicorn) вĐĩĐą-ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē + * **FastAPI**: (Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Starlette) API-ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē ҁ Ņ€ŅĐ´ĐžĐŧ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API, вĐēĐģŅŽŅ‡Đ°Ņ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅ и Ņ‚. Đŋ. * **Uvicorn**: - * Đ‘ŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ĐŊаиĐģŅƒŅ‡ŅˆŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ, Ņ‚Đ°Đē ĐēаĐē ĐŊĐĩ иĐŧĐĩĐĩŅ‚ йОĐģŅŒŅˆĐžĐŗĐž ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐēОда, ĐēŅ€ĐžĐŧĐĩ ŅĐ°ĐŧĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. - * Đ’Ņ‹ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐ¸ŅĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊа Uvicorn ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐģĐž ĐąŅ‹, Ņ‡Ņ‚Đž Đ’Đ°Ņˆ ĐēОд Đ´ĐžĐģĐļĐĩĐŊ вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ вĐĩҁҌ - ĐēОд, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đš Starlette (иĐģи **FastAPI**). И ĐĩҁĐģи Đ’Ņ‹ Ņ‚Đ°Đē ŅĐ´ĐĩĐģаĐĩŅ‚Đĩ, Ņ‚Đž в ĐēĐžĐŊĐĩ҇ĐŊĐžĐŧ Đ¸Ņ‚ĐžĐŗĐĩ Đ’Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ Ņ‚Đĩ ĐļĐĩ ĐŊаĐēĐģадĐŊŅ‹Đĩ Ņ€Đ°ŅŅ…ĐžĐ´Ņ‹, Ņ‡Ņ‚Đž и ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, ĐŧиĐŊиĐŧĐ¸ĐˇĐ¸Ņ€ŅƒŅŽŅ‰ĐĩĐŗĐž ĐēОд Đ’Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ и Đ’Đ°ŅˆĐ¸ ĐžŅˆĐ¸ĐąĐēи. - * Uvicorn ĐŋОдĐģĐĩĐļĐ¸Ņ‚ ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ҁ Daphne, Hypercorn, uWSGI и Đ´Ņ€ŅƒĐŗĐ¸Đŧи вĐĩĐą-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Đŧи. - + * Đ‘ŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ĐŊаиĐģŅƒŅ‡ŅˆŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ, Ņ‚Đ°Đē ĐēаĐē ĐŋĐžĐŧиĐŧĐž ŅĐ°ĐŧĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ҃ ĐŊĐĩĐŗĐž ĐŊĐĩĐŧĐŊĐžĐŗĐž Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐēОда. + * Đ’Ņ‹ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐ¸ŅĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŊа Uvicorn. Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐģĐž ĐąŅ‹, Ņ‡Ņ‚Đž Đ’Đ°Ņˆ ĐēОд Đ´ĐžĐģĐļĐĩĐŊ вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ вĐĩҁҌ ĐēОд, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đš Starlette (иĐģи **FastAPI**). И ĐĩҁĐģи Đ’Ņ‹ Ņ‚Đ°Đē ŅĐ´ĐĩĐģаĐĩŅ‚Đĩ, Ņ‚Đž в ĐēĐžĐŊĐĩ҇ĐŊĐžĐŧ Đ¸Ņ‚ĐžĐŗĐĩ Đ’Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ Ņ‚Đĩ ĐļĐĩ ĐŊаĐēĐģадĐŊŅ‹Đĩ Ņ€Đ°ŅŅ…ĐžĐ´Ņ‹, Ņ‡Ņ‚Đž и ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, ĐŧиĐŊиĐŧĐ¸ĐˇĐ¸Ņ€ŅƒŅŽŅ‰ĐĩĐŗĐž ĐēОд Đ’Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ и Đ’Đ°ŅˆĐ¸ ĐžŅˆĐ¸ĐąĐēи. + * Đ•ŅĐģи Đ’Ņ‹ ŅŅ€Đ°Đ˛ĐŊиваĐĩŅ‚Đĩ Uvicorn, ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ĐšŅ‚Đĩ ĐĩĐŗĐž ҁ Daphne, Hypercorn, uWSGI и Ņ‚. Đ´. — ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Đŧи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. * **Starlette**: - * Đ‘ŅƒĐ´ĐĩŅ‚ ŅƒŅŅ‚ŅƒĐŋĐ°Ņ‚ŅŒ Uvicorn ĐŋĐž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸. ФаĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи Starlette ҃ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ Uvicorn и иС-Са Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ йОĐģҌ҈ĐĩĐŗĐž ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° ĐēОда ĐžĐŊ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ, ҇ĐĩĐŧ Uvicorn. - * Đ—Đ°Ņ‚Đž ĐžĐŊ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ВаĐŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŋŅ€ĐžŅŅ‚Ņ‹Ņ… вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК ҁ ĐžĐąŅ€Đ°ĐąĐžŅ‚ĐēОК ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚ĐžĐ˛ URL и Ņ‚.Đ´. - * Starlette ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°Ņ‚ŅŒ ҁ Sanic, Flask, Django и Đ´Ņ€ŅƒĐŗĐ¸Đŧи вĐĩĐą-҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēаĐŧи (иĐģи ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēаĐŧи). - + * Đ‘ŅƒĐ´ĐĩŅ‚ ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŧ ĐŧĐĩҁ҂Đĩ ĐŋĐž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ ĐŋĐžŅĐģĐĩ Uvicorn. ФаĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи Starlette СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ ĐŋОд ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ Uvicorn, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐžĐŊ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž ÂĢĐŧĐĩĐ´ĐģĐĩĐŊĐŊĐĩĐĩÂģ Uvicorn из‑за Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ йОĐģҌ҈ĐĩĐŗĐž ĐžĐąŅŠŅ‘Đŧа ĐēОда. + * Đ—Đ°Ņ‚Đž ĐžĐŊ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ ВаĐŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŋŅ€ĐžŅŅ‚Ņ‹Ņ… вĐĩб‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК ҁ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ¸ĐˇĐ°Ņ†Đ¸ĐĩĐš ĐŋĐž ĐŋŅƒŅ‚ŅĐŧ и Ņ‚. Đŋ. + * Đ•ŅĐģи Đ’Ņ‹ ŅŅ€Đ°Đ˛ĐŊиваĐĩŅ‚Đĩ Starlette, ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ĐšŅ‚Đĩ ĐĩĐŗĐž ҁ Sanic, Flask, Django и Ņ‚. Đ´. — вĐĩĐąâ€‘Ņ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēаĐŧи (иĐģи ĐŧиĐēŅ€ĐžŅ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēаĐŧи). * **FastAPI**: - * ĐĸаĐē ĐļĐĩ ĐēаĐē Starlette Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Uvicorn и ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ ĐŊĐĩĐŗĐž, **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Starlette, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐžĐŊ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ Starlette. - * FastAPI ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ йОĐģҌ҈Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš ĐŋОвĐĩҀ҅ Starlette, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊавĐĩŅ€ĐŊŅĐēа ВаĐŧ ĐŋĐžĐŊĐ°Đ´ĐžĐąŅŅ‚ŅŅ ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии API, Ņ‚Đ°ĐēиĐĩ ĐēаĐē ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа даĐŊĐŊҋ҅ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ. В дОвĐĩŅĐžĐē Đ’Ņ‹ Đĩ҉ґ и ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ (Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ даĐļĐĩ ĐŊĐĩ ŅƒĐ˛ĐĩĐģĐ¸Ņ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐŊаĐēĐģадĐŊŅ‹Đĩ Ņ€Đ°ŅŅ…ĐžĐ´Ņ‹ ĐŋŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, Ņ‚Đ°Đē ĐēаĐē ĐžĐŊа ŅĐžĐˇĐ´Đ°ĐĩŅ‚ŅŅ ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ). - * Đ•ŅĐģи Đ’Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI, а Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Starlette ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (иĐģи Đ´Ņ€ŅƒĐŗĐžĐš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ Đ˛Ņ€ĐžĐ´Đĩ Sanic, Flask, Responder и Ņ‚.Đ´.), ВаĐŧ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐąŅ‹ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅. ĐĸĐž ĐĩŅŅ‚ŅŒ, в Đ¸Ņ‚ĐžĐŗĐĩ, Đ’Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ иĐŧĐĩĐģĐž ĐąŅ‹ Ņ‚Đ°ĐēиĐĩ ĐļĐĩ ĐŊаĐēĐģадĐŊŅ‹Đĩ Ņ€Đ°ŅŅ…ĐžĐ´Ņ‹, ĐēаĐē ĐĩҁĐģи ĐąŅ‹ ĐžĐŊĐž ĐąŅ‹ĐģĐž ŅĐžĐˇĐ´Đ°ĐŊĐž ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ FastAPI. И вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ ŅĐžĐąĐžĐš ŅĐ°ĐŧŅ‹Đš йОĐģŅŒŅˆĐžĐš ĐžĐąŅŠŅ‘Đŧ ĐēОда, ĐŊаĐŋĐ¸ŅĐ°ĐŊĐŊĐžĐŗĐž в ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ…. - * ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ FastAPI Đ’Ņ‹ ĐŋĐžŅ‚Ņ€Đ°Ņ‚Đ¸Ņ‚Đĩ ĐŧĐĩĐŊҌ҈Đĩ Đ˛Ņ€ĐĩĐŧĐĩĐŊи ĐŊа Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đē҃, ҃ĐŧĐĩĐŊŅŒŅˆĐ¸Ņ‚Đĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐžŅˆĐ¸ĐąĐžĐē, ŅŅ‚Ņ€ĐžĐē ĐēОда и, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ Ņ‚Ņƒ ĐļĐĩ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ (иĐģи ĐģŅƒŅ‡ŅˆĐĩ), ĐēаĐē и ĐĩҁĐģи ĐąŅ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи ĐĩĐŗĐž (ĐŋĐžŅĐēĐžĐģҌĐē҃ ВаĐŧ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐąŅ‹ Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐĩĐŗĐž вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ в ŅĐ˛ĐžĐĩĐŧ ĐēОдĐĩ). - * FastAPI Đ´ĐžĐģĐļĐŊĐž ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°Ņ‚ŅŒ ҁ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēаĐŧи вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК (иĐģи ĐŊĐ°ĐąĐžŅ€Đ°Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛), ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ŅŽŅ‚ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅, а Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Flask-apispec, NestJS, Molten и иĐŧ ĐŋОдОйĐŊŅ‹Đĩ. + * ĐĸĐžŅ‡ĐŊĐž Ņ‚Đ°Đē ĐļĐĩ, ĐēаĐē Starlette Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Uvicorn и ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ ĐŊĐĩĐŗĐž, **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Starlette, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ ĐĩĐŗĐž. + * FastAPI ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ йОĐģҌ҈Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš ĐŋОвĐĩҀ҅ Starlette — Ņ‚Đĩ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐžŅ‡Ņ‚Đ¸ Đ˛ŅĐĩĐŗĐ´Đ° ĐŊ҃ĐļĐŊŅ‹ ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии API, Ņ‚Đ°ĐēиĐĩ ĐēаĐē ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅. В дОвĐĩŅĐžĐē Đ’Ņ‹ Đĩ҉ґ и ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ (Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ даĐļĐĩ ĐŊĐĩ ŅƒĐ˛ĐĩĐģĐ¸Ņ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐŊаĐēĐģадĐŊŅ‹Đĩ Ņ€Đ°ŅŅ…ĐžĐ´Ņ‹ ĐŋŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, Ņ‚Đ°Đē ĐēаĐē ĐžĐŊа ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ŅŅ ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ). + * Đ•ŅĐģи ĐąŅ‹ Đ’Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи FastAPI, а Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи Starlette ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (иĐģи Đ´Ņ€ŅƒĐŗĐžĐš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ Đ˛Ņ€ĐžĐ´Đĩ Sanic, Flask, Responder и Ņ‚. Đ´.), ВаĐŧ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐąŅ‹ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅. ĐĸĐž ĐĩŅŅ‚ŅŒ, в Đ¸Ņ‚ĐžĐŗĐĩ, Đ’Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ иĐŧĐĩĐģĐž ĐąŅ‹ Ņ‚Đ°ĐēиĐĩ ĐļĐĩ ĐŊаĐēĐģадĐŊŅ‹Đĩ Ņ€Đ°ŅŅ…ĐžĐ´Ņ‹, ĐēаĐē ĐĩҁĐģи ĐąŅ‹ ĐžĐŊĐž ĐąŅ‹ĐģĐž ŅĐžĐˇĐ´Đ°ĐŊĐž ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ FastAPI. И вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ваĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ и ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ ŅĐžĐąĐžĐš ŅĐ°ĐŧŅ‹Đš йОĐģŅŒŅˆĐžĐš ĐžĐąŅŠŅ‘Đŧ ĐēОда, ĐŊаĐŋĐ¸ŅĐ°ĐŊĐŊĐžĐŗĐž в ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ…. + * ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ FastAPI, Đ’Ņ‹ ŅĐēĐžĐŊĐžĐŧĐ¸Ņ‚Đĩ Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи, ҃ĐŧĐĩĐŊŅŒŅˆĐ°ĐĩŅ‚Đĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐžŅˆĐ¸ĐąĐžĐē, ŅŅ‚Ņ€ĐžĐē ĐēОда и, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ Ņ‚Ņƒ ĐļĐĩ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ (иĐģи ĐģŅƒŅ‡ŅˆĐĩ), ĐēаĐē и ĐĩҁĐģи ĐąŅ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи ĐĩĐŗĐž (ĐŋĐžŅĐēĐžĐģҌĐē҃ ВаĐŧ ĐŋŅ€Đ¸ŅˆĐģĐžŅŅŒ ĐąŅ‹ Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐĩĐŗĐž вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ в ŅĐ˛ĐžŅ‘Đŧ ĐēОдĐĩ). + * Đ•ŅĐģи Đ’Ņ‹ ŅŅ€Đ°Đ˛ĐŊиваĐĩŅ‚Đĩ FastAPI, ŅŅ€Đ°Đ˛ĐŊĐ¸Đ˛Đ°ĐšŅ‚Đĩ ĐĩĐŗĐž ҁ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ вĐĩб‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК (иĐģи ĐŊĐ°ĐąĐžŅ€ĐžĐŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛), ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ваĐģĐ¸Đ´Đ°Ņ†Đ¸ŅŽ даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ŅŽ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Flask-apispec, NestJS, Molten и иĐŧ ĐŋОдОйĐŊŅ‹Đĩ. Đ¤Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đēи ҁ иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊОК Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК ваĐģĐ¸Đ´Đ°Ņ†Đ¸ĐĩĐš даĐŊĐŊҋ҅, ҁĐĩŅ€Đ¸Đ°ĐģĐ¸ĐˇĐ°Ņ†Đ¸ĐĩĐš и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš. diff --git a/docs/ru/docs/deployment/cloud.md b/docs/ru/docs/deployment/cloud.md new file mode 100644 index 000000000..a400d1843 --- /dev/null +++ b/docs/ru/docs/deployment/cloud.md @@ -0,0 +1,16 @@ +# РаСвĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ FastAPI ҃ ОйĐģĐ°Ņ‡ĐŊҋ҅ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ĐžĐ˛ { #deploy-fastapi-on-cloud-providers } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи ĐģŅŽĐąĐžĐŗĐž ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ€Đ°ĐˇĐ˛ĐĩŅ€ĐŊŅƒŅ‚ŅŒ ŅĐ˛ĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊа FastAPI. + +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ҃ ĐžŅĐŊОвĐŊҋ҅ ОйĐģĐ°Ņ‡ĐŊҋ҅ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ĐžĐ˛ ĐĩŅŅ‚ŅŒ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đ° ĐŋĐž Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸ŅŽ FastAPI ĐŊа Đ¸Ņ… ĐŋĐģĐ°Ņ‚Ņ„ĐžŅ€ĐŧĐĩ. + +## ОбĐģĐ°Ņ‡ĐŊŅ‹Đĩ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩҀҋ — ҁĐŋĐžĐŊŅĐžŅ€Ņ‹ { #cloud-providers-sponsors } + +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ОйĐģĐ°Ņ‡ĐŊŅ‹Đĩ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩҀҋ ✨ [**ҁĐŋĐžĐŊŅĐ¸Ņ€ŅƒŅŽŅ‚ FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ — ŅŅ‚Đž ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐŊĐĩĐŋŅ€ĐĩŅ€Ņ‹Đ˛ĐŊĐžĐĩ и ĐˇĐ´ĐžŅ€ĐžĐ˛ĐžĐĩ Ņ€Đ°ĐˇĐ˛Đ¸Ņ‚Đ¸Đĩ FastAPI и ĐĩĐŗĐž ŅĐēĐžŅĐ¸ŅŅ‚ĐĩĐŧŅ‹. + +И ŅŅ‚Đž ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ Đ¸Ņ… Đ¸ŅĐēŅ€ĐĩĐŊĐŊŅŽŅŽ ĐŋŅ€Đ¸Đ˛ĐĩŅ€ĐļĐĩĐŊĐŊĐžŅŅ‚ŅŒ FastAPI и ĐĩĐŗĐž ŅĐžĐžĐąŅ‰ĐĩŅŅ‚Đ˛Ņƒ (ваĐŧ): ĐžĐŊи ĐŊĐĩ Ņ‚ĐžĐģҌĐēĐž Ņ…ĐžŅ‚ŅŅ‚ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ваĐŧ Ņ…ĐžŅ€ĐžŅˆĐ¸Đš ҁĐĩŅ€Đ˛Đ¸Ņ, ĐŊĐž и ҁ҂ҀĐĩĐŧŅŅ‚ŅŅ ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐąŅƒĐ´ĐĩŅ‚ Ņ…ĐžŅ€ĐžŅˆĐ¸Đš и ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊŅ‹Đš ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē — FastAPI. 🙇 + +ВозĐŧĐžĐļĐŊĐž, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… ҁĐĩŅ€Đ˛Đ¸ŅŅ‹ и Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ¸Ņ… Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đ°Đŧи: + +* Render +* Railway diff --git a/docs/ru/docs/deployment/concepts.md b/docs/ru/docs/deployment/concepts.md index acfa1f4fe..207d1604d 100644 --- a/docs/ru/docs/deployment/concepts.md +++ b/docs/ru/docs/deployment/concepts.md @@ -1,323 +1,321 @@ -# КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ +# КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ { #deployments-concepts } -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš, ĐŋŅ€Đ¸ĐŧĐĩĐŊŅĐĩĐŧҋ҅ Đ´ĐģŅ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК **FastAPI**, Ņ€Đ°Đ˛ĐŊĐž ĐēаĐē и Đ´ĐģŅ ĐģŅŽĐąŅ‹Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ… Ņ‚Đ¸ĐŋОв вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК, ҁҀĐĩди ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ **ĐŊаийОĐģĐĩĐĩ ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰Đ¸Đš** ҁĐŋĐžŅĐžĐą. +ĐŸŅ€Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI** (и Đ˛ĐžĐžĐąŅ‰Đĩ ĐģŅŽĐąĐžĐŗĐž вĐĩб‑API) ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš, Đž ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ŅŅ‚ĐžĐ¸Ņ‚ Đ´ŅƒĐŧĐ°Ņ‚ŅŒ — ҁ Đ¸Ņ… ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŧĐžĐļĐŊĐž Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ **ĐŊаийОĐģĐĩĐĩ ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰Đ¸Đš** ҁĐŋĐžŅĐžĐą **Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ**. -ХаĐŧŅ‹Đĩ ваĐļĐŊŅ‹Đĩ иС ĐŊĐ¸Ņ…: +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ иС ваĐļĐŊҋ҅ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš: -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS -* ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ПĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. +* БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ -Đ Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ĐŊиĐļĐĩ вĐģĐ¸ŅĐŊиĐĩ ĐēаĐļĐ´ĐžĐŗĐž иС ĐŊĐ¸Ņ… ĐŊа ĐŋŅ€ĐžŅ†Đĩҁҁ **Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ**. +ĐŸĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē ĐžĐŊи вĐģĐ¸ŅŅŽŅ‚ ĐŊа **Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ**. -ĐĐ°ŅˆĐ° ĐēĐžĐŊĐĩ҇ĐŊĐ°Ņ ҆ĐĩĐģҌ - **ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ Đ˛Đ°ŅˆĐĩĐŗĐž API ĐąĐĩСОĐŋĐ°ŅĐŊĐž** и **ĐąĐĩҁĐŋĐĩŅ€ĐĩйОКĐŊĐž**, ҁ ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊŅ‹Đŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ **Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊҋ҅ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛/Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊҋ҅ ĐŧĐ°ŅˆĐ¸ĐŊ). 🚀 +В ĐēĐžĐŊĐĩ҇ĐŊĐžĐŧ Đ¸Ņ‚ĐžĐŗĐĩ ҆ĐĩĐģҌ — **ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ Đ˛Đ°ŅˆĐĩĐŗĐž API** ĐąĐĩСОĐŋĐ°ŅĐŊĐž, **иСйĐĩĐŗĐ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩйОĐĩв** и ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ Ņ€ĐĩŅŅƒŅ€ŅŅ‹** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đĩ ҁĐĩŅ€Đ˛ĐĩҀҋ/Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅ‹Đĩ ĐŧĐ°ŅˆĐ¸ĐŊŅ‹). 🚀 -ЗдĐĩҁҌ Ņ ĐŊĐĩĐŧĐŊĐžĐŗĐž Ņ€Đ°ŅŅĐēаĐļ҃ ВаĐŧ Ой ŅŅ‚Đ¸Ņ… **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅŅ…** и ĐŊадĐĩŅŽŅŅŒ, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ҁĐģĐžĐļĐ¸Ņ‚ŅŅ **иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐžĐĩ ĐŋĐžĐŊиĐŧаĐŊиĐĩ**, ĐēаĐēОК ҁĐŋĐžŅĐžĐą Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊии Đ˛Đ°ŅˆĐĩĐŗĐž API в Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸ŅŅ…, вОСĐŧĐžĐļĐŊĐž, даĐļĐĩ **Đĩ҉ґ ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Ņ…**. +ЗдĐĩҁҌ Ņ ĐŊĐĩĐŧĐŊĐžĐŗĐž Ņ€Đ°ŅŅĐēаĐļ҃ Đž ŅŅ‚Đ¸Ņ… **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅŅ…**, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ Đ˛Đ°Ņ ĐŋĐžŅĐ˛Đ¸ĐģĐ°ŅŅŒ **иĐŊŅ‚ŅƒĐ¸Ņ†Đ¸Ņ**, ĐēаĐē Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ Đ˛Đ°Ņˆ API в Ņ€Đ°ĐˇĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸ŅŅ…, вОСĐŧĐžĐļĐŊĐž даĐļĐĩ в **ĐąŅƒĐ´ŅƒŅ‰Đ¸Ņ…**, ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Đĩ҉ґ ĐŊĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚. -ОзĐŊаĐēĐžĐŧĐ¸Đ˛ŅˆĐ¸ŅŅŒ ҁ ŅŅ‚Đ¸Đŧи ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅĐŧи, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ **ĐžŅ†ĐĩĐŊĐ¸Ņ‚ŅŒ и Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ** ĐģŅƒŅ‡ŅˆĐ¸Đš ҁĐŋĐžŅĐžĐą Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊии **Đ’Đ°ŅˆĐĩĐŗĐž API**. +ĐŖŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ ŅŅ‚Đ¸ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ **ĐžŅ†ĐĩĐŊĐ¸Ņ‚ŅŒ и ҁĐŋŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ** ĐģŅƒŅ‡ŅˆĐ¸Đš ҁĐŋĐžŅĐžĐą Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ **ŅĐ˛ĐžĐ¸Ņ… API**. -В ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ… Ņ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŽ ВаĐŧ **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ Ņ€Đĩ҆ĐĩĐŋ҂ҋ** Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI. +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ… Ņ даĐŧ йОĐģĐĩĐĩ **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ Ņ€Đĩ҆ĐĩĐŋ҂ҋ** ĐŋĐž Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸ŅŽ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК FastAPI. -А ҁĐĩĐšŅ‡Đ°Ņ Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ĐžŅŅ‚Đ°ĐŊОвиĐŧŅŅ ĐŊа ваĐļĐŊҋ҅ **идĐĩŅŅ… ŅŅ‚Đ¸Ņ… ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš**. Đ­Ņ‚Đ¸ идĐĩи ĐŧĐžĐļĐŊĐž Ņ‚Đ°ĐēĐļĐĩ ĐŋŅ€Đ¸ĐŧĐĩĐŊĐ¸Ņ‚ŅŒ и Đē Đ´Ņ€ŅƒĐŗĐ¸Đŧ Ņ‚Đ¸ĐŋаĐŧ вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. 💡 +А ĐŋĐžĐēа Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ€Đ°ĐˇĐąĐĩҀґĐŧ ваĐļĐŊŅ‹Đĩ **идĐĩи**. Đ­Ņ‚Đ¸ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ ĐŋŅ€Đ¸ĐŧĐĩĐŊиĐŧŅ‹ и Đē Đ´Ņ€ŅƒĐŗĐ¸Đŧ Ņ‚Đ¸ĐŋаĐŧ вĐĩб‑API. 💡 -## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS +## БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS { #security-https } -В [ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐš ĐŗĐģавĐĩ Ой HTTPS](https.md){.internal-link target=_blank} ĐŧŅ‹ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€ĐĩĐģи, ĐēаĐē HTTPS ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž API. +В [ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐš ĐŗĐģавĐĩ ĐŋŅ€Đž HTTPS](https.md){.internal-link target=_blank} ĐŧŅ‹ Ņ€Đ°ĐˇĐžĐąŅ€Đ°ĐģĐ¸ŅŅŒ, ĐēаĐē HTTPS ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž API. -ĐĸаĐēĐļĐĩ ĐŧŅ‹ СаĐŧĐĩŅ‚Đ¸Đģи, Ņ‡Ņ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐž Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ HTTPS Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ĐŊ҃ĐļĐĩĐŊ **Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš** ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ - **ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ TLS**. +ĐĸаĐēĐļĐĩ ĐŧŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩĐģи, Ņ‡Ņ‚Đž HTTPS ĐžĐąŅ‹Ņ‡ĐŊĐž ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚, **вĐŊĐĩ҈ĐŊиК** ĐŋĐž ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸ŅŽ Đē ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ — **TLS Termination Proxy**. -И ĐĩҁĐģи ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŊĐĩ ҃ĐŧĐĩĐĩŅ‚ ŅĐ°Đŧ **ОйĐŊОвĐģŅŅ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ HTTPS**, Ņ‚Đž ĐŊ҃ĐļĐĩĐŊ Đĩ҉ґ ОдиĐŊ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ. +И Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚, ĐžŅ‚Đ˛ĐĩŅ‡Đ°ŅŽŅ‰Đ¸Đš Са **ОйĐŊОвĐģĐĩĐŊиĐĩ HTTPSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛** — ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ‚ĐžŅ‚ ĐļĐĩ ŅĐ°ĐŧŅ‹Đš ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ иĐģи ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš. -### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ HTTPS +### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ HTTPS { #example-tools-for-https } -Đ’ĐžŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅ‚ŅŒ ĐēаĐē ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩҀҋ: +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐē TLS Termination Proxy: * Traefik - * ĐĄ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐŧ ОйĐŊОвĐģĐĩĐŊиĐĩĐŧ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ✨ + * ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ОйĐŊОвĐģŅĐĩŅ‚ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ ✨ * Caddy - * ĐĄ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐŧ ОйĐŊОвĐģĐĩĐŊиĐĩĐŧ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ✨ + * ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ОйĐŊОвĐģŅĐĩŅ‚ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ ✨ * Nginx - * ĐĄ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ Ņ‚Đ¸Đŋа Certbot Đ´ĐģŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ + * ĐĄ вĐŊĐĩ҈ĐŊиĐŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Certbot) Đ´ĐģŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ * HAProxy - * ĐĄ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ Ņ‚Đ¸Đŋа Certbot Đ´ĐģŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ -* Kubernetes ҁ Ingress Controller ĐŋĐžŅ…ĐžĐļиĐŧ ĐŊа Nginx - * ĐĄ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ Ņ‚Đ¸Đŋа cert-manager Đ´ĐģŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ҃ҁĐģŅƒĐŗ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° (Ņ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ ĐŊиĐļĐĩ 👇) + * ĐĄ вĐŊĐĩ҈ĐŊиĐŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Certbot) Đ´ĐģŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ +* Kubernetes ҁ Ingress Controller (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Nginx) + * ĐĄ вĐŊĐĩ҈ĐŊиĐŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, cert-manager) Đ´ĐģŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ +* ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ ĐĩĐŗĐž ҃ҁĐģŅƒĐŗ (ҁĐŧ. ĐŊиĐļĐĩ 👇) -В ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ ҃ҁĐģŅƒĐŗĐ°Đŧи **ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛Đ¸ŅĐ°**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐ´ĐĩĐģаĐĩŅ‚ йОĐģŅŒŅˆŅƒŅŽ Ņ‡Đ°ŅŅ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Ņ‹, вĐēĐģŅŽŅ‡Đ°Ņ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐē҃ HTTPS. Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐŊаĐģĐžĐļĐ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐ¸Ņ иĐģи ĐŋĐžŅ‚Ņ€ĐĩĐąĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ ĐŋĐģĐ°Ņ‚Ņƒ и Ņ‚.Đŋ. Đ—Đ°Ņ‚Đž ВаĐŧ ĐŊĐĩ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž СаĐŊиĐŧĐ°Ņ‚ŅŒŅŅ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. +Đ”Ņ€ŅƒĐŗĐžĐš Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ — Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛ĐžĐˇŅŒĐŧґ҂ ĐŊа ҁĐĩĐąŅ йОĐģҌ҈Đĩ ĐˇĐ°Đ´Đ°Ņ‡, вĐēĐģŅŽŅ‡Đ°Ņ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐē҃ HTTPS. ĐĸаĐŧ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐ¸Ņ иĐģи Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ ŅŅ‚ĐžĐ¸ĐŧĐžŅŅ‚ŅŒ и Ņ‚.Đŋ., ĐŊĐž в Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ваĐŧ ĐŊĐĩ ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ ŅĐ°ĐŧиĐŧ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°Ņ‚ŅŒ TLS Termination Proxy. -В даĐģҌĐŊĐĩĐšŅˆĐĩĐŧ Ņ ĐŋĐžĐēаĐļ҃ ВаĐŧ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ Đ¸Ņ… ĐŋŅ€Đ¸ĐŧĐĩĐŊĐĩĐŊĐ¸Ņ. +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ… Ņ ĐŋĐžĐēаĐļ҃ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ. --- -ĐĄĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ŅŅĐŧĐ°Ņ‚Ņ€Đ¸Đ˛Đ°ŅŽŅ‚ ĐŋŅ€Đ¸ĐŧĐĩĐŊĐĩĐŊиĐĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰ĐĩĐš Đ’Đ°Ņˆ API (Ņ‚Đ°ĐēОК ĐēаĐē Uvicorn). +ДаĐģĐĩĐĩ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸, ŅĐ˛ŅĐˇĐ°ĐŊĐŊŅ‹Đĩ ҁ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК, ĐēĐžŅ‚ĐžŅ€Đ°Ņ СаĐŋ҃ҁĐēаĐĩŅ‚ Đ˛Đ°Ņˆ Ņ€ĐĩаĐģҌĐŊŅ‹Đš API (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn). -## ĐŸŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа и ĐŋŅ€ĐžŅ†Đĩҁҁ +## ĐŸŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа и ĐŋŅ€ĐžŅ†Đĩҁҁ { #program-and-process } -ĐœŅ‹ Ņ‡Đ°ŅŅ‚Đž ĐąŅƒĐ´ĐĩĐŧ Đ˛ŅŅ‚Ņ€ĐĩŅ‡Đ°Ņ‚ŅŒ ҁĐģОва **ĐŋŅ€ĐžŅ†Đĩҁҁ** и **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа**, ĐŋĐžŅ‚ĐžĐŧ҃ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ŅƒŅŅĐŊĐ¸Ņ‚ŅŒ ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Ņ ĐŧĐĩĐļĐ´Ņƒ ĐŊиĐŧи. +ĐœŅ‹ Ņ‡Đ°ŅŅ‚Đž ĐąŅƒĐ´ĐĩĐŧ ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ŅŒ Đž Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰ĐĩĐŧ "**ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ**", ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŋĐžĐģĐĩСĐŊĐž ҇ґ҂ĐēĐž ĐŋĐžĐŊиĐŧĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž ŅŅ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚ и ҇ĐĩĐŧ ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ "**ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹**". -### Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа +### Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа { #what-is-a-program } -ĐĸĐĩŅ€ĐŧиĐŊĐžĐŧ **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа** ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°ŅŽŅ‚ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž вĐĩ҉ĐĩĐš: +ĐĄĐģОвОĐŧ **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа** ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ Ņ€Đ°ĐˇĐŊŅ‹Đĩ вĐĩŅ‰Đ¸: -* **Код**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ĐŊаĐŋĐ¸ŅĐ°Đģи, в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ **Python-Ņ„Đ°ĐšĐģŅ‹**. -* **ФаКĐģ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **Đ¸ŅĐŋĐžĐģĐŊĐĩĐŊ** ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `python`, `python.exe` иĐģи `uvicorn`. -* КоĐŊĐēŅ€ĐĩŅ‚ĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, **СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐ°Ņ** ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰Đ°Ņ ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊŅ‹Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ и ĐŋаĐŧŅŅ‚ŅŒ. В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž Ņ‚Đ°ĐēĐļĐĩ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ **ĐŋŅ€ĐžŅ†Đĩҁҁ**. +* **Код**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ĐŋĐ¸ŅˆĐĩŅ‚Đĩ, Ņ‚Đž ĐĩŅŅ‚ŅŒ **Pythonâ€‘Ņ„Đ°ĐšĐģŅ‹**. +* **ФаКĐģ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **СаĐŋŅƒŅ‰ĐĩĐŊ** ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: `python`, `python.exe` иĐģи `uvicorn`. +* КоĐŊĐēŅ€ĐĩŅ‚ĐŊŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ в ĐŧĐžĐŧĐĩĐŊŅ‚, ĐēĐžĐŗĐ´Đ° ĐžĐŊа **Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚** в ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ CPU и ĐŋаĐŧŅŅ‚ŅŒ. Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ**. -### Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐŋŅ€ĐžŅ†Đĩҁҁ +### Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐŋŅ€ĐžŅ†Đĩҁҁ { #what-is-a-process } -ĐĸĐĩŅ€ĐŧиĐŊ **ĐŋŅ€ĐžŅ†Đĩҁҁ** иĐŧĐĩĐĩŅ‚ йОĐģĐĩĐĩ ŅƒĐˇĐēĐžĐĩ Ņ‚ĐžĐģĐēОваĐŊиĐĩ, ĐŋĐžĐ´Ņ€Đ°ĐˇŅƒĐŧĐĩĐ˛Đ°Ņ Ņ‡Ņ‚Đž-Ņ‚Đž, СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐžĐĩ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК (ĐēаĐē в ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐŧ Đŋ҃ĐŊĐēŅ‚Đĩ иС Đ˛Ņ‹ŅˆĐĩŅŅ‚ĐžŅŅ‰ĐĩĐŗĐž Đ°ĐąĐˇĐ°Ņ†Đ°): +ĐĄĐģОвО **ĐŋŅ€ĐžŅ†Đĩҁҁ** ĐžĐąŅ‹Ņ‡ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ йОĐģĐĩĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐž — Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž Ņ€ĐĩаĐģҌĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ в ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ (ĐēаĐē в ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐŧ Đŋ҃ĐŊĐēŅ‚Đĩ Đ˛Ņ‹ŅˆĐĩ): -* КоĐŊĐēŅ€ĐĩŅ‚ĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, **СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐ°Ņ** ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК. - * Đ­Ņ‚Đž ĐŊĐĩ иĐŧĐĩĐĩŅ‚ ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸Ņ Đē ĐēаĐēĐžĐŧ҃-ĐģийО Ņ„Đ°ĐšĐģ҃ иĐģи ĐēĐžĐ´Ņƒ, ĐŊĐž ĐŊĐĩŅ‡Ņ‚Đž **ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊĐžĐĩ**, ҃ĐŋŅ€Đ°Đ˛ĐģŅĐĩĐŧĐžĐĩ и **Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩĐŧĐžĐĩ** ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК. -* Đ›ŅŽĐąĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, ĐģŅŽĐąĐžĐš ĐēОд, **ĐŧĐžĐŗŅƒŅ‚ Đ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž** Ņ‚ĐžĐģҌĐēĐž ĐēĐžĐŗĐ´Đ° ĐžĐŊи **Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‚ŅŅ**. ĐĸĐž ĐĩŅŅ‚ŅŒ, ĐēĐžĐŗĐ´Đ° ŅĐ˛ĐģŅŅŽŅ‚ŅŅ **Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ**. -* ĐŸŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **ĐŋŅ€ĐĩŅ€Đ˛Đ°ĐŊ** (иĐģи "ŅƒĐąĐ¸Ņ‚") ВаĐŧи иĐģи Đ˛Đ°ŅˆĐĩĐš ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК. В Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Đĩ ҇ĐĩĐŗĐž ĐžĐŊ ĐŋĐĩŅ€ĐĩŅŅ‚Đ°ĐŊĐĩŅ‚ Đ¸ŅĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ и **ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ°Ņ‚ŅŒ Đ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-ĐģийО**. -* КаĐļĐ´ĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Đģи ĐŊа ŅĐ˛ĐžŅ‘Đŧ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ, ĐēаĐļĐ´Đ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, ĐēаĐļĐ´ĐžĐĩ "ĐžĐēĐŊĐž" СаĐŋ҃ҁĐēаĐĩŅ‚ ĐēаĐēОК-Ņ‚Đž ĐŋŅ€ĐžŅ†Đĩҁҁ. И ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊа вĐēĐģŅŽŅ‡ĐĩĐŊĐŊĐžĐŧ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ **ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž** СаĐŋŅƒŅ‰ĐĩĐŊĐž ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛. -* И **ОдĐŊа ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа** ĐŧĐžĐļĐĩŅ‚ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**. +* КоĐŊĐēŅ€ĐĩŅ‚ĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа в ĐŧĐžĐŧĐĩĐŊŅ‚, ĐēĐžĐŗĐ´Đ° ĐžĐŊа **СаĐŋŅƒŅ‰ĐĩĐŊа** в ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ. + * Đ ĐĩŅ‡ŅŒ ĐŊĐĩ Đž Ņ„Đ°ĐšĐģĐĩ и ĐŊĐĩ Đž ĐēОдĐĩ, а **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐž** Đž Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž **Đ¸ŅĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ** и ҃ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК. +* Đ›ŅŽĐąĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, ĐģŅŽĐąĐžĐš ĐēОд **ĐŧĐžĐŗŅƒŅ‚ Ņ‡Ņ‚Đžâ€‘Ņ‚Đž Đ´ĐĩĐģĐ°Ņ‚ŅŒ** Ņ‚ĐžĐģҌĐēĐž ĐēĐžĐŗĐ´Đ° **Đ¸ŅĐŋĐžĐģĐŊŅŅŽŅ‚ŅŅ**, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐēĐžĐŗĐ´Đ° ĐĩŅŅ‚ŅŒ **Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁҁ**. +* ĐŸŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐŊĐž **СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŒ** (иĐģи ÂĢŅƒĐąĐ¸Ņ‚ŅŒÂģ) ваĐŧи иĐģи ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК. В ŅŅ‚ĐžŅ‚ ĐŧĐžĐŧĐĩĐŊŅ‚ ĐžĐŊ ĐŋĐĩŅ€ĐĩŅŅ‚Đ°Ņ‘Ņ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ и **йОĐģҌ҈Đĩ ĐŊĐ¸Ņ‡ĐĩĐŗĐž Đ´ĐĩĐģĐ°Ņ‚ŅŒ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚**. +* ĐŖ ĐēаĐļĐ´ĐžĐŗĐž СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŊа Đ˛Đ°ŅˆĐĩĐŧ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ ĐĩŅŅ‚ŅŒ ŅĐ˛ĐžĐš ĐŋŅ€ĐžŅ†Đĩҁҁ; ҃ ĐēаĐļдОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹, ҃ ĐēаĐļĐ´ĐžĐŗĐž ĐžĐēĐŊа и Ņ‚.Đ´. ĐžĐąŅ‹Ņ‡ĐŊĐž ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž **Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐŧĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ĐŋĐžĐēа ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ вĐēĐģŅŽŅ‡Ņ‘ĐŊ. +* ĐœĐžĐŗŅƒŅ‚ **ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž** Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** ОдĐŊОК и Ņ‚ĐžĐš ĐļĐĩ **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹**. -Đ•ŅĐģи Đ˛Ņ‹ ĐˇĐ°ĐŗĐģŅĐŊĐĩŅ‚Đĩ в "Đ´Đ¸ŅĐŋĐĩ҂҇ĐĩŅ€ ĐˇĐ°Đ´Đ°Ņ‡" иĐģи "ŅĐ¸ŅŅ‚ĐĩĐŧĐŊŅ‹Đš ĐŧĐžĐŊĐ¸Ņ‚ĐžŅ€" (иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ) Đ˛Đ°ŅˆĐĩĐš ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹, Ņ‚Đž ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛. +Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ÂĢĐ´Đ¸ŅĐŋĐĩ҂҇ĐĩŅ€ ĐˇĐ°Đ´Đ°Ņ‡Âģ иĐģи ÂĢŅĐ¸ŅŅ‚ĐĩĐŧĐŊŅ‹Đš ĐŧĐžĐŊĐ¸Ņ‚ĐžŅ€Âģ (иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ) в Đ˛Đ°ŅˆĐĩĐš ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ, Ņ‚Đž ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛. -ВĐŋĐžĐģĐŊĐĩ вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Ņ‡Ņ‚Đž Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ҁ ОдĐŊиĐŧ и Ņ‚ĐĩĐŧ ĐļĐĩ ĐŊаСваĐŊиĐĩĐŧ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ (Firefox, Chrome, Edge и Ņ‚. Д.). ĐžĐąŅ‹Ņ‡ĐŊĐž ĐąŅ€Đ°ŅƒĐˇĐĩҀҋ СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊа вĐēĐģадĐē҃ и вдОйавОĐē ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ОдĐŊĐžĐŗĐž и Ņ‚ĐžĐŗĐž ĐļĐĩ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ° (Firefox, Chrome, Edge и Ņ‚.Đ´.). ĐžĐąŅ‹Ņ‡ĐŊĐž ĐąŅ€Đ°ŅƒĐˇĐĩҀҋ СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊа вĐēĐģадĐē҃ ĐŋĐģŅŽŅ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ. --- -ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° ĐŊаĐŧ иСвĐĩҁ҂ĐŊа Ņ€Đ°ĐˇĐŊĐ¸Ņ†Đ° ĐŧĐĩĐļĐ´Ņƒ **ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ** и **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК**, Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ĐŋŅ€ĐžĐ´ĐžĐģĐļиĐŧ ĐžĐąŅŅƒĐļĐ´ĐĩĐŊиĐĩ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ. +ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° ĐŧŅ‹ ĐŋĐžĐŊиĐŧаĐĩĐŧ Ņ€Đ°ĐˇĐŊĐ¸Ņ†Ņƒ ĐŧĐĩĐļĐ´Ņƒ **ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ** и **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК**, ĐŋŅ€ĐžĐ´ĐžĐģĐļиĐŧ Ņ€Đ°ĐˇĐŗĐžĐ˛ĐžŅ€ Đž Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸ŅŅ…. -## ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ +## ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ { #running-on-startup } -В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚Đĩ вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, Ņ‚Đž ĐļĐĩĐģаĐĩŅ‚Đĩ, Ņ‡Ņ‚ĐžĐą ĐžĐŊĐž **Ņ€Đ°ĐąĐžŅ‚Đ°ĐģĐž ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž** и ĐŊĐĩĐŋŅ€ĐĩŅ€Ņ‹Đ˛ĐŊĐž, ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅ ĐēĐģиĐĩĐŊŅ‚Đ°Đŧ Đ´ĐžŅŅ‚ŅƒĐŋ в ĐģŅŽĐąĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ. ĐĨĐžŅ‚Ņ иĐŊĐžĐŗĐ´Đ° ҃ Đ˛Đ°Ņ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊŅ‹, Ņ‡Ņ‚ĐžĐą ĐžĐŊĐž СаĐŋ҃ҁĐēаĐģĐžŅŅŒ Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ҃ҁĐģĐžĐ˛Đ¸ŅŅ…. +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв, ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ вĐĩб‑API, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ **Ņ€Đ°ĐąĐžŅ‚Đ°Đģ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž**, ĐąĐĩС ĐŋĐĩŅ€ĐĩŅ€Ņ‹Đ˛ĐžĐ˛, Ņ‡Ņ‚ĐžĐąŅ‹ ĐēĐģиĐĩĐŊ҂ҋ Đ˛ŅĐĩĐŗĐ´Đ° ĐŧĐžĐŗĐģи Đē ĐŊĐĩĐŧ҃ ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒŅŅ. РаСвĐĩ Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐžŅĐžĐąŅ‹Đĩ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊŅ‹ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐĩĐŗĐž Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ҃ҁĐģĐžĐ˛Đ¸ŅŅ…, ĐŊĐž ĐžĐąŅ‹Ņ‡ĐŊĐž Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ ĐąŅ‹Đģ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž СаĐŋŅƒŅ‰ĐĩĐŊ и **Đ´ĐžŅŅ‚ŅƒĐŋĐĩĐŊ**. -### ĐŖĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ +### На ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ { #in-a-remote-server } -ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩŅ‚Đĩ ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ (ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€, Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅƒŅŽ ĐŧĐ°ŅˆĐ¸ĐŊ҃ и Ņ‚.Đŋ.), ŅĐ°ĐŧĐžĐĩ ĐŋŅ€ĐžŅŅ‚ĐžĐĩ, Ņ‡Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ, СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Uvicorn (иĐģи ĐĩĐŗĐž аĐŊаĐģĐžĐŗ) Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ, ĐēаĐē Đ˛Ņ‹ Đ´ĐĩĐģаĐĩŅ‚Đĩ ĐŋŅ€Đ¸ ĐģĐžĐēаĐģҌĐŊОК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ. +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩŅ‚Đĩ ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ (ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€, Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅƒŅŽ ĐŧĐ°ŅˆĐ¸ĐŊ҃ и Ņ‚.Đŋ.), ŅĐ°ĐŧŅ‹Đš ĐŋŅ€ĐžŅŅ‚ĐžĐš Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ — Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `fastapi run` (ĐžĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Uvicorn) иĐģи Ņ‡Ņ‚Đžâ€‘Ņ‚Đž ĐŋĐžŅ…ĐžĐļĐĩĐĩ, ĐēаĐē Đ˛Ņ‹ Đ´ĐĩĐģаĐĩŅ‚Đĩ ĐŋŅ€Đ¸ ĐģĐžĐēаĐģҌĐŊОК Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ. -Đ­Ņ‚Đž Ņ€Đ°ĐąĐžŅ‡Đ¸Đš ҁĐŋĐžŅĐžĐą и ĐžĐŊ ĐŋĐžĐģĐĩСĐĩĐŊ **вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи**. +Đ­Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ и ĐŋĐžĐģĐĩСĐŊĐž **вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи**. -Но ĐĩҁĐģи Đ˛Ņ‹ ĐŋĐžŅ‚ĐĩŅ€ŅĐĩŅ‚Đĩ ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ ҁ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ, Ņ‚Đž ĐŊĐĩ ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ - Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Đģи Đ˛ŅŅ‘ Đĩ҉ґ **СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ВаĐŧи ĐŋŅ€ĐžŅ†Đĩҁҁ**. +Но ĐĩҁĐģи ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ ҁ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ĐŋŅ€ĐĩŅ€Đ˛Ņ‘Ņ‚ŅŅ, **СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ**, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, СавĐĩŅ€ŅˆĐ¸Ņ‚ŅŅ. -И ĐĩҁĐģи ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŅ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋĐžŅĐģĐĩ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ иĐģи ĐēаĐēĐ¸Ņ…-Ņ‚Đž Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đš ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°), Đ˛Ņ‹ ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž **ŅŅ‚ĐžĐŗĐž ĐŊĐĩ СаĐŧĐĩŅ‚Đ¸Ņ‚Đĩ**, Ņ‡Ņ‚ĐžĐąŅ‹ ҁĐŊОва СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžŅ†Đĩҁҁ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ. Đ’ŅĐģĐĩĐ´ŅŅ‚Đ˛Đ¸Đĩ ŅŅ‚ĐžĐŗĐž Đ’Đ°Ņˆ API ĐžŅŅ‚Đ°ĐŊĐĩŅ‚ŅŅ ĐŧŅ‘Ņ€Ņ‚Đ˛Ņ‹Đŧ. 😱 +А ĐĩҁĐģи ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŅ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋĐžŅĐģĐĩ ОйĐŊОвĐģĐĩĐŊиК иĐģи ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đš ҃ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°), Đ˛Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, **даĐļĐĩ ĐŊĐĩ СаĐŧĐĩŅ‚Đ¸Ņ‚Đĩ ŅŅ‚ĐžĐŗĐž**. Из‑за ŅŅ‚ĐžĐŗĐž Đ˛Ņ‹ ĐŊĐĩ ŅƒĐˇĐŊаĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžŅ†Đĩҁҁ — и Đ˛Đ°Ņˆ API ĐŋŅ€ĐžŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ÂĢĐŧŅ‘Ņ€Ņ‚Đ˛Âģ. 😱 -### ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиК СаĐŋ҃ҁĐē ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ +### ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиК СаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ { #run-automatically-on-startup } -ВĐĩŅ€ĐžŅŅ‚ĐŊĐž Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐą Đ’Đ°ŅˆĐ° ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа (Ņ‚Đ°ĐēĐ°Ņ, ĐēаĐē Uvicorn) ŅŅ‚Đ°Ņ€Ņ‚ĐžĐ˛Đ°Đģа Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€Đ¸ вĐēĐģŅŽŅ‡ĐĩĐŊии ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐąĐĩС **҇ĐĩĐģОвĐĩ҇ĐĩҁĐēĐžĐŗĐž вĐŧĐĩŅˆĐ°Ņ‚ĐĩĐģŅŒŅŅ‚Đ˛Đ°** и Đ˛ŅĐĩĐŗĐ´Đ° ĐŧĐžĐŗĐģа ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Đ’Đ°ŅˆĐ¸Đŧ API (Ņ‚Đ°Đē ĐēаĐē Uvicorn СаĐŋ҃ҁĐēаĐĩŅ‚ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI). +КаĐē ĐŋŅ€Đ°Đ˛Đ¸ĐģĐž, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn) СаĐŋ҃ҁĐēаĐģĐ°ŅŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и ĐąĐĩС **ŅƒŅ‡Đ°ŅŅ‚Đ¸Ņ ҇ĐĩĐģОвĐĩĐēа**, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ŅĐĩĐŗĐ´Đ° ĐąŅ‹Đģ ĐŋŅ€ĐžŅ†Đĩҁҁ, СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ҁ Đ˛Đ°ŅˆĐ¸Đŧ API (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Đš Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI). -### ĐžŅ‚Đ´ĐĩĐģҌĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа +### ĐžŅ‚Đ´ĐĩĐģҌĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа { #separate-program } -ДĐģŅ ŅŅ‚ĐžĐŗĐž ҃ ĐžĐąŅ‹Ņ‡ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ĐžŅ‚Đ´ĐĩĐģҌĐŊŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ҁĐģĐĩĐ´Đ¸Ņ‚ Са Ņ‚ĐĩĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ’Đ°ŅˆĐ¸ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ СаĐŋ҃ҁĐēаĐģĐ¸ŅŅŒ ĐŋŅ€Đ¸ вĐēĐģŅŽŅ‡ĐĩĐŊии ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. ĐĸаĐēОК ĐŋĐžĐ´Ņ…ĐžĐ´ ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚, Ņ‡Ņ‚Đž Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊ҂ҋ иĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ŅƒŅ‚ СаĐŋŅƒŅ‰ĐĩĐŊŅ‹, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, йаСа даĐŊĐŊҋ҅ +Đ§Ņ‚ĐžĐąŅ‹ ŅŅ‚ĐžĐŗĐž Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ, ĐžĐąŅ‹Ņ‡ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ **ĐžŅ‚Đ´ĐĩĐģҌĐŊŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃**, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŗĐ°Ņ€Đ°ĐŊŅ‚Đ¸Ņ€ŅƒĐĩŅ‚ СаĐŋ҃ҁĐē Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ. Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐžĐŊа Ņ‚Đ°ĐēĐļĐĩ СаĐŋ҃ҁĐēаĐĩŅ‚ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊ҂ҋ/ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅. -### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Ņ… СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ +### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ { #example-tools-to-run-at-startup } -Đ’ĐžŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐŗŅƒŅ‚ ҁĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒŅŅ ҁ Ņ‚Đ°ĐēОК ĐˇĐ°Đ´Đ°Ņ‡ĐĩĐš: +ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐŗŅƒŅ‚ ҁ ŅŅ‚Đ¸Đŧ ҁĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒŅŅ: * Docker * Kubernetes * Docker Compose -* Docker в Ņ€ĐĩĐļиĐŧĐĩ Swarm +* Docker в Ņ€ĐĩĐļиĐŧĐĩ Swarm (Swarm Mode) * Systemd * Supervisor -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ҃ҁĐģŅƒĐŗ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° +* ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа вĐŊŅƒŅ‚Ņ€Đ¸ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ ĐĩĐŗĐž ҃ҁĐģŅƒĐŗ * ĐŸŅ€ĐžŅ‡Đ¸Đĩ... -Đ¯ ĐŋĐžĐēаĐļ҃ ВаĐŧ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ Đ¸Ņ… Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ в ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ…. +БоĐģĐĩĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ ĐąŅƒĐ´ŅƒŅ‚ в ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ…. -## ПĐĩŅ€ĐĩСаĐŋ҃ҁĐē +## ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи { #restarts } -Đ’Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Ņ‚Đ°ĐēĐļĐĩ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐą Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēаĐģĐžŅŅŒ**, ĐĩҁĐģи в ĐŊŅ‘Đŧ ĐŋŅ€ĐžĐ¸ĐˇĐžŅˆŅ‘Đģ ŅĐąĐžĐš. +ПодобĐŊĐž Ņ‚ĐžĐŧ҃ ĐēаĐē Đ˛Ņ‹ ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚Đĩ СаĐŋ҃ҁĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ, Đ˛Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ОйĐĩҁĐŋĐĩŅ‡Đ¸Ņ‚ŅŒ ĐĩĐŗĐž **ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐē** ĐŋĐžŅĐģĐĩ ŅĐąĐžĐĩв. -### ĐœŅ‹ ĐžŅˆĐ¸ĐąĐ°ĐĩĐŧŅŅ +### ĐœŅ‹ ĐžŅˆĐ¸ĐąĐ°ĐĩĐŧŅŅ { #we-make-mistakes } -Đ’ŅĐĩ ĐģŅŽĐ´Đ¸ ŅĐžĐ˛ĐĩŅ€ŅˆĐ°ŅŽŅ‚ **ĐžŅˆĐ¸ĐąĐēи**. ĐŸŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐŊĐžĐĩ ОйĐĩҁĐŋĐĩ҇ĐĩĐŊиĐĩ ĐŋĐžŅ‡Ņ‚Đ¸ *Đ˛ŅĐĩĐŗĐ´Đ°* ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ **ĐąĐ°ĐŗĐ¸** ҁĐŋŅ€ŅŅ‚Đ°Đ˛ŅˆĐ¸ĐĩŅŅ в Ņ€Đ°ĐˇĐŊҋ҅ ĐŧĐĩŅŅ‚Đ°Ņ…. 🐛 +ĐœŅ‹, ĐģŅŽĐ´Đ¸, ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž ŅĐžĐ˛ĐĩŅ€ŅˆĐ°ĐĩĐŧ **ĐžŅˆĐ¸ĐąĐēи**. В ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐŊĐžĐŧ ОйĐĩҁĐŋĐĩ҇ĐĩĐŊии ĐŋĐžŅ‡Ņ‚Đ¸ Đ˛ŅĐĩĐŗĐ´Đ° ĐĩŅŅ‚ŅŒ **ĐąĐ°ĐŗĐ¸**, ҁĐēҀҋ҂ҋĐĩ в Ņ€Đ°ĐˇĐŊҋ҅ ĐŧĐĩŅŅ‚Đ°Ņ…. 🐛 -И ĐŧŅ‹, ĐąŅƒĐ´ŅƒŅ‡Đ¸ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи, ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩĐŧ ҃ĐģŅƒŅ‡ŅˆĐ°Ņ‚ŅŒ ĐēОд, ĐēĐžĐŗĐ´Đ° ОйĐŊĐ°Ņ€ŅƒĐļиваĐĩĐŧ в ĐŊŅ‘Đŧ ĐąĐ°ĐŗĐ¸ иĐģи дОйавĐģŅĐĩĐŧ ĐŊĐžĐ˛Ņ‹Đš Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģ (вОСĐŧĐžĐļĐŊĐž, дОйавĐģŅŅ ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐąĐ°ĐŗĐ¸ 😅). +И ĐŧŅ‹, ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи, ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩĐŧ ҃ĐģŅƒŅ‡ŅˆĐ°Ņ‚ŅŒ ĐēОд — ĐŊĐ°Ņ…ĐžĐ´Đ¸Đŧ ĐąĐ°ĐŗĐ¸ и дОйавĐģŅĐĩĐŧ ĐŊĐžĐ˛Ņ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ (иĐŊĐžĐŗĐ´Đ° дОйавĐģŅŅ ĐŊĐžĐ˛Ņ‹Đĩ ĐąĐ°ĐŗĐ¸ 😅). -### НĐĩйОĐģŅŒŅˆĐ¸Đĩ ĐžŅˆĐ¸ĐąĐēи ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи +### НĐĩйОĐģŅŒŅˆĐ¸Đĩ ĐžŅˆĐ¸ĐąĐēи ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи { #small-errors-automatically-handled } -ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚Đĩ ŅĐ˛ĐžĐ¸ API ĐŊа ĐžŅĐŊОвĐĩ FastAPI и Đ´ĐžĐŋ҃ҁĐēаĐĩŅ‚Đĩ в ĐēОдĐĩ ĐžŅˆĐ¸ĐąĐē҃, Ņ‚Đž FastAPI ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ ĐĩŅ‘ Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊĐĩĐŊиĐĩ вĐŊŅƒŅ‚Ņ€Đ¸ ОдĐŊĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°, ĐŋŅ€Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚ĐēĐĩ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ĐžĐŊа вОСĐŊиĐēĐģа. 🛡 +ĐĄĐžĐˇĐ´Đ°Đ˛Đ°Ņ вĐĩб‑API ҁ FastAPI, ĐĩҁĐģи в ĐŊĐ°ŅˆĐĩĐŧ ĐēОдĐĩ вОСĐŊиĐēаĐĩŅ‚ ĐžŅˆĐ¸ĐąĐēа, FastAPI ĐžĐąŅ‹Ņ‡ĐŊĐž ÂĢĐģĐžĐēаĐģĐ¸ĐˇŅƒĐĩŅ‚Âģ ĐĩŅ‘ в ĐŋŅ€ĐĩĐ´ĐĩĐģĐ°Ņ… ОдĐŊĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅŅ‚Ņƒ ĐžŅˆĐ¸ĐąĐē҃ Đ˛Ņ‹ĐˇĐ˛Đ°Đģ. 🛡 -КĐģиĐĩĐŊŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ ĐžŅˆĐ¸ĐąĐē҃ **500 Internal Server Error** в ĐžŅ‚Đ˛ĐĩŅ‚ ĐŊа ŅĐ˛ĐžĐš СаĐŋŅ€ĐžŅ, ĐŊĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŊĐĩ ҁĐģĐžĐŧаĐĩŅ‚ŅŅ и ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ°Ņ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧи СаĐŋŅ€ĐžŅĐ°Đŧи. +КĐģиĐĩĐŊŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ **500 Internal Server Error** Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž СаĐŋŅ€ĐžŅĐ°, ĐŊĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ Đ´ĐģŅ ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛, а ĐŊĐĩ ÂĢ҃ĐŋĐ°Đ´Ņ‘Ņ‚Âģ ҆ĐĩĐģиĐēĐžĐŧ. -### БоĐģŅŒŅˆĐ¸Đĩ ĐžŅˆĐ¸ĐąĐēи - ПадĐĩĐŊиĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК +### БоĐģŅŒŅˆĐ¸Đĩ ĐžŅˆĐ¸ĐąĐēи — ĐŋадĐĩĐŊĐ¸Ņ { #bigger-errors-crashes } -ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅ‡Đ¸Ņ‚ŅŒŅŅ Ņ‚Đ°Đē, Ņ‡Ņ‚Đž ĐžŅˆĐ¸ĐąĐēа Đ˛Ņ‹ĐˇĐžĐ˛ĐĩŅ‚ **ŅĐąĐžĐš Đ˛ŅĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** иĐģи даĐļĐĩ ŅĐąĐžĐš в Uvicorn, а Ņ‚Đž и в ŅĐ°ĐŧĐžĐŧ Python. đŸ’Ĩ +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ вОСĐŧĐžĐļĐŊŅ‹ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° ĐēОд **Ņ€ĐžĐŊŅĐĩŅ‚ Đ˛ŅŅ‘ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ**, ĐŋŅ€Đ¸Đ˛ĐžĐ´Ņ Đē ŅĐąĐžŅŽ Uvicorn и Python. đŸ’Ĩ -Но ĐŧŅ‹ Đ˛ŅŅ‘ Đĩ҉ґ Ņ…ĐžŅ‚Đ¸Đŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐģĐž Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ** ĐŊĐĩҁĐŧĐžŅ‚Ņ€Ņ ĐŊа ŅŅ‚Ņƒ ĐĩдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊŅƒŅŽ ĐžŅˆĐ¸ĐąĐē҃, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ, ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ, СаĐŋŅ€ĐžŅŅ‹ Đē *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧ ĐŋŅƒŅ‚Đ¸* ĐŊĐĩ иĐŧĐĩŅŽŅ‰Đ¸Đŧ ĐžŅˆĐ¸ĐąĐžĐē. +И Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐŊĐĩ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐžŅŅ‚Đ°Đ˛Đ°ĐģĐžŅŅŒ ÂĢĐŧŅ‘Ņ€Ņ‚Đ˛Ņ‹ĐŧÂģ из‑за ĐžŅˆĐ¸ĐąĐēи в ОдĐŊĐžĐŧ ĐŧĐĩҁ҂Đĩ — Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊĐž **ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐģĐž Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ** Ņ…ĐžŅ‚Ņ ĐąŅ‹ Đ´ĐģŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐĩ ҁĐģĐžĐŧаĐŊŅ‹. -### ПĐĩŅ€ĐĩСаĐŋ҃ҁĐē ĐŋĐžŅĐģĐĩ ĐŋадĐĩĐŊĐ¸Ņ +### ПĐĩŅ€ĐĩСаĐŋ҃ҁĐē ĐŋĐžŅĐģĐĩ ĐŋадĐĩĐŊĐ¸Ņ { #restart-after-crash } -ДĐģŅ ҁĐģŅƒŅ‡Đ°Đĩв, ĐēĐžĐŗĐ´Đ° ĐžŅˆĐ¸ĐąĐēи ĐŋŅ€Đ¸Đ˛ĐžĐ´ŅŅ‚ Đē ŅĐąĐžŅŽ в СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐžĐŧ **ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ**, ВаĐŧ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš **ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Đ¸Ņ‚** ĐŋŅ€ĐžŅ†Đĩҁҁ Ņ…ĐžŅ‚Ņ ĐąŅ‹ ĐŋĐ°Ņ€Ņƒ Ņ€Đ°Đˇ... +В ҁĐģŅƒŅ‡Đ°ŅŅ… Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ҁĐĩŅ€ŅŒŅ‘ĐˇĐŊҋ҅ ĐžŅˆĐ¸ĐąĐžĐē, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ€ĐžĐŊŅŅŽŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đš **ĐŋŅ€ĐžŅ†Đĩҁҁ**, ваĐŧ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ вĐŊĐĩ҈ĐŊиК ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚, ĐžŅ‚Đ˛ĐĩŅ‡Đ°ŅŽŅ‰Đ¸Đš Са **ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐē** ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°, ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ ĐŋĐ°Ņ€Ņƒ Ņ€Đ°Đˇ... -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -... Đ•ŅĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŋадаĐĩŅ‚ ŅŅ€Đ°ĐˇŅƒ ĐļĐĩ ĐŋĐžŅĐģĐĩ СаĐŋ҃ҁĐēа, вĐĩŅ€ĐžŅŅ‚ĐŊĐž ĐąĐĩҁĐŋĐžĐģĐĩСĐŊĐž ĐĩĐŗĐž ĐąĐĩҁĐēĐžĐŊĐĩ҇ĐŊĐž ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ. Но ĐŋĐžĐģĐ°ĐŗĐ°ŅŽ, Đ˛Ņ‹ СаĐŧĐĩŅ‚Đ¸Ņ‚Đĩ Ņ‚Đ°ĐēĐžĐĩ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи иĐģи, ĐŋĐž ĐēŅ€Đ°ĐšĐŊĐĩĐš ĐŧĐĩŅ€Đĩ, ŅŅ€Đ°ĐˇŅƒ ĐŋĐžŅĐģĐĩ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ. +...ĐĨĐžŅ‚Ņ ĐĩҁĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **ĐŋадаĐĩŅ‚ ŅŅ€Đ°ĐˇŅƒ ĐļĐĩ**, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŊĐĩŅ‚ ҁĐŧҋҁĐģа ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐĩĐŗĐž ĐąĐĩҁĐēĐžĐŊĐĩ҇ĐŊĐž. Но Ņ‚Đ°ĐēиĐĩ ҁĐģŅƒŅ‡Đ°Đ¸ Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, СаĐŧĐĩŅ‚Đ¸Ņ‚Đĩ вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи иĐģи ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ ŅŅ€Đ°ĐˇŅƒ ĐŋĐžŅĐģĐĩ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ. -ĐĸаĐē Ņ‡Ņ‚Đž Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸ĐŧŅŅ ĐŊа ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ ҁĐģŅƒŅ‡Đ°ŅŅ…, ĐēĐžĐŗĐ´Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ Đ˛Ņ‹ĐšŅ‚Đ¸ иС ŅŅ‚Ņ€ĐžŅ, ĐŊĐž Đ˛ŅŅ‘ Đĩ҉ґ ĐĩŅŅ‚ŅŒ ҁĐŧҋҁĐģ ĐĩĐŗĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ СаĐŊОвО. +Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸ĐŧŅŅ ĐŊа ĐžŅĐŊОвĐŊҋ҅ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸ŅŅ…, ĐēĐžĐŗĐ´Đ° в ĐēаĐēĐ¸Ņ…â€‘Ņ‚Đž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸ŅŅ… **в ĐąŅƒĐ´ŅƒŅ‰ĐĩĐŧ** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ ĐŋĐ°Đ´Đ°Ņ‚ŅŒ ҆ĐĩĐģиĐēĐžĐŧ, и ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ иĐŧĐĩĐĩŅ‚ ҁĐŧҋҁĐģ ĐĩĐŗĐž ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ. /// -ВозĐŧĐžĐļĐŊĐž Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐą ĐąŅ‹Đģ ĐŊĐĩĐēиК **вĐŊĐĩ҈ĐŊиК ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚**, ĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đš Са ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐē Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ даĐļĐĩ ĐĩҁĐģи ҃ĐļĐĩ ĐŊĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Uvicorn иĐģи Python. ĐĸĐž ĐĩŅŅ‚ŅŒ ĐŊĐ¸Ņ‡ĐĩĐŗĐž иС Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž ĐŊаĐŋĐ¸ŅĐ°ĐŊĐž в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ вĐŊŅƒŅ‚Ņ€Đ¸ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐž в ĐŋŅ€Đ¸ĐŊŅ†Đ¸ĐŋĐĩ. +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐžĐŧ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ СаĐŊиĐŧаĐģŅŅ **вĐŊĐĩ҈ĐŊиК ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚**, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž Đē Ņ‚ĐžĐŧ҃ ĐŧĐžĐŧĐĩĐŊŅ‚Ņƒ Uvicorn и Python ҃ĐļĐĩ ҃ĐŋаĐģи, и вĐŊŅƒŅ‚Ņ€Đ¸ Ņ‚ĐžĐŗĐž ĐļĐĩ ĐēОда Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ҃ĐļĐĩ ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩĐģŅŒĐˇŅ. -### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēа +### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēа { #example-tools-to-restart-automatically } -В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ **СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°** ҃ĐŧĐĩŅŽŅ‚ **ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ** ŅŅ‚Đ¸ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹. +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв Ņ‚ĐžŅ‚ ĐļĐĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš **СаĐŋ҃ҁĐēаĐĩŅ‚ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ**, ҃ĐŧĐĩĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ **ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēи**. -В ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° ĐŧĐžĐļĐŊĐž Đ˛ĐˇŅŅ‚ŅŒ Ņ‚Đĩ ĐļĐĩ: +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ: * Docker * Kubernetes * Docker Compose -* Docker в Ņ€ĐĩĐļиĐŧĐĩ Swarm +* Docker в Ņ€ĐĩĐļиĐŧĐĩ Swarm (Swarm Mode) * Systemd * Supervisor -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ҃ҁĐģŅƒĐŗ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° +* ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа вĐŊŅƒŅ‚Ņ€Đ¸ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ ĐĩĐŗĐž ҃ҁĐģŅƒĐŗ * ĐŸŅ€ĐžŅ‡Đ¸Đĩ... -## ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ (Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ) - ĐŸŅ€ĐžŅ†Đĩҁҁҋ и ĐŋаĐŧŅŅ‚ŅŒ +## Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ — ĐŋŅ€ĐžŅ†Đĩҁҁҋ и ĐŋаĐŧŅŅ‚ŅŒ { #replication-processes-and-memory } -ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI, ҃ĐŋŅ€Đ°Đ˛ĐģŅĐĩĐŧĐžĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК (Ņ‚Đ°ĐēОК ĐēаĐē Uvicorn), СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ ĐēаĐē **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** и ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž. +В ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии FastAPI, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžĐŧаĐŊĐ´Ņƒ `fastapi`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ СаĐŋ҃ҁĐēаĐĩŅ‚ Uvicorn), СаĐŋ҃ҁĐē в **ОдĐŊĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ** ҃ĐļĐĩ ĐŋОСвОĐģŅĐĩŅ‚ ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž. -Но Ņ‡Đ°ŅŅ‚Đž ВаĐŧ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ОдиĐŊаĐēĐžĐ˛Ņ‹Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛. +Но вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛â€‘Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛. -### МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ - Đ’ĐžŅ€ĐēĐĩҀҋ (Workers) +### НĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ — Đ’ĐžŅ€ĐēĐĩҀҋ { #multiple-processes-workers } -Đ•ŅĐģи ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž Đ’Đ°ŅˆĐ¸Ņ… ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ йОĐģҌ҈Đĩ, ҇ĐĩĐŧ ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅĐģ҃ĐļĐ¸Ņ‚ŅŒ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ (Đ´ĐžĐŋŅƒŅŅ‚Đ¸Đŧ, Ņ‡Ņ‚Đž Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа ĐŊĐĩ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐŧĐžŅ‰ĐŊĐ°Ņ), ĐŊĐž ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ВаĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐž **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ŅĐ´ĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°**, Ņ‚Đž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** ОдĐŊĐžĐŗĐž и Ņ‚ĐžĐŗĐž ĐļĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž и Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ ĐŧĐĩĐļĐ´Ņƒ ŅŅ‚Đ¸Đŧи ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи. +Đ•ŅĐģи ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛ йОĐģҌ҈Đĩ, ҇ĐĩĐŧ ҁĐŋĐžŅĐžĐąĐĩĐŊ ĐžĐąŅĐģ҃ĐļĐ¸Ņ‚ŅŒ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа ĐŊĐĩ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐŧĐžŅ‰ĐŊĐ°Ņ), и ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ ĐĩŅŅ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ŅĐ´ĐĩŅ€ CPU**, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** ОдĐŊĐžĐŗĐž и Ņ‚ĐžĐŗĐž ĐļĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž и Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ ĐŧĐĩĐļĐ´Ņƒ ĐŊиĐŧи. -**НĐĩҁĐēĐžĐģҌĐēĐž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** ОдĐŊОК и Ņ‚ĐžĐš ĐļĐĩ API-ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ Ņ‡Đ°ŅŅ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи**. +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** ОдĐŊОК и Ņ‚ĐžĐš ĐļĐĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ API, Đ¸Ņ… ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи**. -### ĐŸŅ€ĐžŅ†Đĩҁҁҋ и ĐŋĐžŅ€Ņ‚Ņ‹Ė +### ĐŸŅ€ĐžŅ†ĐĩŅŅŅ‹â€‘Đ˛ĐžŅ€ĐēĐĩҀҋ и ĐŋĐžŅ€Ņ‚Ņ‹ { #worker-processes-and-ports } -ПоĐŧĐŊĐ¸Ņ‚Đĩ Đģи Đ’Ņ‹, ĐēаĐē ĐŊа ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đĩ [Об HTTPS](https.md){.internal-link target=_blank} ĐŧŅ‹ ĐžĐąŅŅƒĐļдаĐģи, Ņ‡Ņ‚Đž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ОдĐŊ҃ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ŅŽ IP-Đ°Đ´Ņ€ĐĩŅĐ° и ĐŋĐžŅ€Ņ‚Đ°? +ПоĐŧĐŊĐ¸Ņ‚Đĩ иС Ņ€Đ°ĐˇĐ´ĐĩĐģа [Об HTTPS](https.md){.internal-link target=_blank}, Ņ‡Ņ‚Đž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅƒŅŽ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ŅŽ ĐŋĐžŅ€Ņ‚Đ° и IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ°? -ĐĄ Ņ‚ĐĩŅ… ĐŋĐžŅ€ ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩ иСĐŧĐĩĐŊиĐģĐžŅŅŒ. +Đ­Ņ‚Đž Đŋо‑ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ Ņ‚Đ°Đē. -ĐĄĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ĐĩĐŊĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ иĐŧĐĩŅ‚ŅŒ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ **ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи** ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž, Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ, ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°ŅŽŅ‰Đ¸Đš ĐŋĐžŅ€Ņ‚** и ĐˇĐ°Ņ‚ĐĩĐŧ ĐēаĐēиĐŧ-ĐģийО ĐžĐąŅ€Đ°ĐˇĐžĐŧ ĐŋĐĩŅ€ĐĩĐ´Đ°ŅŽŅ‰Đ¸Đš даĐŊĐŊŅ‹Đĩ ĐēаĐļĐ´ĐžĐŧ҃ Ņ€Đ°ĐąĐžŅ‡ĐĩĐŧ҃ ĐŋŅ€ĐžŅ†Đĩҁҁ҃. +ĐŸĐžŅŅ‚ĐžĐŧ҃, Ņ‡Ņ‚ĐžĐąŅ‹ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐģĐž **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ, ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đš ĐŋĐžŅ€Ņ‚**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐˇĐ°Ņ‚ĐĩĐŧ ĐēаĐēиĐŧâ€‘Ņ‚Đž ĐžĐąŅ€Đ°ĐˇĐžĐŧ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ ĐēĐžĐŧĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸ŅŽ ĐēаĐļĐ´ĐžĐŧ҃ Đ˛ĐžŅ€ĐēĐĩŅ€â€‘ĐŋŅ€ĐžŅ†Đĩҁҁ҃. -### ĐŖ ĐēаĐļĐ´ĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° ŅĐ˛ĐžŅ ĐŋаĐŧŅŅ‚ŅŒ +### ПаĐŧŅŅ‚ŅŒ ĐŊа ĐŋŅ€ĐžŅ†Đĩҁҁ { #memory-per-process } -Đ Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩŅ‚ в ĐŋаĐŧŅŅ‚ŅŒ даĐŊĐŊŅ‹Đĩ, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Đ´ĐģŅ ĐĩŅ‘ Ņ€Đ°ĐąĐžŅ‚Ņ‹, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đĩ ĐŧОдĐĩĐģи ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ иĐģи йОĐģŅŒŅˆĐ¸Đĩ Ņ„Đ°ĐšĐģŅ‹. КаĐļĐ´Đ°Ņ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ **ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ (RAM)** ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. +ĐšĐžĐŗĐ´Đ° ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩŅ‚ Ņ‡Ņ‚Đžâ€‘Ņ‚Đž в ĐŋаĐŧŅŅ‚ŅŒ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŧОдĐĩĐģҌ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ в ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅƒŅŽ иĐģи ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ йОĐģŅŒŅˆĐžĐŗĐž Ņ„Đ°ĐšĐģа в ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅƒŅŽ), Đ˛ŅŅ‘ ŅŅ‚Đž **ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩŅ‚ Ņ‡Đ°ŅŅ‚ŅŒ ĐŋаĐŧŅŅ‚Đ¸ (RAM)** ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. -ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŋŅ€ĐžŅ†Đĩҁҁҋ **ĐŊĐĩ Đ´ĐĩĐģŅŅ‚ŅŅ ĐŋаĐŧŅŅ‚ŅŒŅŽ Đ´Ņ€ŅƒĐŗ ҁ Đ´Ņ€ŅƒĐŗĐžĐŧ**. ХиĐĩ ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đš ĐŋŅ€ĐžŅ†Đĩҁҁ иĐŧĐĩĐĩŅ‚ ŅĐ˛ĐžĐ¸ даĐŊĐŊŅ‹Đĩ, ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ и ŅĐ˛ĐžĐš ĐēŅƒŅĐžĐē ĐŋаĐŧŅŅ‚Đ¸. И ĐĩҁĐģи Đ´ĐģŅ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ Đ˛Đ°ŅˆĐĩĐŗĐž ĐēОда ĐŋŅ€ĐžŅ†Đĩҁҁ҃ ĐŊ҃ĐļĐŊĐž ĐŧĐŊĐžĐŗĐž ĐŋаĐŧŅŅ‚Đ¸, Ņ‚Đž **ĐēаĐļĐ´Ņ‹Đš Ņ‚Đ°ĐēОК ĐļĐĩ ĐŋŅ€ĐžŅ†Đĩҁҁ** СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐž, ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒĐĩŅ‚ Ņ‚Đ°ĐēĐžĐŗĐž ĐļĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° ĐŋаĐŧŅŅ‚Đ¸. +И Ņ€Đ°ĐˇĐŊŅ‹Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ ĐžĐąŅ‹Ņ‡ĐŊĐž **ĐŊĐĩ Đ´ĐĩĐģŅŅ‚ ĐŋаĐŧŅŅ‚ŅŒ**. Đ­Ņ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž ҃ ĐēаĐļĐ´ĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° ŅĐ˛ĐžĐ¸ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ и ŅĐ˛ĐžŅ ĐŋаĐŧŅŅ‚ŅŒ. Đ•ŅĐģи Đ˛Đ°Ņˆ ĐēОд ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩŅ‚ ĐŧĐŊĐžĐŗĐž ĐŋаĐŧŅŅ‚Đ¸, Ņ‚Đž **ĐēаĐļĐ´Ņ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ** ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅ‚ŅŒ ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸ĐŧŅ‹Đš ĐžĐąŅŠŅ‘Đŧ ĐŋаĐŧŅŅ‚Đ¸. -### ПаĐŧŅŅ‚ŅŒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° +### ПаĐŧŅŅ‚ŅŒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° { #server-memory } -ДоĐŋŅƒŅŅ‚Đ¸Đŧ, Ņ‡Ņ‚Đž Đ’Đ°Ņˆ ĐēОд ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩŅ‚ ĐŧОдĐĩĐģҌ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ **Ņ€Đ°ĐˇĐŧĐĩŅ€ĐžĐŧ 1 ГБ**. ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ŅĐ˛ĐžŅ‘ API ĐēаĐē ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ, ĐžĐŊ СаКĐŧґ҂ в ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ 1 ГБ. А ĐĩҁĐģи Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ **4 Ņ‚Đ°ĐēĐ¸Ņ… ĐļĐĩ ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°** (4 Đ˛ĐžŅ€ĐēĐĩŅ€Đ°), Ņ‚Đž ĐēаĐļĐ´Ņ‹Đš иС ĐŊĐ¸Ņ… СаКĐŧґ҂ 1 ГБ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸. В Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚Đĩ Đ˛Đ°ŅˆĐĩĐŧ҃ API ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒĐĩŅ‚ŅŅ **4 ГБ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ (RAM)**. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи Đ˛Đ°Ņˆ ĐēОд ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩŅ‚ ĐŧОдĐĩĐģҌ ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ Ņ€Đ°ĐˇĐŧĐĩŅ€ĐžĐŧ **1 ГБ**, Ņ‚Đž ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ ОдĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° ҁ Đ˛Đ°ŅˆĐ¸Đŧ API ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ 1 ГБ RAM. А ĐĩҁĐģи Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ **4 ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°** (4 Đ˛ĐžŅ€ĐēĐĩŅ€Đ°), ĐēаĐļĐ´Ņ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ 1 ГБ RAM. Đ’ŅĐĩĐŗĐž Đ˛Đ°Ņˆ API ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅ‚ŅŒ **4 ГБ RAM**. -И ĐĩҁĐģи Đ’Đ°Ņˆ ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ иĐģи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа Ņ€Đ°ŅĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚ Ņ‚ĐžĐģҌĐēĐž 3 ГБ ĐŋаĐŧŅŅ‚Đ¸, Ņ‚Đž ĐŋĐžĐŋҋ҂Đēа ĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŒ в ĐŊĐĩŅ‘ 4 ГБ даĐŊĐŊҋ҅ Đ˛Ņ‹ĐˇĐžĐ˛ĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. 🚨 +И ĐĩҁĐģи ҃ Đ˛Đ°ŅˆĐĩĐŗĐž ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° иĐģи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊŅ‹ Ņ‚ĐžĐģҌĐēĐž 3 ГБ RAM, ĐŋĐžĐŋҋ҂Đēа ĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŒ йОĐģĐĩĐĩ 4 ГБ Đ˛Ņ‹ĐˇĐžĐ˛ĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. 🚨 -### МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ - ĐŸŅ€Đ¸ĐŧĐĩŅ€ +### НĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ — ĐŋŅ€Đ¸ĐŧĐĩŅ€ { #multiple-processes-an-example } -В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** СаĐŋŅƒŅŅ‚Đ¸Ņ‚ и ĐąŅƒĐ´ĐĩŅ‚ ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Đ´Đ˛ŅƒĐŧŅ **Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи**. +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ ĐĩŅŅ‚ŅŒ **ĐŋŅ€ĐžŅ†ĐĩŅŅâ€‘ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš СаĐŋ҃ҁĐēаĐĩŅ‚ и ĐēĐžĐŊŅ‚Ņ€ĐžĐģĐ¸Ņ€ŅƒĐĩŅ‚ два **ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°â€‘Đ˛ĐžŅ€ĐēĐĩŅ€Đ°**. -МĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐąŅƒĐ´ĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš **ŅĐžĐēĐĩŅ‚** (IP:ĐŋĐžŅ€Ņ‚) и ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ даĐŊĐŊŅ‹Đĩ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧ. +ĐŸŅ€ĐžŅ†ĐĩŅŅâ€‘ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐąŅƒĐ´ĐĩŅ‚ Ņ‚ĐĩĐŧ, ĐēŅ‚Đž ҁĐģŅƒŅˆĐ°ĐĩŅ‚ **ĐŋĐžŅ€Ņ‚** ĐŊа IP. И ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ Đ˛ŅŅŽ ĐēĐžĐŧĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸ŅŽ Đ˛ĐžŅ€ĐēĐĩŅ€â€‘ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧ. -КаĐļĐ´Ņ‹Đš иС ŅŅ‚Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐąŅƒĐ´ĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊĐžĐŗĐž **СаĐŋŅ€ĐžŅĐ°** и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰ĐĩĐŊĐ¸Ņ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐŊĐžĐŗĐž **ĐžŅ‚Đ˛ĐĩŅ‚Đ°** и ĐžĐŊи ĐąŅƒĐ´ŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊŅƒŅŽ ĐŋаĐŧŅŅ‚ŅŒ. +Đ­Ņ‚Đ¸ Đ˛ĐžŅ€ĐēĐĩҀҋ ĐąŅƒĐ´ŅƒŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ ĐžŅĐŊОвĐŊŅ‹Đĩ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ **СаĐŋŅ€ĐžŅĐ°** и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‚Đ° **ĐžŅ‚Đ˛ĐĩŅ‚Đ°**, и ĐˇĐ°ĐŗŅ€ŅƒĐļĐ°Ņ‚ŅŒ Đ˛ŅŅ‘, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐēĐģĐ°Đ´Ņ‘Ņ‚Đĩ в ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ, в RAM. -БĐĩĐˇŅƒŅĐģОвĐŊĐž, ĐŊа ŅŅ‚ĐžĐŧ ĐļĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ ĐąŅƒĐ´ŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ и **Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐĩ ĐžŅ‚ĐŊĐžŅŅŅ‚ŅŅ Đē Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ. +КоĐŊĐĩ҇ĐŊĐž, ĐŊа Ņ‚ĐžĐš ĐļĐĩ ĐŧĐ°ŅˆĐ¸ĐŊĐĩ ĐŋĐžĐŧиĐŧĐž Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐąŅƒĐ´ŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ и **Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ**. -ИĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐ°Ņ Đ´ĐĩŅ‚Đ°ĐģҌ СаĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ŅŅ в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŋŅ€ĐžŅ†ĐĩĐŊŅ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° (CPU)** ĐēаĐļĐ´Ņ‹Đŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ ĐŧĐžĐļĐĩŅ‚ ŅĐ¸ĐģҌĐŊĐž ĐŧĐĩĐŊŅŅ‚ŅŒŅŅ ҁ Ņ‚Đĩ҇ĐĩĐŊиĐĩĐŧ Đ˛Ņ€ĐĩĐŧĐĩĐŊи, ĐŊĐž ĐžĐąŅŠŅ‘Đŧ СаĐŊиĐŧаĐĩĐŧОК **ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ (RAM)** ĐžŅŅ‚Đ°Ņ‘Ņ‚ŅŅ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž **ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊŅ‹Đŧ**. +ИĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐ°Ņ Đ´ĐĩŅ‚Đ°ĐģҌ: ĐŋŅ€ĐžŅ†ĐĩĐŊŅ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ CPU** ĐēаĐļĐ´Ņ‹Đŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ ŅĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊĐĩĐŧ ĐŧĐžĐļĐĩŅ‚ ŅĐ¸ĐģҌĐŊĐž **ĐŧĐĩĐŊŅŅ‚ŅŒŅŅ**, ĐŊĐž **ĐŋаĐŧŅŅ‚ŅŒ (RAM)** ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžŅŅ‚Đ°Ņ‘Ņ‚ŅŅ йОĐģĐĩĐĩ‑ĐŧĐĩĐŊĐĩĐĩ **ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊОК**. -Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ API, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸ĐŧŅ‹Đš ĐžĐąŅŠĐĩĐŧ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊиК, и ҃ Đ˛Đ°Ņ ĐŧĐŊĐžĐŗĐž ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛, Ņ‚Đž **ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°**, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, *Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊОК* (вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž ĐąŅ‹ŅŅ‚Ņ€Đž ŅƒĐ˛ĐĩĐģĐ¸Ņ‡Đ¸Đ˛Đ°Ņ‚ŅŒŅŅ и ҃ĐŧĐĩĐŊŅŒŅˆĐ°Ņ‚ŅŒŅŅ). +Đ•ŅĐģи ҃ Đ˛Đ°Ņ API, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸ĐŧŅ‹Đš ĐžĐąŅŠŅ‘Đŧ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊиК, и ҃ Đ˛Đ°Ņ ĐŧĐŊĐžĐŗĐž ĐēĐģиĐĩĐŊŅ‚ĐžĐ˛, Ņ‚Đž **ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°**, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, *Ņ‚ĐžĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊОК* (вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐąŅ‹ŅŅ‚Ņ€Đž и ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž ÂĢҁĐēаĐēĐ°Ņ‚ŅŒÂģ). -### ĐŸŅ€Đ¸ĐŧĐĩҀҋ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš и иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ СаĐŋ҃ҁĐēа ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ +### ĐŸŅ€Đ¸ĐŧĐĩҀҋ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Đ¸ { #examples-of-replication-tools-and-strategies } -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋĐžĐ´Ņ…ĐžĐ´ĐžĐ˛ Đ´ĐģŅ Đ´ĐžŅŅ‚Đ¸ĐļĐĩĐŊĐ¸Ņ ҆ĐĩĐģĐĩĐš Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Đ¸ и Ņ Ņ€Đ°ŅŅĐēаĐļ҃ ВаĐŧ йОĐģҌ҈Đĩ Đž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸ŅŅ… в ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ…, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžĐŗĐ´Đ° Ņ€ĐĩŅ‡ŅŒ ĐŋОКдĐĩŅ‚ Đž Docker и ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ…. +Đ•ŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋĐžĐ´Ņ…ĐžĐ´ĐžĐ˛ Đ´ĐģŅ Đ´ĐžŅŅ‚Đ¸ĐļĐĩĐŊĐ¸Ņ ŅŅ‚ĐžĐŗĐž, и Ņ Ņ€Đ°ŅŅĐēаĐļ҃ йОĐģҌ҈Đĩ Đž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸ŅŅ… в ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ…, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŗĐžĐ˛ĐžŅ€Ņ Đž Docker и ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ…. -ĐžŅĐŊОвĐŊĐžĐĩ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиĐĩ ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ - Ņ‚ĐžĐģҌĐēĐž **ОдиĐŊ** ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ ĐŧĐžĐļĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧ **ĐŋĐžŅ€Ņ‚ĐžĐŧ ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŗĐž IP**. И Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ ҁĐŋĐžŅĐžĐą **ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸** даĐŊĐŊҋ҅ ĐŧĐĩĐļĐ´Ņƒ ŅŅ‚Đ¸Đŧ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐŧ и ĐēĐžĐŋĐ¸ŅĐŧи **ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛/Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛**. +ГĐģавĐŊĐžĐĩ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиĐĩ: Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ **ОдиĐŊ** ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ **ĐŋĐžŅ€Ņ‚** ĐŊа **ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŧ IP**. И ҃ ĐŊĐĩĐŗĐž Đ´ĐžĐģĐļĐĩĐŊ ĐąŅ‹Ņ‚ŅŒ ҁĐŋĐžŅĐžĐą **ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ** ĐēĐžĐŧĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸ŅŽ Ņ€ĐĩĐŋĐģĐ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đŧ **ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧ/Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧ**. -Đ’ĐžŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ вОСĐŧĐžĐļĐŊŅ‹Đĩ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸Đ¸ и ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸: +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ вОСĐŧĐžĐļĐŊŅ‹Đĩ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸Đ¸ и ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸: -* **Gunicorn** ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš **Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи Uvicorn** - * Gunicorn ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ŅŅ‚ŅƒĐŋĐ°Ņ‚ŅŒ ĐēаĐē **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°Ņ **IP:port**. НĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐąŅƒĐ´ĐĩŅ‚ ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģŅŅ‚ŅŒŅŅ ĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐžĐŧ СаĐŋ҃ҁĐēа **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Uvicorn**. -* **Uvicorn** ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš **Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи Uvicorn** - * ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ŅŅ‚ŅƒĐŋĐ°Ņ‚ŅŒ ĐēаĐē **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°Ņ **IP:port**. ОĐŊ ĐąŅƒĐ´ĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Uvicorn**. -* **Kubernetes** и аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đĩ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐŊŅ‹Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹** - * КаĐēОК-Ņ‚Đž ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ в **Kubernetes** ĐąŅƒĐ´ĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ **IP:port**. НĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐąŅƒĐ´ĐĩŅ‚ ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģŅŅ‚ŅŒŅŅ ĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐžĐŧ СаĐŋ҃ҁĐēа **ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, в ĐēаĐļĐ´ĐžĐŧ иС ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn**. -* **ОбĐģĐ°Ņ‡ĐŊŅ‹Đĩ ҁĐĩŅ€Đ˛Đ¸ŅŅ‹**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐžĐˇĐ°ĐąĐžŅ‚ŅŅ‚ŅŅ ОйО Đ˛ŅŅ‘Đŧ Са Đ’Đ°Ņ - * ВозĐŧĐžĐļĐŊĐž, Ņ‡Ņ‚Đž ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ ҃ĐŧĐĩĐĩŅ‚ **҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ СаĐŋ҃ҁĐēĐžĐŧ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ**. ВĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐžĐŊ ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒĐĩŅ‚, Ņ‡Ņ‚ĐžĐą Đ˛Ņ‹ ҃ĐēаСаĐģи - ĐēаĐēОК **ĐŋŅ€ĐžŅ†Đĩҁҁ** иĐģи **ĐžĐąŅ€Đ°Đˇ** ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐēĐģĐžĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ. ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, Đ˛Ņ‹ ҃ĐēаĐļĐĩŅ‚Đĩ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn** и ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ ĐąŅƒĐ´ĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐĩĐŗĐž ĐēĐžĐŋии ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸. +* **Uvicorn** ҁ `--workers` + * ОдиĐŊ **ĐŋŅ€ĐžŅ†ĐĩŅŅâ€‘ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€** Uvicorn ĐąŅƒĐ´ĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ **IP** и **ĐŋĐžŅ€Ņ‚** и СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛â€‘Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ Uvicorn**. +* **Kubernetes** и Đ´Ņ€ŅƒĐŗĐ¸Đĩ Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đĩ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐŊŅ‹Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹** + * НĐĩĐēиК ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ **Kubernetes** ĐąŅƒĐ´ĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ **IP** и **ĐŋĐžŅ€Ņ‚**. Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ Đ´ĐžŅŅ‚Đ¸ĐŗĐ°ĐĩŅ‚ŅŅ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, в ĐēаĐļĐ´ĐžĐŧ иС ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn**. +* **ОбĐģĐ°Ņ‡ĐŊŅ‹Đĩ ҁĐĩŅ€Đ˛Đ¸ŅŅ‹**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐąĐĩŅ€ŅƒŅ‚ ŅŅ‚Đž ĐŊа ҁĐĩĐąŅ + * ОбĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, **Đ˛ĐžĐˇŅŒĐŧґ҂ Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ŅŽ ĐŊа ҁĐĩĐąŅ**. ОĐŊ, вОСĐŧĐžĐļĐŊĐž, ĐŋОСвОĐģĐ¸Ņ‚ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ **ĐŋŅ€ĐžŅ†Đĩҁҁ Đ´ĐģŅ СаĐŋ҃ҁĐēа** иĐģи **ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**. В ĐģŅŽĐąĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐąŅƒĐ´ĐĩŅ‚ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn**, а ҁĐĩŅ€Đ˛Đ¸Ņ СаКĐŧŅ‘Ņ‚ŅŅ ĐĩĐŗĐž Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ĐĩĐš. -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -Đ•ŅĐģи Đ˛Ņ‹ ĐŊĐĩ СĐŊаĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ**, Docker иĐģи Kubernetes, ĐŊĐĩ ĐŋĐĩŅ€ĐĩĐļĐ¸Đ˛Đ°ĐšŅ‚Đĩ. +НĐĩ ĐąĐĩҁĐŋĐžĐēĐžĐšŅ‚ĐĩҁҌ, ĐĩҁĐģи ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đŋ҃ĐŊĐē҂ҋ ĐŋŅ€Đž **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ**, Docker иĐģи Kubernetes ĐŋĐžĐēа ĐēаĐļŅƒŅ‚ŅŅ ĐŊĐĩĐžŅ‡ĐĩвидĐŊŅ‹Đŧи. -Đ¯ ĐŋОвĐĩĐ´Đ°ŅŽ ВаĐŧ Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ…, ĐžĐąŅ€Đ°ĐˇĐ°Ņ…, Docker, Kubernetes и Ņ‚.Đŋ. в ĐŗĐģавĐĩ: [FastAPI вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ - Docker](docker.md){.internal-link target=_blank}. +Đ¯ Ņ€Đ°ŅŅĐēаĐļ҃ йОĐģҌ҈Đĩ ĐŋŅ€Đž ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛, Docker, Kubernetes и Ņ‚.Đŋ. в ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐš ĐŗĐģавĐĩ: [FastAPI вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ — Docker](docker.md){.internal-link target=_blank}. /// -## Đ¨Đ°ĐŗĐ¸, ĐŋŅ€ĐĩĐ´ŅˆĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đĩ СаĐŋ҃ҁĐē҃ +## ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ { #previous-steps-before-starting } -Đ§Đ°ŅŅ‚Đž ĐąŅ‹Đ˛Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ВаĐŧ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ ĐēаĐēиĐĩ-Ņ‚Đž ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ **ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ** ŅĐ˛ĐžĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅˆĐ°ĐŗĐ¸ **ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ **ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đ¸ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅**. -Но в йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв Ņ‚Đ°ĐēиĐĩ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ **ОдĐŊĐžĐēŅ€Đ°Ņ‚ĐŊĐž**. +Но Ņ‡Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž ŅŅ‚Đ¸ ŅˆĐ°ĐŗĐ¸ ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž **ОдиĐŊ Ņ€Đ°Đˇ**. -ĐŸĐžŅŅ‚ĐžĐŧ҃ ВаĐŧ ĐŊ҃ĐļĐĩĐŊ ĐąŅƒĐ´ĐĩŅ‚ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‰Đ¸Đš ŅŅ‚Đ¸ **ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸** Đ´Đž СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. +ĐŸĐžŅŅ‚ĐžĐŧ҃ Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ ŅŅ‚Đ¸ **ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸**, ĐŋŅ€ĐĩĐļĐ´Đĩ ҇ĐĩĐŧ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. -ĐĸаĐēĐļĐĩ ВаĐŧ ĐŊ҃ĐļĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž ŅŅ‚ĐžŅ‚ ĐŋŅ€ĐžŅ†Đĩҁҁ Đ˛Ņ‹ĐŋĐžĐģĐŊиĐģ ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ *даĐļĐĩ* ĐĩҁĐģи вĐŋĐžŅĐģĐĩĐ´ŅŅ‚Đ˛Đ¸Đ¸ Đ˛Ņ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** (ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛) ŅĐ°ĐŧĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. Đ•ŅĐģи ĐąŅ‹ ŅŅ‚Đ¸ ŅˆĐ°ĐŗĐ¸ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģĐ¸ŅŅŒ в ĐēаĐļĐ´ĐžĐŧ **ĐēĐģĐžĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ**, ĐžĐŊи ĐąŅ‹ **Đ´ŅƒĐąĐģĐ¸Ņ€ĐžĐ˛Đ°Đģи** Ņ€Đ°ĐąĐžŅ‚Ņƒ, ĐŋŅ‹Ņ‚Đ°ŅŅŅŒ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐĩŅ‘ **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž**. И ĐĩҁĐģи ĐąŅ‹ ŅŅ‚Đ° Ņ€Đ°ĐąĐžŅ‚Đ° ĐąŅ‹Đģа ĐąŅ‹ ҇ĐĩĐŧ-Ņ‚Đž Đ´ĐĩĐģиĐēĐ°Ņ‚ĐŊŅ‹Đŧ, Đ˛Ņ€ĐžĐ´Đĩ ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đ¸ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅, Ņ‚Đž ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ ĐēĐžĐŊŅ„ĐģиĐē҂ҋ ĐŧĐĩĐļĐ´Ņƒ ĐŊиĐŧи. +И ваĐŧ ĐŊ҃ĐļĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž ŅŅ‚Đž Đ´ĐĩĐģаĐĩŅ‚ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ **даĐļĐĩ** ĐĩҁĐģи ĐŋĐžŅ‚ĐžĐŧ Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** (ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛) ŅĐ°ĐŧĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. Đ•ŅĐģи ŅŅ‚Đ¸ ŅˆĐ°ĐŗĐ¸ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ĐžĐŊи **Đ´ŅƒĐąĐģĐ¸Ņ€ŅƒŅŽŅ‚** Ņ€Đ°ĐąĐžŅ‚Ņƒ, СаĐŋŅƒŅŅ‚Đ¸Đ˛ ĐĩŅ‘ **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž**, и, ĐĩҁĐģи Ņ€ĐĩŅ‡ŅŒ Đž ҇ґĐŧâ€‘Ņ‚Đž Đ´ĐĩĐģиĐēĐ°Ņ‚ĐŊĐžĐŧ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đ¸ БД), ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐˇĐ˛Đ°Ņ‚ŅŒ ĐēĐžĐŊŅ„ĐģиĐē҂ҋ. -БĐĩĐˇŅƒŅĐģОвĐŊĐž, вОСĐŧĐžĐļĐŊŅ‹ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° ĐŊĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧ ĐŋŅ€Đ¸ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊии ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊОК ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đēи ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž иĐģи ĐŊĐĩҁĐēĐžĐģҌĐēĐž Ņ€Đ°Đˇ. ĐĸĐžĐŗĐ´Đ° ВаĐŧ ĐŋОвĐĩСĐģĐž, Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ ĐŊиĐŧи ĐŊаĐŧĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‰Đĩ. +КоĐŊĐĩ҇ĐŊĐž, ĐąŅ‹Đ˛Đ°ŅŽŅ‚ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° ĐŊĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧ, ĐĩҁĐģи ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‚ŅŅ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Ņ€Đ°Đˇ — Ņ‚ĐžĐŗĐ´Đ° Đ˛ŅŅ‘ ĐŋŅ€ĐžŅ‰Đĩ. -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… СаĐŋ҃ҁĐē Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **ĐŧĐžĐļĐĩŅ‚ ĐŊĐĩ ҂ҀĐĩĐąĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐēĐ¸Ņ…-ĐģийО ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ŅˆĐ°ĐŗĐžĐ˛ Đ˛ĐžĐ˛ŅĐĩ**. +ĐĸаĐēĐļĐĩ ŅƒŅ‡Ņ‚Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ Đ˛Đ°ŅˆĐĩĐš ҁ҅ĐĩĐŧŅ‹ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… **ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŧĐžĐŗŅƒŅ‚ Đ˛ĐžĐ˛ŅĐĩ ĐŊĐĩ ҂ҀĐĩĐąĐžĐ˛Đ°Ņ‚ŅŒŅŅ**. -Đ§Ņ‚Đž Đļ, Ņ‚ĐžĐŗĐ´Đ° ВаĐŧ ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐąĐĩҁĐŋĐžĐēĐžĐ¸Ņ‚ŅŒŅŅ Ой ŅŅ‚ĐžĐŧ. 🤷 +ĐĸĐžĐŗĐ´Đ° Ой ŅŅ‚ĐžĐŧ ĐŧĐžĐļĐŊĐž ĐŊĐĩ ĐąĐĩҁĐŋĐžĐēĐžĐ¸Ņ‚ŅŒŅŅ. 🤷 /// -### ĐŸŅ€Đ¸ĐŧĐĩҀҋ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš СаĐŋ҃ҁĐēа ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ŅˆĐ°ĐŗĐžĐ˛ +### ĐŸŅ€Đ¸ĐŧĐĩҀҋ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš Đ´ĐģŅ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ŅˆĐ°ĐŗĐžĐ˛ { #examples-of-previous-steps-strategies } -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ **ŅĐ¸ĐģҌĐŊĐ°Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŒ** ĐžŅ‚ Ņ‚ĐžĐŗĐž, ĐēаĐē Đ˛Ņ‹ **Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ŅĐ˛ĐžŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃**, СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēи и Ņ‚.Đ´. +Đ­Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ **ŅĐ¸ĐģҌĐŊĐž ĐˇĐ°Đ˛Đ¸ŅĐĩŅ‚ŅŒ** ĐžŅ‚ Ņ‚ĐžĐŗĐž, ĐēаĐē Đ˛Ņ‹ **Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧ҃**, ĐēаĐē СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹, ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēи и Ņ‚.Đ´. -Đ’ĐžŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ вОСĐŧĐžĐļĐŊŅ‹Đĩ идĐĩи: +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ вОСĐŧĐžĐļĐŊŅ‹Đĩ идĐĩи: -* ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии Kubernetes ĐŊ҃ĐļĐŊĐž ĐŋŅ€ĐĩĐ´ŅƒŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ "иĐŊĐ¸Ņ†Đ¸Đ°ĐģĐ¸ĐˇĐ¸Ņ€ŅƒŅŽŅ‰Đ¸Đš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€", СаĐŋ҃ҁĐēаĐĩĐŧŅ‹Đš Đ´Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. -* Bash-ҁĐēŅ€Đ¸ĐŋŅ‚, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‰Đ¸Đš ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸, а ĐˇĐ°Ņ‚ĐĩĐŧ СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Đš ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. - * ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ ВаĐŧ Đ˛ŅŅ‘ Đĩ҉ґ ĐŊ҃ĐļĐŊĐž ĐŊĐ°ĐšŅ‚Đ¸ ҁĐŋĐžŅĐžĐą - ĐēаĐē СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ/ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ *Ņ‚Đ°ĐēОК* bash-ҁĐēŅ€Đ¸ĐŋŅ‚, ОйĐŊĐ°Ņ€ŅƒĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐžŅˆĐ¸ĐąĐēи и Ņ‚.Đŋ. +* ÂĢInit ContainerÂģ в Kubernetes, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ ĐŋĐĩŅ€ĐĩĐ´ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐŧ ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ +* Bashâ€‘ŅĐēŅ€Đ¸ĐŋŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸, а ĐˇĐ°Ņ‚ĐĩĐŧ СаĐŋ҃ҁĐēаĐĩŅ‚ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ + * ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐŊ҃ĐļĐĩĐŊ ҁĐŋĐžŅĐžĐą СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ/ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ *ŅŅ‚ĐžŅ‚* bashâ€‘ŅĐēŅ€Đ¸ĐŋŅ‚, ОйĐŊĐ°Ņ€ŅƒĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ĐžŅˆĐ¸ĐąĐēи и Ņ‚.Đŋ. -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -Đ¯ ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņƒ ВаĐŧ йОĐģҌ҈Đĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐžĐ˛ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи в ĐŗĐģавĐĩ: [FastAPI вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ - Docker](docker.md){.internal-link target=_blank}. +Đ¯ ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņƒ йОĐģĐĩĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ ҁ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи в ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐš ĐŗĐģавĐĩ: [FastAPI вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ — Docker](docker.md){.internal-link target=_blank}. /// -## ĐŖŅ‚Đ¸ĐģĐ¸ĐˇĐ°Ņ†Đ¸Ņ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ +## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ { #resource-utilization } -Đ’Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ Ņ€Đ°ŅĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚ Ņ€ĐĩŅŅƒŅ€ŅĐ°Đŧи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ’Đ°ŅˆĐ¸ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ĐŧĐžĐŗŅƒŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅ‚ŅŒ иĐģи **ŅƒŅ‚Đ¸ĐģĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ**, а иĐŧĐĩĐŊĐŊĐž - Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° и ĐžĐąŅŠŅ‘Đŧ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸. +Đ’Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€(а) — ŅŅ‚Đž **Ņ€ĐĩŅŅƒŅ€Ņ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Đ°ŅˆĐ¸ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ĐŧĐžĐŗŅƒŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅ‚ŅŒ иĐģи **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ**: Đ˛Ņ€ĐĩĐŧŅ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊиК ĐŊа CPU и Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅƒŅŽ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊŅƒŅŽ ĐŋаĐŧŅŅ‚ŅŒ (RAM). -КаĐē ĐŧĐŊĐžĐŗĐž ŅĐ¸ŅŅ‚ĐĩĐŧĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ Đ˛Ņ‹ ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚Đĩ ĐŋĐžŅ‚Ņ€ĐĩĐąĐ¸Ņ‚ŅŒ/ŅƒŅ‚Đ¸ĐģĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ? Đ•ŅĐģи ĐŊĐĩ ĐˇĐ°Đ´ŅƒĐŧŅ‹Đ˛Đ°Ņ‚ŅŒŅŅ, Ņ‚Đž ĐŧĐžĐļĐŊĐž ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Ņ‚ŅŒ - "ĐŊĐĩĐŧĐŊĐžĐŗĐž", ĐŊĐž ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ Đ’Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž вОСĐŧĐžĐļĐŊĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž**. +КаĐēŅƒŅŽ Đ´ĐžĐģŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅ‚ŅŒ/Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ? МоĐļĐŊĐž ĐŋĐžĐ´ŅƒĐŧĐ°Ņ‚ŅŒ ÂĢĐŊĐĩĐŧĐŊĐžĐŗĐžÂģ, ĐŊĐž ĐŊа ĐŋŅ€Đ°ĐēŅ‚Đ¸ĐēĐĩ Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅ‚ŅŒ **ĐŧаĐēŅĐ¸Đŧ҃Đŧ ĐąĐĩС ĐŋадĐĩĐŊиК**. -Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐģĐ°Ņ‚Đ¸Ņ‚Đĩ Са ŅĐžĐ´ĐĩŅ€ĐļаĐŊиĐĩ ҂Ҁґ҅ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛, ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐģĐ¸ŅˆŅŒ ĐŧаĐģŅƒŅŽ Ņ‡Đ°ŅŅ‚ŅŒ ŅĐ¸ŅŅ‚ĐĩĐŧĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ ĐēаĐļĐ´ĐžĐŗĐž иС ĐŊĐ¸Ņ…, Ņ‚Đž Đ˛Ņ‹ **Đ˛Ņ‹ĐąŅ€Đ°ŅŅ‹Đ˛Đ°ĐĩŅ‚Đĩ Đ´ĐĩĐŊŅŒĐŗĐ¸ ĐŊа вĐĩŅ‚ĐĩŅ€**, а Ņ‚Đ°ĐēĐļĐĩ **вĐŋŅƒŅŅ‚ŅƒŅŽ Ņ‚Ņ€Đ°Ņ‚Đ¸Ņ‚Đĩ ŅĐģĐĩĐēŅ‚Ņ€ĐžŅĐŊĐĩŅ€ĐŗĐ¸ŅŽ** и Ņ‚.Đŋ. +Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐģĐ°Ņ‚Đ¸Ņ‚Đĩ Са 3 ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐģĐ¸ŅˆŅŒ ĐŧаĐģŅƒŅŽ Ņ‡Đ°ŅŅ‚ŅŒ Đ¸Ņ… RAM и CPU, Đ˛Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, **Ņ‚Ņ€Đ°Ņ‚Đ¸Ņ‚Đĩ Đ´ĐĩĐŊŅŒĐŗĐ¸ вĐŋŅƒŅŅ‚ŅƒŅŽ** 💸 и **ŅĐģĐĩĐēŅ‚Ņ€ĐžŅĐŊĐĩŅ€ĐŗĐ¸ŅŽ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛** 🌎 и Ņ‚.Đŋ. -В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐąŅ‹ĐģĐž ĐąŅ‹ ĐģŅƒŅ‡ŅˆĐĩ ĐžĐąĐžĐšŅ‚Đ¸ŅŅŒ Đ´Đ˛ŅƒĐŧŅ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Đŧи, ĐŊĐž йОĐģĐĩĐĩ ĐŋĐžĐģĐŊĐž ŅƒŅ‚Đ¸ĐģĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… Ņ€ĐĩŅŅƒŅ€ŅŅ‹ (҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊŅ‹Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€, ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊŅƒŅŽ ĐŋаĐŧŅŅ‚ŅŒ, Đļґҁ҂ĐēиК Đ´Đ¸ŅĐē, ҁĐĩŅ‚Đ¸ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ даĐŊĐŊҋ҅ и Ņ‚.Đ´). +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐģŅƒŅ‡ŅˆĐĩ иĐŧĐĩŅ‚ŅŒ 2 ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ йОĐģĐĩĐĩ Đ˛Ņ‹ŅĐžĐēиК ĐŋŅ€ĐžŅ†ĐĩĐŊŅ‚ Đ¸Ņ… Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ (CPU, ĐŋаĐŧŅŅ‚ŅŒ, Đ´Đ¸ŅĐē, ҁĐĩŅ‚ĐĩĐ˛ŅƒŅŽ ĐŋĐžĐģĐžŅŅƒ и Ņ‚.Đ´.). -ĐĄ Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, ĐĩҁĐģи Đ˛Ņ‹ Ņ€Đ°ŅĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚Đĩ Ņ‚ĐžĐģҌĐēĐž Đ´Đ˛ŅƒĐŧŅ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Đŧи и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **ĐŊа 100% Đ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Ņ‹ и ĐŋаĐŧŅŅ‚ŅŒ**, ĐŊĐž ĐēаĐēОК-ĐģийО ĐŋŅ€ĐžŅ†Đĩҁҁ СаĐŋŅ€ĐžŅĐ¸Ņ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅƒŅŽ ĐŋаĐŧŅŅ‚ŅŒ, Ņ‚Đž ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊĐ°Ņ ŅĐ¸ŅŅ‚ĐĩĐŧа ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đļґҁ҂ĐēиК Đ´Đ¸ŅĐē Đ´ĐģŅ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ (а Đ´Đ¸ŅĐē Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ в Ņ‚Ņ‹ŅŅŅ‡Đ¸ Ņ€Đ°Đˇ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊĐĩĐĩ), а Ņ‚Đž Đ˛ĐžĐ˛ŅĐĩ **҃ĐŋĐ°Đ´Ņ‘Ņ‚**. ИĐģи ĐĩҁĐģи ĐēаĐēĐžĐŧ҃-Ņ‚Đž ĐŋŅ€ĐžŅ†Đĩҁҁ҃ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ, Ņ‚Đž ĐĩĐŧ҃ ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ ĐŋОдОĐļĐ´Đ°Ņ‚ŅŒ, ĐŋĐžĐēа ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ ĐžŅĐ˛ĐžĐąĐžĐ´Đ¸Ņ‚ŅŅ. +ĐĄ Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, ĐĩҁĐģи ҃ Đ˛Đ°Ņ 2 ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **100% Đ¸Ņ… CPU и RAM**, в ĐēаĐēĐžĐšâ€‘Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ йОĐģҌ҈Đĩ ĐŋаĐŧŅŅ‚Đ¸, и ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŊĐ°Ņ‡ĐŊґ҂ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´Đ¸ŅĐē ĐēаĐē ÂĢĐŋаĐŧŅŅ‚ŅŒÂģ (Ņ‡Ņ‚Đž в Ņ‚Ņ‹ŅŅŅ‡Đ¸ Ņ€Đ°Đˇ ĐŧĐĩĐ´ĐģĐĩĐŊĐŊĐĩĐĩ) иĐģи даĐļĐĩ **҃ĐŋĐ°Đ´Ņ‘Ņ‚**. ИĐģи ĐŋŅ€ĐžŅ†Đĩҁҁ҃ ĐŋĐžĐŊĐ°Đ´ĐžĐąŅŅ‚ŅŅ Đ˛Ņ‹Ņ‡Đ¸ŅĐģĐĩĐŊĐ¸Ņ, ĐŊĐž ĐĩĐŧ҃ ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ ĐļĐ´Đ°Ņ‚ŅŒ ĐžŅĐ˛ĐžĐąĐžĐļĐ´ĐĩĐŊĐ¸Ņ CPU. -В Ņ‚Đ°ĐēОК ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸Đ¸ ĐģŅƒŅ‡ŅˆĐĩ ĐŋОдĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ **Đĩ҉ґ ОдиĐŊ ҁĐĩŅ€Đ˛ĐĩŅ€** и ĐŋĐĩŅ€ĐĩŅ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžŅ†Đĩҁҁҋ ĐŧĐĩĐļĐ´Ņƒ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Đŧи, Ņ‡Ņ‚ĐžĐą Đ˛ŅĐĩĐŧ **Ņ…Đ˛Đ°Ņ‚Đ°ĐģĐž ĐŋаĐŧŅŅ‚Đ¸ и ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи**. +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐģŅƒŅ‡ŅˆĐĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ **Đĩ҉ґ ОдиĐŊ ҁĐĩŅ€Đ˛ĐĩŅ€** и СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Ņ‡Đ°ŅŅ‚ŅŒ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐŊа ĐŊŅ‘Đŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ Đ˛ŅĐĩŅ… ĐąŅ‹ĐģĐž **Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž RAM и Đ˛Ņ€ĐĩĐŧĐĩĐŊи CPU**. -ĐĸаĐēĐļĐĩ ĐĩŅŅ‚ŅŒ вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒ, Ņ‡Ņ‚Đž ĐŋĐž ĐēаĐēОК-Ņ‚Đž ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊĐĩ вОСĐŊиĐē **Đ˛ŅĐŋĐģĐĩҁĐē** СаĐŋŅ€ĐžŅĐžĐ˛ Đē Đ˛Đ°ŅˆĐĩĐŧ҃ API. ВозĐŧĐžĐļĐŊĐž, ŅŅ‚Đž ĐąŅ‹Đģ Đ˛Đ¸Ņ€ŅƒŅ, ĐąĐžŅ‚Ņ‹ иĐģи Đ´Ņ€ŅƒĐŗĐ¸Đĩ ҁĐĩŅ€Đ˛Đ¸ŅŅ‹ ĐŊĐ°Ņ‡Đ°Đģи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ иĐŧ. И Đ´ĐģŅ Ņ‚Đ°ĐēĐ¸Ņ… ĐŋŅ€ĐžĐ¸ŅŅˆĐĩŅŅ‚Đ˛Đ¸Đš Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Ņ…ĐžŅ‚ĐĩŅ‚ŅŒ иĐŧĐĩŅ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ Ņ€ĐĩŅŅƒŅ€ŅŅ‹. +ĐĸаĐēĐļĐĩ вОСĐŧĐžĐļĐĩĐŊ **Đ˛ŅĐŋĐģĐĩҁĐē** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ˛Đ°ŅˆĐĩĐŗĐž API: ĐžĐŊ ĐŧĐžĐŗ ÂĢĐ˛ĐˇĐžŅ€Đ˛Đ°Ņ‚ŅŒŅŅÂģ ĐŋĐž ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊĐžŅŅ‚Đ¸, иĐģи ĐēаĐēиĐĩâ€‘Ņ‚Đž ҁĐĩŅ€Đ˛Đ¸ŅŅ‹/ĐąĐžŅ‚Ņ‹ ĐŊĐ°Ņ‡Đ°Đģи ĐĩĐŗĐž аĐēŅ‚Đ¸Đ˛ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ. На Ņ‚Đ°ĐēиĐĩ ҁĐģŅƒŅ‡Đ°Đ¸ ŅŅ‚ĐžĐ¸Ņ‚ иĐŧĐĩŅ‚ŅŒ СаĐŋĐ°Ņ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛. -ĐŸŅ€Đ¸ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ ĐģĐžĐŗĐ¸Đēи Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиК, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ **҆ĐĩĐģĐĩвОĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ** ŅƒŅ‚Đ¸ĐģĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛, Đ´ĐžĐŋŅƒŅŅ‚Đ¸Đŧ, **ĐžŅ‚ 50% Đ´Đž 90%**. ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚Đ¸ ĐŧĐĩŅ‚Ņ€Đ¸Đēи и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚. +МоĐļĐŊĐž ĐˇĐ°Đ´Đ°Ņ‚ŅŒ **҆ĐĩĐģĐĩвОĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ **ĐŧĐĩĐļĐ´Ņƒ 50% и 90%** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛. ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, иĐŧĐĩĐŊĐŊĐž ŅŅ‚Đ¸ вĐĩŅ‰Đ¸ Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ иСĐŧĐĩŅ€ŅŅ‚ŅŒ и ĐŊа Đ¸Ņ… ĐžŅĐŊОвĐĩ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°Ņ‚ŅŒ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ. -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, Ņ‚Đ°ĐēиĐĩ ĐēаĐē `htop`, Đ´ĐģŅ ĐžŅ‚ŅĐģĐĩĐļиваĐŊĐ¸Ņ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° и ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, в Ņ‚ĐžĐŧ Ņ‡Đ¸ŅĐģĐĩ ĐēаĐļĐ´Ņ‹Đŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ. ИĐģи йОĐģĐĩĐĩ ҁĐģĐžĐļĐŊŅ‹Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ĐŧĐžĐŊĐ¸Ņ‚ĐžŅ€Đ¸ĐŊĐŗĐ° ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛. +МоĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Đ˛Ņ€ĐžĐ´Đĩ `htop`, Ņ‡Ņ‚ĐžĐąŅ‹ ҁĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐē҃ CPU и RAM ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ иĐģи ĐŋĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧ. ИĐģи йОĐģĐĩĐĩ ҁĐģĐžĐļĐŊŅ‹Đĩ Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ĐŧĐžĐŊĐ¸Ņ‚ĐžŅ€Đ¸ĐŊĐŗĐ°. -## Đ ĐĩĐˇŅŽĐŧĐĩ +## Đ ĐĩĐˇŅŽĐŧĐĩ { #recap } -Đ’Ņ‹ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Đģи ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ иС ĐžŅĐŊОвĐŊҋ҅ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž иĐŧĐĩŅ‚ŅŒ в Đ˛Đ¸Đ´Ņƒ ĐŋŅ€Đ¸ ĐŋŅ€Đ¸ĐŊŅŅ‚Đ¸Đ¸ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ Đž Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК: +ЗдĐĩҁҌ Đ˛Ņ‹ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Đģи Đž ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžŅĐŊОвĐŊҋ҅ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅŅ…, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ŅŅ‚ĐžĐ¸Ņ‚ ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ Đ˛Ņ‹ĐąĐžŅ€Đĩ ҁĐŋĐžŅĐžĐąĐ° Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ: -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS -* ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ПĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. +* БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ -ĐžŅĐžĐˇĐŊаĐŊиĐĩ ŅŅ‚Đ¸Ņ… идĐĩĐš и Ņ‚ĐžĐŗĐž, ĐēаĐē Đ¸Ņ… ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅ‚ŅŒ, Đ´ĐžĐģĐļĐŊĐž Đ´Đ°Ņ‚ŅŒ ВаĐŧ иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐžĐĩ ĐŋĐžĐŊиĐŧаĐŊиĐĩ, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžĐĩ Đ´ĐģŅ ĐŋŅ€Đ¸ĐŊŅŅ‚Đ¸Ņ Ņ€Đĩ҈ĐĩĐŊиК ĐŋŅ€Đ¸ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊиК. 🤓 +ПоĐŊиĐŧаĐŊиĐĩ ŅŅ‚Đ¸Ņ… идĐĩĐš и Ņ‚ĐžĐŗĐž, ĐēаĐē Đ¸Ņ… ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅ‚ŅŒ, Đ´Đ°ŅŅ‚ ваĐŧ иĐŊŅ‚ŅƒĐ¸Ņ†Đ¸ŅŽ, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅƒŅŽ Đ´ĐģŅ ĐŋŅ€Đ¸ĐŊŅŅ‚Đ¸Ņ Ņ€Đĩ҈ĐĩĐŊиК ĐŋŅ€Đ¸ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ и Đ´ĐžŅ€Đ°ĐąĐžŅ‚ĐēĐĩ Đ˛Đ°ŅˆĐ¸Ņ… Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиК. 🤓 -В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… Ņ€Đ°ĐˇĐ´ĐĩĐģĐ°Ņ… Ņ ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņƒ йОĐģĐĩĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ вОСĐŧĐžĐļĐŊҋ҅ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҁĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ŅŒ. 🚀 +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… Ņ€Đ°ĐˇĐ´ĐĩĐģĐ°Ņ… Ņ ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņƒ йОĐģĐĩĐĩ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ вОСĐŧĐžĐļĐŊҋ҅ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš. 🚀 diff --git a/docs/ru/docs/deployment/docker.md b/docs/ru/docs/deployment/docker.md index c72f67172..3937b0165 100644 --- a/docs/ru/docs/deployment/docker.md +++ b/docs/ru/docs/deployment/docker.md @@ -1,17 +1,17 @@ -# FastAPI и Docker-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ +# FastAPI в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ… — Docker { #fastapi-in-containers-docker } -ĐŸŅ€Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК FastAPI, Ņ‡Đ°ŅŅ‚Đž ĐŊĐ°Ņ‡Đ¸ĐŊĐ°ŅŽŅ‚ ҁ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ **ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŊа ĐžŅĐŊОвĐĩ Linux**. ĐžĐąŅ‹Ņ‡ĐŊĐž Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ **Docker**. Đ—Đ°Ņ‚ĐĩĐŧ ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐ˛ĐĩŅ€ĐŊŅƒŅ‚ŅŒ Ņ‚Đ°ĐēОК ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ ОдĐŊиĐŧ иС ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ҁĐŋĐžŅĐžĐąĐžĐ˛. +ĐŸŅ€Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК FastAPI Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅ‘ĐŊĐŊŅ‹Đš ĐŋĐžĐ´Ņ…ĐžĐ´ — ŅĐžĐąĐ¸Ņ€Đ°Ņ‚ŅŒ **ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŊа Linux**. ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚Đž Đ´ĐĩĐģĐ°ŅŽŅ‚ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **Docker**. Đ—Đ°Ņ‚ĐĩĐŧ Ņ‚Đ°ĐēОК ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐ˛ĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ҁĐŋĐžŅĐžĐąĐ°Đŧи. -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ĐŊа ĐžŅĐŊОвĐĩ Linux иĐŧĐĩĐĩŅ‚ Ņ€ŅĐ´ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛, вĐēĐģŅŽŅ‡Đ°Ņ **ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ**, **Đ˛ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸ĐŧĐžŅŅ‚ŅŒ**, **ĐŋŅ€ĐžŅŅ‚ĐžŅ‚Ņƒ** и ĐŋŅ€ĐžŅ‡Đ¸Đĩ. +Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Linux-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ Đ´Đ°Ņ‘Ņ‚ Ņ€ŅĐ´ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛: **ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ**, **Đ˛ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸ĐŧĐžŅŅ‚ŅŒ**, **ĐŋŅ€ĐžŅŅ‚ĐžŅ‚Ņƒ** и Đ´Ņ€ŅƒĐŗĐ¸Đĩ. /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -ĐĸĐžŅ€ĐžĐŋĐ¸Ņ‚ĐĩҁҌ иĐģи ҃ĐļĐĩ СĐŊаĐēĐžĐŧŅ‹ ҁ ŅŅ‚ĐžĐš Ņ‚ĐĩŅ…ĐŊĐžĐģĐžĐŗĐ¸ĐĩĐš? ПĐĩŅ€ĐĩĐŋŅ€Ņ‹ĐŗĐŊĐ¸Ņ‚Đĩ ĐŊа Ņ€Đ°ĐˇĐ´ĐĩĐģ [ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ FastAPI 👇](#docker-fastapi) +НĐĩŅ‚ Đ˛Ņ€ĐĩĐŧĐĩĐŊи и Đ˛Ņ‹ ҃ĐļĐĩ СĐŊаĐēĐžĐŧŅ‹ ҁ ŅŅ‚Đ¸Đŧ? ПĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ Đē [`Dockerfile` ĐŊиĐļĐĩ 👇](#build-a-docker-image-for-fastapi). ///
-РаСвĐĩŅ€ĐŊŅƒŅ‚ŅŒ Dockerfile 👀 +ĐŸŅ€ĐĩĐ´ĐŋŅ€ĐžŅĐŧĐžŅ‚Ņ€ Dockerfile 👀 ```Dockerfile FROM python:3.9 @@ -24,130 +24,125 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt COPY ./app /code/app -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +CMD ["fastapi", "run", "app/main.py", "--port", "80"] -# Đ•ŅĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€, Ņ‚Đ°ĐēОК ĐēаĐē Nginx иĐģи Traefik, Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ --proxy-headers -# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"] +# Đ•ŅĐģи СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ Са ĐŋŅ€ĐžĐēŅĐ¸, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Nginx иĐģи Traefik, Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ --proxy-headers +# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"] ```
-## Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ "ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€" +## Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ { #what-is-a-container } -КоĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ¸ĐˇĐ°Ņ†Đ¸Ņ - ŅŅ‚Đž **ĐģĐĩĐŗĐēОвĐĩҁĐŊŅ‹Đš** ҁĐŋĐžŅĐžĐą ҃ĐŋаĐēĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, вĐēĐģŅŽŅ‡Đ°Ņ Đ˛ŅĐĩ ĐĩĐŗĐž ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ и ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Ņ„Đ°ĐšĐģŅ‹, Ņ‡Ņ‚ĐžĐąŅ‹ иСОĐģĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž ĐžŅ‚ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ (Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК и ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛) Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐŊа ŅŅ‚ĐžĐš ĐļĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ. +КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ (в ĐžŅĐŊОвĐŊĐžĐŧ Linux-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ) — ŅŅ‚Đž ĐžŅ‡ĐĩĐŊҌ **ĐģĐĩĐŗĐēОвĐĩҁĐŊŅ‹Đš** ҁĐŋĐžŅĐžĐą ҃ĐŋаĐēĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ вĐŧĐĩҁ҂Đĩ ŅĐž Đ˛ŅĐĩĐŧи Đ¸Ņ… ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи и ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đŧи Ņ„Đ°ĐšĐģаĐŧи, иСОĐģĐ¸Ņ€ĐžĐ˛Đ°Đ˛ Đ¸Ņ… ĐžŅ‚ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ (Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК иĐģи ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛) в Ņ‚ĐžĐš ĐļĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧĐĩ. -КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ, ĐžŅĐŊОваĐŊĐŊŅ‹Đĩ ĐŊа Linux, СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ŅĐ´Ņ€Đž Linux Ņ…ĐžŅŅ‚Đ° (ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и Ņ‚.Đŋ.). Đ­Ņ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž ĐžĐŊи ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēОвĐĩҁĐŊŅ‹Đĩ (ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ҁ ĐŋĐžĐģĐŊĐžŅ†ĐĩĐŊĐŊŅ‹Đŧи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅ‹Đŧи ĐŧĐ°ŅˆĐ¸ĐŊаĐŧи, ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐŧ҃ĐģĐ¸Ņ€ŅƒŅŽŅ‰Đ¸Đŧи Ņ€Đ°ĐąĐžŅ‚Ņƒ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹). +Linux-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ŅŅ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ‚Đž ĐļĐĩ ŅĐ´Ņ€Đž Linux Ņ…ĐžŅŅ‚Đ° (ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и Ņ‚.Đŋ.). Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐžĐŊи ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēОвĐĩҁĐŊŅ‹Đĩ (ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ҁ ĐŋĐžĐģĐŊĐžŅ†ĐĩĐŊĐŊŅ‹Đŧи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅ‹Đŧи ĐŧĐ°ŅˆĐ¸ĐŊаĐŧи, ŅĐŧ҃ĐģĐ¸Ņ€ŅƒŅŽŅ‰Đ¸Đŧи ҆ĐĩĐģŅƒŅŽ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃). -БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃, ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅŽŅ‚ **ĐŧаĐģĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛**, ŅŅ€Đ°Đ˛ĐŊиĐŧĐžĐĩ ҁ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đŧ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒĐĩŅ‚ ĐŗĐžŅ€Đ°ĐˇĐ´Đž йОĐģҌ҈Đĩ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛). +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅŅŽŅ‚ **ĐŧаĐģĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛**, ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸ĐŧĐžĐĩ ҁ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ (Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа ĐŋĐžŅ‚Ņ€ĐĩйОваĐģа ĐąŅ‹ ĐŊаĐŧĐŊĐžĐŗĐž йОĐģҌ҈Đĩ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛). -КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ Ņ‚Đ°ĐēĐļĐĩ иĐŧĐĩŅŽŅ‚ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đĩ **иСОĐģĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ** ĐŋŅ€ĐžŅ†Đĩҁҁҋ (ĐŊĐž Ņ‡Đ°ŅŅ‚Đž Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ), Ņ„Đ°ĐšĐģĐžĐ˛ŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ и ҁĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž ҃ĐŋŅ€ĐžŅ‰Đ°ĐĩŅ‚ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ, Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đē҃, ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ Đ´ĐžŅŅ‚ŅƒĐŋĐžĐŧ и Ņ‚.Đŋ. +ĐŖ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ Ņ‚Đ°ĐēĐļĐĩ ĐĩŅŅ‚ŅŒ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ **иСОĐģĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ** Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩĐŧŅ‹Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ (ĐžĐąŅ‹Ņ‡ĐŊĐž Đ˛ŅĐĩĐŗĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ), Ņ„Đ°ĐšĐģĐžĐ˛Đ°Ņ ŅĐ¸ŅŅ‚ĐĩĐŧа и ҁĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž ҃ĐŋŅ€ĐžŅ‰Đ°ĐĩŅ‚ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ, ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ, Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đē҃ и Ņ‚.Đ´. -## Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ "ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°" +## Đ§Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° { #what-is-a-container-image } -ДĐģŅ СаĐŋ҃ҁĐēа **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°** ĐŊ҃ĐļĐĩĐŊ **ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**. +**КоĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** СаĐŋ҃ҁĐēаĐĩŅ‚ŅŅ иС **ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**. -ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° - ŅŅ‚Đž **СаĐŧĐžŅ€ĐžĐļĐĩĐŊĐŊĐ°Ņ** вĐĩŅ€ŅĐ¸Ņ Đ˛ŅĐĩŅ… Ņ„Đ°ĐšĐģОв, ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ, ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ и ĐēĐžĐŧаĐŊĐ´ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. **ЗаĐŧĐžŅ€ĐžĐļĐĩĐŊĐŊŅ‹Đš** - ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž **ĐžĐąŅ€Đ°Đˇ** ĐŊĐĩ СаĐŋŅƒŅ‰ĐĩĐŊ и ĐŊĐĩ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ, ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ҃ĐŋаĐēОваĐŊĐŊŅ‹Đĩ вĐŧĐĩҁ҂Đĩ Ņ„Đ°ĐšĐģŅ‹ и ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ. +ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° — ŅŅ‚Đž **ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ** вĐĩŅ€ŅĐ¸Ņ Đ˛ŅĐĩŅ… Ņ„Đ°ĐšĐģОв, ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ и ĐēĐžĐŧаĐŊĐ´Ņ‹/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ´ĐžĐģĐļĐŊŅ‹ ĐŋŅ€Đ¸ŅŅƒŅ‚ŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ. ЗдĐĩҁҌ **ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ** ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž **ĐžĐąŅ€Đ°Đˇ** ĐŊĐĩ СаĐŋŅƒŅ‰ĐĩĐŊ, ĐžĐŊ ĐŊĐĩ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ — ŅŅ‚Đž Ņ‚ĐžĐģҌĐēĐž ҃ĐŋаĐēОваĐŊĐŊŅ‹Đĩ Ņ„Đ°ĐšĐģŅ‹ и ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ. -В ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚ **ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**, Ņ…Ņ€Đ°ĐŊŅŅ‰ĐĩĐŗĐž ĐŊĐĩиСĐŧĐĩĐŊĐŊĐžĐĩ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ, ĐŋОд Ņ‚ĐĩŅ€ĐŧиĐŊĐžĐŧ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** ĐŋĐžĐ´Ņ€Đ°ĐˇŅƒĐŧĐĩĐ˛Đ°ŅŽŅ‚ СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ, Ņ‚Đž ĐĩŅŅ‚ŅŒ ĐžĐąŅŠŅ‘ĐēŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš **Đ¸ŅĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ**. +В ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐžĐŋĐžĐģĐžĐļĐŊĐžŅŅ‚ŅŒ ÂĢ**ĐžĐąŅ€Đ°ĐˇŅƒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**Âģ (Ņ…Ņ€Đ°ĐŊŅŅ‰ĐĩĐŧ҃ ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ ŅĐžĐ´ĐĩŅ€ĐļиĐŧĐžĐĩ), ÂĢ**ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**Âģ ĐžĐąŅ‹Ņ‡ĐŊĐž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚ СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ŅĐēСĐĩĐŧĐŋĐģŅŅ€, Ņ‚Đž, Ņ‡Ņ‚Đž **Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ**. -ĐšĐžĐŗĐ´Đ° **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** СаĐŋŅƒŅ‰ĐĩĐŊ (ĐŊа ĐžŅĐŊОваĐŊии **ĐžĐąŅ€Đ°ĐˇĐ°**), ĐžĐŊ ĐŧĐžĐļĐĩŅ‚ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ и иСĐŧĐĩĐŊŅŅ‚ŅŒ Ņ„Đ°ĐšĐģŅ‹, ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ и Ņ‚.Đ´. Đ­Ņ‚Đ¸ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ĐąŅƒĐ´ŅƒŅ‚ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°, ĐŊĐž ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ ŅĐžŅ…Ņ€Đ°ĐŊŅŅ‚ŅŒŅŅ в ĐžĐąŅ€Đ°ĐˇĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° (ĐŊĐĩ ĐąŅƒĐ´ŅƒŅ‚ ŅĐžŅ…Ņ€Đ°ĐŊĐĩĐŊŅ‹ ĐŊа Đ´Đ¸ŅĐē). +ĐšĐžĐŗĐ´Đ° **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** СаĐŋŅƒŅ‰ĐĩĐŊ (ĐŊа ĐžŅĐŊОвĐĩ **ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**), ĐžĐŊ ĐŧĐžĐļĐĩŅ‚ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ иĐģи иСĐŧĐĩĐŊŅŅ‚ŅŒ Ņ„Đ°ĐšĐģŅ‹, ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ и Ņ‚.Đ´.. Đ­Ņ‚Đ¸ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‚ Ņ‚ĐžĐģҌĐēĐž вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° и ĐŊĐĩ ŅĐžŅ…Ņ€Đ°ĐŊŅŅŽŅ‚ŅŅ в Đ¸ŅŅ…ĐžĐ´ĐŊĐžĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° (ĐŊĐĩ СаĐŋĐ¸ŅŅ‹Đ˛Đ°ŅŽŅ‚ŅŅ ĐŊа Đ´Đ¸ŅĐē). -ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŧĐžĐļĐŊĐž ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ ҁ Ņ„Đ°ĐšĐģĐžĐŧ, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰ĐĩĐŧ **ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēаĐē Ņ„Đ°ĐšĐģ `main.py`. +ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŧĐžĐļĐŊĐž ŅŅ€Đ°Đ˛ĐŊĐ¸Ņ‚ŅŒ ҁ **Ņ„Đ°ĐšĐģаĐŧи ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `python` и ĐēаĐēиĐŧ-Ņ‚Đž Ņ„Đ°ĐšĐģĐžĐŧ `main.py`. -И **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** (в ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚ **ĐžĐąŅ€Đ°ĐˇĐ°**) - ŅŅ‚Đž ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩĐŧŅ‹Đš ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ĐžĐąŅ€Đ°ĐˇĐ°, ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž ĐēаĐē **ĐŋŅ€ĐžŅ†Đĩҁҁ**. По Ņ„Đ°ĐēŅ‚Ņƒ, ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ СаĐŋŅƒŅ‰ĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž ĐēĐžĐŗĐ´Đ° СаĐŋŅƒŅ‰ĐĩĐŊŅ‹ ĐĩĐŗĐž ĐŋŅ€ĐžŅ†Đĩҁҁҋ (Ņ‡Đ°Ņ‰Đĩ, Đ˛ŅĐĩĐŗĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ) и ĐžŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ, ĐēĐžĐŗĐ´Đ° СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐŊĐĩŅ‚. +А ŅĐ°Đŧ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** (в ĐžŅ‚ĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚ **ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**) — ŅŅ‚Đž Ņ„Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ŅĐēСĐĩĐŧĐŋĐģŅŅ€ ĐžĐąŅ€Đ°ĐˇĐ°, ŅĐžĐŋĐžŅŅ‚Đ°Đ˛Đ¸ĐŧŅ‹Đš ҁ **ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ**. По ŅŅƒŅ‚Đ¸, ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Ņ‚ĐžĐģҌĐēĐž Ņ‚ĐžĐŗĐ´Đ°, ĐēĐžĐŗĐ´Đ° в ĐŊŅ‘Đŧ ĐĩŅŅ‚ŅŒ **СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ** (и ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚Đž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ). КоĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐžŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚ŅŅ, ĐēĐžĐŗĐ´Đ° в ĐŊŅ‘Đŧ ĐŊĐĩ ĐžŅŅ‚Đ°Ņ‘Ņ‚ŅŅ СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛. -## ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ +## ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ { #container-images } -Docker ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ОдĐŊиĐŧ иС ĐžŅĐŊОвĐŊҋ҅ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ **ĐžĐąŅ€Đ°ĐˇĐžĐ˛** и **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** и ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ иĐŧи. +Docker — ОдиĐŊ иС ĐžŅĐŊОвĐŊҋ҅ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ и ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ **ĐžĐąŅ€Đ°ĐˇĐ°Đŧи ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** и **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи**. -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐžĐąŅ‰ĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đš Docker Hub ҁ ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛ĐģĐĩĐŊĐŊŅ‹Đŧи **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đŧи ĐžĐąŅ€Đ°ĐˇĐ°Đŧи** ĐŧĐŊĐžĐŗĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐžĐēŅ€ŅƒĐļĐĩĐŊиК, йаС даĐŊĐŊҋ҅ и ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. +ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš Docker Hub ҁ ĐŗĐžŅ‚ĐžĐ˛Ņ‹Đŧи **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đŧи ĐžĐąŅ€Đ°ĐˇĐ°Đŧи** Đ´ĐģŅ ĐŧĐŊĐžĐŗĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, ĐžĐēŅ€ŅƒĐļĐĩĐŊиК, йаС даĐŊĐŊҋ҅ и ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. -К ĐŋŅ€Đ¸ĐŧĐĩŅ€Ņƒ, ĐĩŅŅ‚ŅŒ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ Python. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩŅŅ‚ŅŒ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ Python. -ĐĸаĐēĐļĐĩ Ņ‚Đ°Đŧ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģĐĩĐŊŅ‹ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋĐžĐģĐĩСĐŊŅ‹Đĩ ĐžĐąŅ€Đ°ĐˇŅ‹, Ņ‚Đ°ĐēиĐĩ ĐēаĐē ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅: +А Ņ‚Đ°ĐēĐļĐĩ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐžĐąŅ€Đ°ĐˇĐžĐ˛ Đ´ĐģŅ Ņ€Đ°ĐˇĐŊҋ҅ вĐĩ҉ĐĩĐš, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ йаС даĐŊĐŊҋ҅: * PostgreSQL * MySQL * MongoDB -* Redis +* Redis, и Ņ‚.Đ´. -и Ņ‚.Đŋ. +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŗĐžŅ‚ĐžĐ˛Ņ‹Đĩ ĐžĐąŅ€Đ°ĐˇŅ‹, ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēĐž **ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ** Ņ€Đ°ĐˇĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ…. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐžĐ˛ŅƒŅŽ ĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅. В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ĐŧĐžĐļĐŊĐž Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đŧи ĐžĐąŅ€Đ°ĐˇĐ°Đŧи** и ĐŋŅ€ĐžŅŅ‚Đž ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ Đ¸Ņ… ҇ĐĩŅ€ĐĩС ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ. -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛ĐģĐĩĐŊĐŊҋ҅ ĐžĐąŅ€Đ°ĐˇĐžĐ˛ СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž ҃ĐŋŅ€ĐžŅ‰Đ°ĐĩŅ‚ **ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ** и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Ņ€Đ°ĐˇĐŊҋ҅ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐžĐ˛ŅƒŅŽ ĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅. В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ** и Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ. +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ĐˇŅƒŅ‡Đ¸Ņ‚ŅŒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ и Docker и ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ СĐŊаĐŊĐ¸Ņ ҁ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛ĐžĐŧ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊҋ҅ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ĐˇŅƒŅ‡Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ¸ĐˇĐ°Ņ†Đ¸Ņ и Docker, и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đĩ СĐŊаĐŊĐ¸Ņ ҁ Ņ€Đ°ĐˇĐŊŅ‹Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи и ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚Đ°Đŧи. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**: ҁ йаСОК даĐŊĐŊҋ҅, Python-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ, вĐĩĐą-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ҁ Ņ„Ņ€ĐžĐŊŅ‚ĐĩĐŊĐ´ĐžĐŧ ĐŊа React и ŅĐ˛ŅĐˇĐ°Ņ‚ŅŒ Đ¸Ņ… ҇ĐĩŅ€ĐĩС вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊŅŽŅŽ ҁĐĩŅ‚ŅŒ. -ĐĸаĐē, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ҁ йаСОК даĐŊĐŊҋ҅, Python-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ, вĐĩĐą-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ, React-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ и ŅĐžĐĩдиĐŊĐ¸Ņ‚ŅŒ Đ¸Ņ… вĐŧĐĩҁ҂Đĩ ҇ĐĩŅ€ĐĩС вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊŅŽŅŽ ҁĐĩŅ‚ŅŒ. +Đ’ŅĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи (Ņ‚Đ°ĐēиĐĩ ĐēаĐē Docker иĐģи Kubernetes) иĐŧĐĩŅŽŅ‚ иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Đ´ĐģŅ Ņ‚Đ°ĐēĐžĐŗĐž ҁĐĩŅ‚ĐĩĐ˛ĐžĐŗĐž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ. -Đ’ŅĐĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи (Ņ‚Đ°ĐēиĐĩ, ĐēаĐē Docker иĐģи Kubernetes) иĐŧĐĩŅŽŅ‚ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Đ´ĐģŅ ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ Ņ‚Đ°ĐēĐžĐŗĐž ҁĐĩŅ‚ĐĩĐ˛ĐžĐŗĐž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ. +## КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ и ĐŋŅ€ĐžŅ†Đĩҁҁҋ { #containers-and-processes } -## КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ и ĐŋŅ€ĐžŅ†Đĩҁҁҋ +**ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°** ĐžĐąŅ‹Ņ‡ĐŊĐž вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ в ŅĐ˛ĐžĐ¸ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ иĐģи ĐēĐžĐŧаĐŊĐ´Ņƒ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**, а Ņ‚Đ°ĐēĐļĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ, ĐŋĐĩŅ€ĐĩдаваĐĩĐŧŅ‹Đĩ ŅŅ‚ĐžĐš ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ. Đ­Ņ‚Đž ĐžŅ‡ĐĩĐŊҌ ĐŋĐžŅ…ĐžĐļĐĩ ĐŊа СаĐŋ҃ҁĐē ĐēĐžĐŧаĐŊĐ´Ņ‹ в Ņ‚ĐĩŅ€ĐŧиĐŊаĐģĐĩ. -ĐžĐąŅ‹Ņ‡ĐŊĐž **ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°** ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ ĐŋŅ€ĐĩĐ´ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ иĐģи ĐēĐžĐŧаĐŊĐ´Ņƒ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**. ĐĸаĐēĐļĐĩ ĐžĐŊ ĐŧĐžĐļĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ, ĐŋĐĩŅ€ĐĩдаваĐĩĐŧŅ‹Đĩ ĐŋŅ€ĐĩĐ´ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐĩ. ĐŸĐžŅ…ĐžĐļĐĩ ĐŊа Ņ‚Đž, ĐēаĐē ĐĩҁĐģи ĐąŅ‹ Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐģи Ņ‚Đ°ĐēŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ ҇ĐĩŅ€ĐĩС Ņ‚ĐĩŅ€ĐŧиĐŊаĐģ. +ĐšĐžĐŗĐ´Đ° **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** ŅŅ‚Đ°Ņ€Ņ‚ŅƒĐĩŅ‚, ĐžĐŊ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ ҃ĐēаСаĐŊĐŊŅƒŅŽ ĐēĐžĐŧаĐŊĐ´Ņƒ/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ (Ņ…ĐžŅ‚Ņ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ŅŅ‚Đž и СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗŅƒŅŽ ĐēĐžĐŧаĐŊĐ´Ņƒ/ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃). -ĐšĐžĐŗĐ´Đ° **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** СаĐŋŅƒŅ‰ĐĩĐŊ, ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ ĐŋŅ€ĐžĐŋĐ¸ŅĐ°ĐŊĐŊŅ‹Đĩ в ĐŊŅ‘Đŧ ĐēĐžĐŧаĐŊĐ´Ņ‹ и ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹. Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ĐĩĐŗĐž Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐą ĐžĐŊ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐģ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐēĐžĐŧаĐŊĐ´Ņ‹ и ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹. +КоĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Đ´Đž Ņ‚ĐĩŅ… ĐŋĐžŅ€, ĐŋĐžĐēа Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐĩĐŗĐž **ĐŗĐģавĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ** (ĐēĐžĐŧаĐŊда иĐģи ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа). -КоĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ Đ´Đž Ņ‚ĐĩŅ… ĐŋĐžŅ€, ĐŋĐžĐēа Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ ĐĩĐŗĐž **ĐŗĐģавĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ** (ĐēĐžĐŧаĐŊда иĐģи ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа). +ĐžĐąŅ‹Ņ‡ĐŊĐž в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐĩŅŅ‚ŅŒ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**, ĐŊĐž ĐŗĐģавĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐŋОдĐŋŅ€ĐžŅ†Đĩҁҁҋ, и Ņ‚ĐžĐŗĐ´Đ° в Ņ‚ĐžĐŧ ĐļĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐąŅƒĐ´ĐĩŅ‚ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**. -В ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐžĐąŅ‹Ņ‡ĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**, ĐŊĐž ĐžŅ‚ ĐĩĐŗĐž иĐŧĐĩĐŊи ĐŧĐžĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ, Ņ‚ĐžĐŗĐ´Đ° в ŅŅ‚ĐžĐŧ ĐļĐĩ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**. +НĐĩĐģŅŒĐˇŅ иĐŧĐĩŅ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐąĐĩС **Ņ…ĐžŅ‚Ņ ĐąŅ‹ ОдĐŊĐžĐŗĐž СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°**. Đ•ŅĐģи ĐŗĐģавĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ ĐžŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚ŅŅ, ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐžŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚ŅŅ. -КоĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐŊĐĩ ŅŅ‡Đ¸Ņ‚Đ°ĐĩŅ‚ŅŅ СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đŧ, ĐĩҁĐģи в ĐŊŅ‘Đŧ **ĐŊĐĩ Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ Ņ…ĐžŅ‚Ņ ĐąŅ‹ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**. Đ•ŅĐģи ĐŗĐģавĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ ĐžŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ, СĐŊĐ°Ņ‡Đ¸Ņ‚ и ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐžŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ. +## ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ FastAPI { #build-a-docker-image-for-fastapi } -## ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ FastAPI +Đ˜Ņ‚Đ°Đē, Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ Ņ‡Ņ‚Đž-ĐŊĐ¸ĐąŅƒĐ´ŅŒ ŅĐžĐąĐĩҀґĐŧ! 🚀 -Đ§Ņ‚Đž Đļ, Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ҃ĐļŅ‘ ŅĐžĐˇĐ´Đ°Đ´Đ¸Đŧ Ņ‡Ņ‚Đž-ĐŊĐ¸ĐąŅƒĐ´ŅŒ! 🚀 +Đ¯ ĐŋĐžĐēаĐļ҃, ĐēаĐē ŅĐžĐąŅ€Đ°Ņ‚ŅŒ **Docker-ĐžĐąŅ€Đ°Đˇ** Đ´ĐģŅ FastAPI **ҁ ĐŊ҃ĐģŅ** ĐŊа ĐžŅĐŊОвĐĩ **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŗĐž ĐžĐąŅ€Đ°ĐˇĐ° Python**. -Đ¯ ĐŋĐžĐēаĐļ҃ ВаĐŧ, ĐēаĐē ŅĐžĐąĐ¸Ņ€Đ°Ņ‚ŅŒ **Docker-ĐžĐąŅ€Đ°Đˇ** Đ´ĐģŅ FastAPI **ҁ ĐŊ҃ĐģŅ**, ĐžŅĐŊĐžĐ˛Ņ‹Đ˛Đ°ŅŅŅŒ ĐŊа **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ Python**. +ИĐŧĐĩĐŊĐŊĐž Ņ‚Đ°Đē ŅŅ‚ĐžĐ¸Ņ‚ Đ´ĐĩĐģĐ°Ņ‚ŅŒ в **йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: -ĐĸаĐēОК ĐŋĐžĐ´Ņ…ĐžĐ´ ŅĐŗĐžĐ´Đ¸Ņ‚ŅŅ Đ´ĐģŅ **йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đ° ҁĐģŅƒŅ‡Đ°Đĩв**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: +* ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии **Kubernetes** иĐģи ĐŋĐžŅ…ĐžĐļĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ +* ĐŸŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ ĐŊа **Raspberry Pi** +* ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛Đ¸ŅĐ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš СаĐŋ҃ҁĐēаĐĩŅ‚ Đ´ĐģŅ Đ˛Đ°Ņ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° и Ņ‚.Đŋ. -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ҁ **Kubernetes** иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ -* ЗаĐŋ҃ҁĐē в **Raspberry Pi** -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ в ОйĐģĐ°Ņ‡ĐŊҋ҅ ҁĐĩŅ€Đ˛Đ¸ŅĐ°Ņ…, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Ņ… ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ Đ´ĐģŅ Đ˛Đ°Ņ и Ņ‚.Đŋ. +### Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŋаĐēĐĩŅ‚ĐžĐ˛ { #package-requirements } -### ĐŖŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ +ĐžĐąŅ‹Ņ‡ĐŊĐž **ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸** Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐžĐŋĐ¸ŅĐ°ĐŊŅ‹ в ĐēаĐēĐžĐŧ-Ņ‚Đž Ņ„Đ°ĐšĐģĐĩ. -ĐžĐąŅ‹Ņ‡ĐŊĐž Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹ **Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи**, ҁĐŋĐ¸ŅĐžĐē ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ в ĐžŅ‚Đ´ĐĩĐģҌĐŊĐžĐŧ Ņ„Đ°ĐšĐģĐĩ. +КоĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš Ņ„ĐžŅ€ĐŧĐ°Ņ‚ ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ в ĐžŅĐŊОвĐŊĐžĐŧ ĐžŅ‚ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ Đ˛Ņ‹ **ŅƒŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚Đĩ** ŅŅ‚Đ¸ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. -На ĐŊаСваĐŊиĐĩ и ŅĐžĐ´ĐĩŅ€ĐļаĐŊиĐĩ Ņ‚Đ°ĐēĐžĐŗĐž Ņ„Đ°ĐšĐģа вĐģĐ¸ŅĐĩŅ‚ Đ˛Ņ‹ĐąŅ€Đ°ĐŊĐŊŅ‹Đš ВаĐŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ **ŅƒŅŅ‚Đ°ĐŊОвĐēи** ŅŅ‚Đ¸Ņ… йийĐģĐ¸ĐžŅ‚ĐĩĐē (ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš). +Đ§Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Ņ„Đ°ĐšĐģ `requirements.txt` ҁ иĐŧĐĩĐŊаĐŧи ĐŋаĐēĐĩŅ‚ĐžĐ˛ и Đ¸Ņ… вĐĩŅ€ŅĐ¸ŅĐŧи ĐŋĐž ОдĐŊĐžĐŧ҃ ĐŊа ŅŅ‚Ņ€ĐžĐē҃. -Đ§Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚ĐžĐš Ņ„Đ°ĐšĐģ `requirements.txt` ҁ ĐŋĐžŅŅ‚Ņ€ĐžŅ‡ĐŊŅ‹Đŧ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊиĐĩĐŧ йийĐģĐ¸ĐžŅ‚ĐĩĐē и Đ¸Ņ… вĐĩŅ€ŅĐ¸Đš. +Đ Đ°ĐˇŅƒĐŧĐĩĐĩŅ‚ŅŅ, Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋŅ€Đ¸Đ´ĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒŅŅ Ņ‚ĐĩŅ… ĐļĐĩ идĐĩĐš, Ņ‡Ņ‚Đž ĐžĐŋĐ¸ŅĐ°ĐŊŅ‹ СдĐĩҁҌ: [О вĐĩŅ€ŅĐ¸ŅŅ… FastAPI](versions.md){.internal-link target=_blank}, Ņ‡Ņ‚ĐžĐąŅ‹ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ диаĐŋаСОĐŊŅ‹ вĐĩŅ€ŅĐ¸Đš. -ĐŸŅ€Đ¸ ŅŅ‚ĐžĐŧ Đ’Ņ‹, Đ´ĐģŅ Đ˛Ņ‹ĐąĐžŅ€Đ° вĐĩŅ€ŅĐ¸Đš, ĐąŅƒĐ´ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đĩ ĐļĐĩ идĐĩи, Ņ‡Ņ‚Đž ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚Ņ‹ ĐŊа ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đĩ [О вĐĩŅ€ŅĐ¸ŅŅ… FastAPI](versions.md){.internal-link target=_blank}. - -Đ’Đ°Ņˆ Ņ„Đ°ĐšĐģ `requirements.txt` ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ ĐēаĐē-Ņ‚Đž Ņ‚Đ°Đē: +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Đ°Ņˆ `requirements.txt` ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: ``` -fastapi>=0.68.0,<0.69.0 -pydantic>=1.8.0,<2.0.0 -uvicorn>=0.15.0,<0.16.0 +fastapi[standard]>=0.113.0,<0.114.0 +pydantic>=2.7.0,<3.0.0 ``` -ĐŖŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŋŅ€ĐžŅ‰Đĩ Đ˛ŅĐĩĐŗĐž ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ `pip`: +И ĐžĐąŅ‹Ņ‡ĐŊĐž Đ˛Ņ‹ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ ŅŅ‚Đ¸ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐēĐžĐŧаĐŊдОК `pip`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€:
```console $ pip install -r requirements.txt ---> 100% -Successfully installed fastapi pydantic uvicorn +Successfully installed fastapi pydantic ```
/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‚ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи. - -В ŅŅ‚ĐžĐŧ ĐļĐĩ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ, ĐŊĐž ĐŋОСĐļĐĩ, Ņ ĐŋĐžĐēаĐļ҃ ваĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Poetry. 👇 +ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‚ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņ‹ и иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Đ´ĐģŅ ĐžĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ и ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. /// -### ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** +### ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐēОд **FastAPI** { #create-the-fastapi-code } * ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `app` и ĐŋĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ в ĐŊĐĩŅ‘. * ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ ĐŋŅƒŅŅ‚ĐžĐš Ņ„Đ°ĐšĐģ `__init__.py`. -* ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `main.py` и СаĐŋĐžĐģĐŊĐ¸Ņ‚Đĩ ĐĩĐŗĐž: +* ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `main.py` ŅĐž ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ŅĐžĐ´ĐĩŅ€ĐļиĐŧŅ‹Đŧ: ```Python from typing import Union @@ -167,77 +162,109 @@ def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} ``` -### Dockerfile +### Dockerfile { #dockerfile } -В ŅŅ‚ĐžĐš ĐļĐĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `Dockerfile` и СаĐŋĐžĐģĐŊĐ¸Ņ‚Đĩ ĐĩĐŗĐž: +ĐĸĐĩĐŋĐĩŅ€ŅŒ в Ņ‚ĐžĐš ĐļĐĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ ĐŋŅ€ĐžĐĩĐēŅ‚Đ° ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `Dockerfile`: ```{ .dockerfile .annotate } -# (1) +# (1)! FROM python:3.9 -# (2) +# (2)! WORKDIR /code -# (3) +# (3)! COPY ./requirements.txt /code/requirements.txt -# (4) +# (4)! RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt -# (5) +# (5)! COPY ./app /code/app -# (6) -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] +# (6)! +CMD ["fastapi", "run", "app/main.py", "--port", "80"] ``` -1. ĐĐ°Ņ‡ĐŊĐ¸Ņ‚Đĩ ҁ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŗĐž ĐžĐąŅ€Đ°ĐˇĐ° Python, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ ĐžŅĐŊОвОК Đ´ĐģŅ ĐžĐąŅ€Đ°ĐˇĐ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. +1. ĐĐ°Ņ‡Đ¸ĐŊаĐĩĐŧ ҁ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŗĐž ĐąĐ°ĐˇĐžĐ˛ĐžĐŗĐž ĐžĐąŅ€Đ°ĐˇĐ° Python. -2. ĐŖĐēаĐļĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž в даĐģҌĐŊĐĩĐšŅˆĐĩĐŧ ĐēĐžĐŧаĐŊĐ´Ņ‹ СаĐŋ҃ҁĐēаĐĩĐŧŅ‹Đĩ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ, ĐąŅƒĐ´ŅƒŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒŅŅ в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `/code`. +2. ĐŖŅŅ‚Đ°ĐŊавĐģиваĐĩĐŧ Ņ‚ĐĩĐēŅƒŅ‰ŅƒŅŽ Ņ€Đ°ĐąĐžŅ‡ŅƒŅŽ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ в `/code`. - ИĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Ņ ŅĐžĐˇĐ´Đ°ŅŅ‚ ŅŅ‚Ņƒ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° и ĐŧŅ‹ ĐŋĐžĐŧĐĩŅŅ‚Đ¸Đŧ в ĐŊĐĩŅ‘ Ņ„Đ°ĐšĐģ `requirements.txt` и Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `app`. + ЗдĐĩҁҌ ĐŧŅ‹ Ņ€Đ°ĐˇĐŧĐĩŅŅ‚Đ¸Đŧ Ņ„Đ°ĐšĐģ `requirements.txt` и Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `app`. -3. ĐĄĐēĐžĐŋĐ¸Ņ€ŅƒĐĩŅ‚Đĩ Ņ„Đ°ĐšĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи иС Ņ‚ĐĩĐēŅƒŅ‰ĐĩĐš Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ в `/code`. +3. КоĐŋĐ¸Ņ€ŅƒĐĩĐŧ Ņ„Đ°ĐšĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `/code`. - ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ **Ņ‚ĐžĐģҌĐēĐž** Ņ„Đ°ĐšĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи. + ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ **Ņ‚ĐžĐģҌĐēĐž** Ņ„Đ°ĐšĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи, ĐŊĐĩ ĐžŅŅ‚Đ°ĐģҌĐŊОК ĐēОд. - Đ­Ņ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ **иСĐŧĐĩĐŊŅĐĩŅ‚ŅŅ дОвОĐģҌĐŊĐž Ņ€ĐĩĐ´ĐēĐž**, Docker Đ¸Ņ‰ĐĩŅ‚ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ĐŋŅ€Đ¸ ĐŋĐžŅŅ‚Ņ€ĐžĐšĐēĐĩ ĐžĐąŅ€Đ°ĐˇĐ° и ĐĩҁĐģи ĐŊĐĩ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚, Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ **ĐēŅŅˆ**, в ĐēĐžŅ‚ĐžŅ€ĐžĐŧ Ņ…Ņ€Đ°ĐŊŅŅ‚ŅŅ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Đĩ вĐĩŅ€ŅĐ¸Đ¸ ŅĐąĐžŅ€Đēи ĐžĐąŅ€Đ°ĐˇĐ°. + ĐĸаĐē ĐēаĐē ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ **ĐŧĐĩĐŊŅĐĩŅ‚ŅŅ ĐŊĐĩŅ‡Đ°ŅŅ‚Đž**, Docker ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ ŅŅ‚Đž и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ **ĐēŅŅˆ** ĐŊа ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ, Ņ‡Ņ‚Đž ĐŋОСвОĐģĐ¸Ņ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ и ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŧ ŅˆĐ°ĐŗĐĩ. -4. ĐŖŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊŅ‹Đĩ в Ņ„Đ°ĐšĐģĐĩ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи. +4. ĐŖŅŅ‚Đ°ĐŊавĐģиваĐĩĐŧ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ иС Ņ„Đ°ĐšĐģа ҁ ҂ҀĐĩйОваĐŊĐ¸ŅĐŧи. - ОĐŋŅ†Đ¸Ņ `--no-cache-dir` ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ `pip` ĐŊĐĩ ŅĐžŅ…Ņ€Đ°ĐŊŅŅ‚ŅŒ ĐˇĐ°ĐŗŅ€ŅƒĐļаĐĩĐŧŅ‹Đĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи ĐŊа ĐģĐžĐēаĐģҌĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ Đ´ĐģŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ¸Ņ… в ҁĐģŅƒŅ‡Đ°Đĩ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊОК ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи. В ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ, в ҁĐģŅƒŅ‡Đ°Đĩ ĐŋĐĩŅ€ĐĩŅĐąĐžŅ€Đēи ŅŅ‚ĐžĐŗĐž ŅˆĐ°ĐŗĐ°, ĐžĐŊи Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ŅƒŅ‚ ŅƒĐ´Đ°ĐģĐĩĐŊŅ‹. + ОĐŋŅ†Đ¸Ņ `--no-cache-dir` ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ `pip` ĐŊĐĩ ŅĐžŅ…Ņ€Đ°ĐŊŅŅ‚ŅŒ ĐˇĐ°ĐŗŅ€ŅƒĐļĐĩĐŊĐŊŅ‹Đĩ ĐŋаĐēĐĩ҂ҋ ĐģĐžĐēаĐģҌĐŊĐž, Ņ‚.Đē. ŅŅ‚Đž ĐŊ҃ĐļĐŊĐž Ņ‚ĐžĐģҌĐēĐž ĐĩҁĐģи `pip` ĐąŅƒĐ´ĐĩŅ‚ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒŅŅ ҁĐŊОва Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи Ņ‚ĐĩŅ… ĐļĐĩ ĐŋаĐēĐĩŅ‚ĐžĐ˛, а ĐŋŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊĐĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ. /// note | ЗаĐŧĐĩŅ‚Đēа - ОĐŋŅ†Đ¸Ņ `--no-cache-dir` ĐŊ҃ĐļĐŊа Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ `pip`, ĐžĐŊа ĐŊиĐēаĐē ĐŊĐĩ вĐģĐ¸ŅĐĩŅ‚ ĐŊа Docker иĐģи ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ. + `--no-cache-dir` ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Ņ‚ĐžĐģҌĐēĐž Đē `pip` и ĐŊĐĩ иĐŧĐĩĐĩŅ‚ ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸Ņ Đē Docker иĐģи ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ. /// - ОĐŋŅ†Đ¸Ņ `--upgrade` ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ `pip` ОйĐŊĐžĐ˛Đ¸Ņ‚ŅŒ йийĐģĐ¸ĐžŅ‚ĐĩĐēи, ĐĩĐŧĐģи ĐžĐŊи ҃ĐļĐĩ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊŅ‹. + ОĐŋŅ†Đ¸Ņ `--upgrade` ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ `pip` ОйĐŊОвĐģŅŅ‚ŅŒ ĐŋаĐēĐĩ҂ҋ, ĐĩҁĐģи ĐžĐŊи ҃ĐļĐĩ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊŅ‹. - КаĐē и в ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐŧ ŅˆĐ°ĐŗĐĩ ҁ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ„Đ°ĐšĐģа, ŅŅ‚ĐžŅ‚ ŅˆĐ°Đŗ Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐēŅŅˆ Docker** в ҁĐģŅƒŅ‡Đ°Đĩ ĐžŅ‚ŅŅƒŅ‚ŅŅ‚Đ˛Đ¸Ņ иСĐŧĐĩĐŊĐĩĐŊиК. + ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Đš ŅˆĐ°Đŗ ҁ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ„Đ°ĐšĐģа ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐŊ **ĐēŅŅˆĐĩĐŧ Docker**, ŅŅ‚ĐžŅ‚ ŅˆĐ°Đŗ Ņ‚Đ°ĐēĐļĐĩ **Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐēŅŅˆ Docker**, ĐēĐžĐŗĐ´Đ° ŅŅ‚Đž вОСĐŧĐžĐļĐŊĐž. - Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐēŅŅˆĐ°, ĐžŅĐžĐąĐĩĐŊĐŊĐž ĐŊа ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ, ĐŋОСвОĐģĐ¸Ņ‚ ваĐŧ **ŅŅĐēĐžĐŊĐžĐŧĐ¸Ņ‚ŅŒ** ĐēŅƒŅ‡Ņƒ Đ˛Ņ€ĐĩĐŧĐĩĐŊи ĐŋŅ€Đ¸ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊОК ŅĐąĐžŅ€ĐēĐĩ ĐžĐąŅ€Đ°ĐˇĐ°, Ņ‚Đ°Đē ĐēаĐē ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐąŅƒĐ´ŅƒŅ‚ ŅĐžŅ…Ņ€Đ°ĐŊĐĩĐŊŅ‹ в ĐēĐĩ҈Đĩ, а ĐŊĐĩ **ĐˇĐ°ĐŗŅ€ŅƒĐļĐ°Ņ‚ŅŒŅŅ и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒŅŅ ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ**. + Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐēŅŅˆĐ° ĐŊа ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ **ŅŅĐēĐžĐŊĐžĐŧĐ¸Ņ‚** ваĐŧ ĐŧĐŊĐžĐŗĐž **Đ˛Ņ€ĐĩĐŧĐĩĐŊи** ĐŋŅ€Đ¸ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊҋ҅ ŅĐąĐžŅ€ĐēĐ°Ņ… ĐžĐąŅ€Đ°ĐˇĐ° вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи, вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž Ņ‡Ņ‚ĐžĐąŅ‹ **ĐˇĐ°ĐŗŅ€ŅƒĐļĐ°Ņ‚ŅŒ и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ** Đ˛ŅĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ **ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ**. -5. ĐĄĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `./app` вĐŊŅƒŅ‚Ņ€ŅŒ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `/code` (в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ). +5. КоĐŋĐ¸Ņ€ŅƒĐĩĐŧ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `./app` вĐŊŅƒŅ‚Ņ€ŅŒ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `/code`. - ĐĸаĐē ĐēаĐē в ŅŅ‚ĐžĐš Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ Ņ€Đ°ŅĐŋĐžĐģĐžĐļĐĩĐŊ ĐēОд, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš **Ņ‡Đ°ŅŅ‚Đž иСĐŧĐĩĐŊŅĐĩŅ‚ŅŅ**, Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ **ĐēŅŅˆĐ°** ĐŊа ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŊаиĐŧĐĩĐŊĐĩĐĩ ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊĐž, а СĐŊĐ°Ņ‡Đ¸Ņ‚ ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ŅˆĐ°Đŗ **ĐąĐģиĐļĐĩ Đē ĐēĐžĐŊŅ†Ņƒ** `Dockerfile`, Đ´Đ°ĐąŅ‹ ĐŊĐĩ Ņ‚ĐĩŅ€ŅŅ‚ŅŒ Đ˛Ņ‹ĐŗĐžĐ´Ņƒ ĐžŅ‚ ĐžĐŋŅ‚Đ¸ĐŧĐ¸ĐˇĐ°Ņ†Đ¸Đ¸ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… ŅˆĐ°ĐŗĐžĐ˛. + ĐĸаĐē ĐēаĐē СдĐĩҁҌ вĐĩҁҌ ĐēОд, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš **ĐŧĐĩĐŊŅĐĩŅ‚ŅŅ Ņ‡Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž**, ĐēŅŅˆ Docker **Đ˛Ņ€ŅĐ´ Đģи** ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ŅˆĐ°Đŗa иĐģи **ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ŅˆĐ°ĐŗĐžĐ˛**. -6. ĐŖĐēаĐļĐ¸Ņ‚Đĩ **ĐēĐžĐŧаĐŊĐ´Ņƒ**, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰ŅƒŅŽ ҁĐĩŅ€Đ˛ĐĩŅ€ `uvicorn`. + ĐŸĐžŅŅ‚ĐžĐŧ҃ ваĐļĐŊĐž Ņ€Đ°ĐˇĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ŅˆĐ°Đŗ **ĐąĐģиĐļĐĩ Đē ĐēĐžĐŊŅ†Ņƒ** `Dockerfile`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŋŅ‚Đ¸ĐŧĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ˛Ņ€ĐĩĐŧŅ ŅĐąĐžŅ€Đēи ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. - `CMD` ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ҁĐŋĐ¸ŅĐžĐē ŅŅ‚Ņ€ĐžĐē, Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ СаĐŋŅŅ‚Ņ‹Đŧи, ĐŊĐž ĐŋŅ€Đ¸ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊии ĐžĐąŅŠĐĩдиĐŊĐ¸Ņ‚ Đ¸Ņ… ҇ĐĩŅ€ĐĩС ĐŋŅ€ĐžĐąĐĩĐģ, ŅĐžĐąŅ€Đ°Đ˛ иС ĐŊĐ¸Ņ… ОдĐŊ҃ ĐēĐžĐŧаĐŊĐ´Ņƒ, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ˛Ņ‹ ĐŧĐžĐŗĐģи ĐąŅ‹ ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ в Ņ‚ĐĩŅ€ĐŧиĐŊаĐģĐĩ. +6. ĐŖĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧ **ĐēĐžĐŧаĐŊĐ´Ņƒ** Đ´ĐģŅ СаĐŋ҃ҁĐēа `fastapi run`, ĐŋОд ĐēаĐŋĐžŅ‚ĐžĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Uvicorn. - Đ­Ņ‚Đ° ĐēĐžĐŧаĐŊда ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊа в **Ņ‚ĐĩĐēŅƒŅ‰ĐĩĐš Ņ€Đ°ĐąĐžŅ‡ĐĩĐš Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸**, а иĐŧĐĩĐŊĐŊĐž в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `/code`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ҃ĐēаСаĐŊа в ĐēĐžĐŧаĐŊĐ´Đĩ `WORKDIR /code`. + `CMD` ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ҁĐŋĐ¸ŅĐžĐē ŅŅ‚Ņ€ĐžĐē, ĐēаĐļĐ´Đ°Ņ иС ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… — ŅŅ‚Đž Ņ‚Đž, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐąŅ‹ ввĐĩĐģи в ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēĐĩ, Ņ€Đ°ĐˇĐ´ĐĩĐģŅŅ ĐŋŅ€ĐžĐąĐĩĐģаĐŧи. - ĐĸаĐē ĐēаĐē ĐēĐžĐŧаĐŊда Đ˛Ņ‹ĐŋĐžĐģĐŊŅĐĩŅ‚ŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `/code`, в ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ ĐŧŅ‹ ĐŋĐžĐŧĐĩŅŅ‚Đ¸Đģи ĐŋаĐŋĐē҃ `./app` ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ, Ņ‚Đž **Uvicorn** ҁĐŧĐžĐļĐĩŅ‚ ĐŊĐ°ĐšŅ‚Đ¸ и **иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ** ĐžĐąŅŠĐĩĐēŅ‚ `app` иС Ņ„Đ°ĐšĐģа `app.main`. + Đ­Ņ‚Đ° ĐēĐžĐŧаĐŊда ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊа иС **Ņ‚ĐĩĐēŅƒŅ‰ĐĩĐš Ņ€Đ°ĐąĐžŅ‡ĐĩĐš Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸**, Ņ‚ĐžĐš ŅĐ°ĐŧОК `/code`, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ˛Ņ‹ СадаĐģи Đ˛Ņ‹ŅˆĐĩ `WORKDIR /code`. /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -Đ•ŅĐģи Ņ‚ĐēĐŊґ҂Đĩ ĐŊа ĐēŅ€ŅƒĐļĐžĐē ҁ ĐŋĐģŅŽŅĐžĐŧ, Ņ‚Đž ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐŋĐžŅŅĐŊĐĩĐŊĐ¸Ņ. 👆 +ĐŸĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ´ĐĩĐģаĐĩŅ‚ ĐēаĐļĐ´Đ°Ņ ŅŅ‚Ņ€ĐžĐēа, ĐēĐģиĐēĐŊŅƒĐ˛ ĐŋĐž ĐŊĐžĐŧĐĩŅ€Ņƒ Ņ€ŅĐ´ĐžĐŧ ŅĐž ŅŅ‚Ņ€ĐžĐēОК. 👆 /// -На даĐŊĐŊĐžĐŧ ŅŅ‚Đ°ĐŋĐĩ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° ĐŋŅ€ĐžĐĩĐēŅ‚Đ° Đ´ĐžĐģĐļĐŊŅ‹ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ + +Đ’ŅĐĩĐŗĐ´Đ° Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ **exec-Ņ„ĐžŅ€Đŧ҃** иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Đ¸ `CMD`, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž ĐŊиĐļĐĩ. + +/// + +#### Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `CMD` — exec-Ņ„ĐžŅ€Đŧа { #use-cmd-exec-form } + +ИĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸ŅŽ Docker `CMD` ĐŧĐžĐļĐŊĐž ĐŋĐ¸ŅĐ°Ņ‚ŅŒ в Đ´Đ˛ŅƒŅ… Ņ„ĐžŅ€ĐŧĐ°Ņ…: + +✅ **Exec**-Ņ„ĐžŅ€Đŧа: + +```Dockerfile +# ✅ ДĐĩĐģĐ°ĐšŅ‚Đĩ Ņ‚Đ°Đē +CMD ["fastapi", "run", "app/main.py", "--port", "80"] +``` + +â›”ī¸ **Shell**-Ņ„ĐžŅ€Đŧа: + +```Dockerfile +# â›”ī¸ НĐĩ Đ´ĐĩĐģĐ°ĐšŅ‚Đĩ Ņ‚Đ°Đē +CMD fastapi run app/main.py --port 80 +``` + +ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ **exec**-Ņ„ĐžŅ€Đŧ҃, Ņ‡Ņ‚ĐžĐąŅ‹ FastAPI ĐŧĐžĐŗ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž СавĐĩŅ€ŅˆĐ°Ņ‚ŅŒŅŅ и Ņ‡Ņ‚ĐžĐąŅ‹ ŅŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Đģи [ŅĐžĐąŅ‹Ņ‚Đ¸Ņ lifespan](../advanced/events.md){.internal-link target=_blank}. + +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Ой ŅŅ‚ĐžĐŧ Ņ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Docker Đž shell- и exec-Ņ„ĐžŅ€ĐŧĐ°Ņ…. + +Đ­Ņ‚Đž ĐžŅĐžĐąĐĩĐŊĐŊĐž СаĐŧĐĩŅ‚ĐŊĐž ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии `docker compose`. ĐĄĐŧ. Ņ€Đ°ĐˇĐ´ĐĩĐģ FAQ Docker Compose ҁ Ņ‚ĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐŧи ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚ŅĐŧи: ĐŸĐžŅ‡ĐĩĐŧ҃ ĐŧОи ҁĐĩŅ€Đ˛Đ¸ŅŅ‹ ĐŋĐĩŅ€ĐĩŅĐžĐˇĐ´Đ°ŅŽŅ‚ŅŅ иĐģи ĐžŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ 10 ҁĐĩĐē҃ĐŊĐ´?. + +#### ĐĄŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đš { #directory-structure } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ҃ Đ˛Đ°Ņ Đ´ĐžĐģĐļĐŊа ĐąŅ‹Ņ‚ŅŒ Ņ‚Đ°ĐēĐ°Ņ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ°: ``` . @@ -248,53 +275,52 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] └── requirements.txt ``` -#### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° +#### За ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ TLS Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ { #behind-a-tls-termination-proxy } -Đ•ŅĐģи Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ Са ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS (йаĐģаĐŊŅĐ¸Ņ€ŅƒŅŽŅ‰ĐĩĐŗĐž ĐŊĐ°ĐŗŅ€ŅƒĐˇĐē҃), Ņ‚Đ°ĐēиĐŧ ĐēаĐē Nginx иĐģи Traefik, Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ ĐžĐŋŅ†Đ¸ŅŽ `--proxy-headers`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ҃ĐēаĐļĐĩŅ‚ Uvicorn, Ņ‡Ņ‚Đž ĐžĐŊ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐŋОСади ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° и ĐŧĐžĐļĐĩŅ‚ дОвĐĩŅ€ŅŅ‚ŅŒ ĐˇĐ°ĐŗĐžĐģОвĐēаĐŧ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đŧ иĐŧ. +Đ•ŅĐģи Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ Са ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS (йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи), Ņ‚Đ°ĐēиĐŧ ĐēаĐē Nginx иĐģи Traefik, Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ ĐžĐŋŅ†Đ¸ŅŽ `--proxy-headers`. Đ­Ņ‚Đž ŅĐžĐžĐąŅ‰Đ¸Ņ‚ Uvicorn (҇ĐĩŅ€ĐĩС FastAPI CLI), Ņ‡Ņ‚Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ Са HTTPS и ĐŧĐžĐļĐŊĐž дОвĐĩŅ€ŅŅ‚ŅŒ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đŧ ĐˇĐ°ĐŗĐžĐģОвĐēаĐŧ. ```Dockerfile -CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] +CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"] ``` -#### ĐšŅŅˆ Docker'а +#### ĐšŅŅˆ Docker { #docker-cache } -В ĐŊĐ°ŅˆĐĩĐŧ `Dockerfile` Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊа ĐŋĐžĐģĐĩСĐŊĐ°Ņ Ņ…Đ¸Ņ‚Ņ€ĐžŅŅ‚ŅŒ, ĐēĐžĐŗĐ´Đ° ҁĐŊĐ°Ņ‡Đ°Đģа ĐēĐžĐŋĐ¸Ņ€ŅƒĐĩŅ‚ŅŅ **Ņ‚ĐžĐģҌĐēĐž Ņ„Đ°ĐšĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи**, а ĐŊĐĩ Đ˛ŅŅ ĐŋаĐŋĐēа ҁ ĐēОдОĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. +В ŅŅ‚ĐžĐŧ `Dockerfile` ĐĩŅŅ‚ŅŒ ваĐļĐŊĐ°Ņ Ņ…Đ¸Ņ‚Ņ€ĐžŅŅ‚ŅŒ: ĐŧŅ‹ ҁĐŊĐ°Ņ‡Đ°Đģа ĐēĐžĐŋĐ¸Ņ€ŅƒĐĩĐŧ **Ņ‚ĐžĐģҌĐēĐž Ņ„Đ°ĐšĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи**, а ĐŊĐĩ вĐĩҁҌ ĐēОд. Đ’ĐžŅ‚ ĐˇĐ°Ņ‡ĐĩĐŧ. ```Dockerfile COPY ./requirements.txt /code/requirements.txt ``` -Docker и ĐŋОдОйĐŊŅ‹Đĩ ĐĩĐŧ҃ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ **ŅĐžĐˇĐ´Đ°ŅŽŅ‚** ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ **ĐŋĐžŅˆĐ°ĐŗĐžĐ˛Đž**, дОйавĐģŅŅ **ОдиĐŊ ҁĐģОК ĐŊад Đ´Ņ€ŅƒĐŗĐ¸Đŧ**, ĐŊĐ°Ņ‡Đ¸ĐŊĐ°Ņ ҁ ĐŋĐĩŅ€Đ˛ĐžĐš ŅŅ‚Ņ€ĐžĐēи `Dockerfile` и дОйавĐģŅŅ Ņ„Đ°ĐšĐģŅ‹, ŅĐžĐˇĐ´Đ°Đ˛Đ°ĐĩĐŧŅ‹Đĩ ĐŋŅ€Đ¸ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊии ĐēаĐļдОК иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Đ¸ иС `Dockerfile`. +Docker и ĐŋОдОйĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ **ŅŅ‚Ņ€ĐžŅŅ‚** ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ **иĐŊĐēŅ€ĐĩĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊĐž**, дОйавĐģŅŅ **ҁĐģОК Са ҁĐģĐžĐĩĐŧ**, ĐŊĐ°Ņ‡Đ¸ĐŊĐ°Ņ ҁ ĐŋĐĩŅ€Đ˛ĐžĐš ŅŅ‚Ņ€ĐžĐēи `Dockerfile` и дОйавĐģŅŅ ĐģŅŽĐąŅ‹Đĩ Ņ„Đ°ĐšĐģŅ‹, ŅĐžĐˇĐ´Đ°Đ˛Đ°ĐĩĐŧŅ‹Đĩ ĐēаĐļдОК иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸ĐĩĐš `Dockerfile`. -ĐŸŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐžĐąŅ€Đ°ĐˇĐ° Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ **вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиК ĐēŅŅˆ** и ĐĩҁĐģи в Ņ„Đ°ĐšĐģĐ°Ņ… ĐŊĐĩŅ‚ иСĐŧĐĩĐŊĐĩĐŊиК ҁ ĐŧĐžĐŧĐĩĐŊŅ‚Đ° ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐš ŅĐąĐžŅ€Đēи ĐžĐąŅ€Đ°ĐˇĐ°, Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ **ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ** Ņ€Đ°ĐŊĐĩĐĩ ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš ҁĐģОК ĐžĐąŅ€Đ°ĐˇĐ°, а ĐŊĐĩ ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐžĐĩ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Ņ„Đ°ĐšĐģОв и ŅĐžĐˇĐ´Đ°ĐŊиĐĩ ҁĐģĐžŅ ҁ ĐŊ҃ĐģŅ. -ЗаĐŧĐĩŅ‚ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đ°Đē ĐēаĐē ҁĐģОК ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŗĐž ŅˆĐ°ĐŗĐ° ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ ҁĐģĐžŅ ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐŗĐž, Ņ‚Đž иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ вĐŊĐĩҁґĐŊĐŊŅ‹Đĩ в ĐŋŅ€ĐžĐŧĐĩĐļŅƒŅ‚ĐžŅ‡ĐŊŅ‹Đš ҁĐģОК, Ņ‚Đ°ĐēĐļĐĩ ĐŋОвĐģĐ¸ŅŅŽŅ‚ ĐŊа ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ. +Docker и ĐŋОдОйĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Ņ‚Đ°ĐēĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ **вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиК ĐēŅŅˆ** ĐŋŅ€Đ¸ ŅĐąĐžŅ€ĐēĐĩ ĐžĐąŅ€Đ°ĐˇĐ°: ĐĩҁĐģи Ņ„Đ°ĐšĐģ ĐŊĐĩ иСĐŧĐĩĐŊиĐģŅŅ ҁ ĐŧĐžĐŧĐĩĐŊŅ‚Đ° ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐš ŅĐąĐžŅ€Đēи, ĐąŅƒĐ´ĐĩŅ‚ **ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ ҁĐģОК**, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš в ĐŋŅ€ĐžŅˆĐģŅ‹Đš Ņ€Đ°Đˇ, вĐŧĐĩŅŅ‚Đž ĐŋĐžĐ˛Ņ‚ĐžŅ€ĐŊĐžĐŗĐž ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ„Đ°ĐšĐģа и ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŊĐžĐ˛ĐžĐŗĐž ҁĐģĐžŅ ҁ ĐŊ҃ĐģŅ. -ИСйĐĩĐŗĐ°ĐŊиĐĩ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ„Đ°ĐšĐģОв ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚ ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸ŅŽ, ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐēŅŅˆĐ° ĐŊа ОдĐŊĐžĐŧ ŅˆĐ°ĐŗĐĩ, ĐŋОСвОĐģĐ¸Ņ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ и ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ŅˆĐ°ĐŗĐ°Ņ…**. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ ĐŋŅ€Đ¸ ŅƒŅŅ‚Đ°ĐŊОвĐēĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš: +ХаĐŧĐž ĐŋĐž ҁĐĩĐąĐĩ иСйĐĩĐŗĐ°ĐŊиĐĩ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Đ˛ŅĐĩŅ… Ņ„Đ°ĐšĐģОв ĐŊĐĩ Đ˛ŅĐĩĐŗĐ´Đ° Đ´Đ°Ņ‘Ņ‚ ĐŧĐŊĐžĐŗĐž, ĐŊĐž ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸ŅŽ ĐēŅŅˆĐ° ĐŊа ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ Docker ҁĐŧĐžĐļĐĩŅ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ и ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŧ ŅˆĐ°ĐŗĐĩ**. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŊа ŅˆĐ°ĐŗĐĩ ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš: ```Dockerfile RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt ``` -ФаКĐģ ŅĐž ҁĐŋĐ¸ŅĐēĐžĐŧ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš **иСĐŧĐĩĐŊŅĐĩŅ‚ŅŅ дОвОĐģҌĐŊĐž Ņ€ĐĩĐ´ĐēĐž**. ĐĸаĐē Ņ‡Ņ‚Đž Đ˛Ņ‹ĐŋĐžĐģĐŊив ĐēĐžĐŧаĐŊĐ´Ņƒ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ‚ĐžĐģҌĐēĐž ŅŅ‚ĐžĐŗĐž Ņ„Đ°ĐšĐģа, Docker ҁĐŧĐžĐļĐĩŅ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ** ĐŊа ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ. +ФаКĐģ ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи **ĐŧĐĩĐŊŅĐĩŅ‚ŅŅ ĐŊĐĩŅ‡Đ°ŅŅ‚Đž**. ĐŸĐžŅŅ‚ĐžĐŧ҃, ĐēĐžĐŋĐ¸Ņ€ŅƒŅ Ņ‚ĐžĐģҌĐēĐž ĐĩĐŗĐž, Docker ҁĐŧĐžĐļĐĩŅ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ** Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ŅˆĐ°ĐŗĐ°. -А ĐˇĐ°Ņ‚ĐĩĐŧ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ и ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŧ ŅˆĐ°ĐŗĐĩ**, ĐˇĐ°ĐŗŅ€ŅƒĐļĐ°ŅŽŅ‰ĐĩĐŧ и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°ŅŽŅ‰ĐĩĐŧ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. И Đ˛ĐžŅ‚ Ņ‚ŅƒŅ‚-Ņ‚Đž ĐŧŅ‹ и **ŅŅĐēĐžĐŊĐžĐŧиĐŧ ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи**. ✨ ...а ĐŊĐĩ ĐąŅƒĐ´ĐĩĐŧ Ņ‚ĐžĐŧĐ¸Ņ‚ŅŒŅŅ в Ņ‚ŅĐŗĐžŅŅ‚ĐŊĐžĐŧ ĐžĐļидаĐŊии. đŸ˜Ē😆 +А ĐˇĐ°Ņ‚ĐĩĐŧ Docker ҁĐŧĐžĐļĐĩŅ‚ **Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ и ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŧ ŅˆĐ°ĐŗĐĩ**, ĐŗĐ´Đĩ ҁĐēĐ°Ņ‡Đ¸Đ˛Đ°ŅŽŅ‚ŅŅ и ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸. ЗдĐĩҁҌ ĐŧŅ‹ ĐēаĐē Ņ€Đ°Đˇ **ŅĐēĐžĐŊĐžĐŧиĐŧ ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи**. ✨ ...и ĐŊĐĩ ҁĐēŅƒŅ‡Đ°ĐĩĐŧ в ĐžĐļидаĐŊии. đŸ˜Ē😆 -ДĐģŅ ĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи и ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ йийĐģĐ¸ĐžŅ‚ĐĩĐē **ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧиĐŊŅƒŅ‚**, ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ **ĐēŅŅˆĐ°** СаĐŊиĐŧаĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž **ҁĐĩĐē҃ĐŊĐ´** ĐŧаĐēŅĐ¸Đŧ҃Đŧ. +ĐĄĐēĐ°Ņ‡Đ¸Đ˛Đ°ĐŊиĐĩ и ŅƒŅŅ‚Đ°ĐŊОвĐēа ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš **ĐŧĐžĐļĐĩŅ‚ СаĐŊŅŅ‚ŅŒ ĐŧиĐŊŅƒŅ‚Ņ‹**, ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ **ĐēŅŅˆĐ°** — **ҁĐĩĐē҃ĐŊĐ´Ņ‹**. -И Ņ‚Đ°Đē ĐēаĐē вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ Ņ‡Đ°ŅŅ‚Đž ĐŋĐĩŅ€ĐĩŅĐžĐąĐ¸Ņ€Đ°Ņ‚ŅŒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Ņ€Đ°ĐąĐžŅ‚ĐžŅĐŋĐžŅĐžĐąĐŊĐžŅŅ‚Đ¸ вĐŊĐĩҁґĐŊĐŊҋ҅ иСĐŧĐĩĐŊĐĩĐŊиК, Ņ‚Đž ŅŅĐēĐžĐŊĐžĐŧĐģĐĩĐŊĐŊŅ‹Đĩ ĐŧиĐŊŅƒŅ‚Ņ‹ ҁĐģĐžĐļĐ°Ņ‚ŅŅ в Ņ‡Đ°ŅŅ‹, а Ņ‚Đž и Đ´ĐŊи. +ĐŸĐžŅĐēĐžĐģҌĐē҃ вО Đ˛Ņ€ĐĩĐŧŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩŅĐžĐąĐ¸Ņ€Đ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Đˇ ҁĐŊОва и ҁĐŊОва, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ в ĐēОдĐĩ, ҁ҃ĐŧĐŧĐ°Ņ€ĐŊĐž ŅŅ‚Đž ŅŅĐēĐžĐŊĐžĐŧĐ¸Ņ‚ ĐŊĐĩĐŧаĐģĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи. -ĐĸаĐē ĐēаĐē ĐŋаĐŋĐēа ҁ ĐēОдОĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **иСĐŧĐĩĐŊŅĐĩŅ‚ŅŅ Ņ‡Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž**, Ņ‚Đž ĐŧŅ‹ Ņ€Đ°ŅĐŋĐžĐģĐžĐļиĐģи ĐĩŅ‘ в ĐēĐžĐŊ҆Đĩ `Dockerfile`, вĐĩĐ´ŅŒ ĐŋĐžŅĐģĐĩ вĐŊĐĩҁґĐŊĐŊҋ҅ в ĐēОд иСĐŧĐĩĐŊĐĩĐŊиК ĐēŅŅˆ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊ ĐŊа ŅŅ‚ĐžĐŧ и ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ŅˆĐ°ĐŗĐ°Ņ…. +Đ—Đ°Ņ‚ĐĩĐŧ, ĐąĐģиĐļĐĩ Đē ĐēĐžĐŊŅ†Ņƒ `Dockerfile`, ĐŧŅ‹ ĐēĐžĐŋĐ¸Ņ€ŅƒĐĩĐŧ вĐĩҁҌ ĐēОд. ĐĸаĐē ĐēаĐē ĐžĐŊ **ĐŧĐĩĐŊŅĐĩŅ‚ŅŅ Ņ‡Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž**, ĐŧŅ‹ ŅŅ‚Đ°Đ˛Đ¸Đŧ ŅŅ‚ĐžŅ‚ ŅˆĐ°Đŗ в ĐēĐžĐŊĐĩ҆, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐŋĐžŅ‡Ņ‚Đ¸ Đ˛ŅĐĩĐŗĐ´Đ° Đ˛ŅŅ‘, Ņ‡Ņ‚Đž ĐŋĐžŅĐģĐĩ ĐŊĐĩĐŗĐž, ҃ĐļĐĩ ĐŊĐĩ ҁĐŧĐžĐļĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēŅŅˆ. ```Dockerfile COPY ./app /code/app ``` -### ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ +### ĐĄĐžĐąŅ€Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ { #build-the-docker-image } -ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° Đ˛ŅĐĩ Ņ„Đ°ĐšĐģŅ‹ ĐŊа ŅĐ˛ĐžĐ¸Ņ… ĐŧĐĩŅŅ‚Đ°Ņ…, Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ŅĐžĐˇĐ´Đ°Đ´Đ¸Đŧ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. +ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° Đ˛ŅĐĩ Ņ„Đ°ĐšĐģŅ‹ ĐŊа ĐŧĐĩҁ҂Đĩ, ŅĐžĐąĐĩҀґĐŧ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. -* ПĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ ĐŋŅ€ĐžĐĩĐēŅ‚Đ° (в Ņ‚Ņƒ, ĐŗĐ´Đĩ Ņ€Đ°ŅĐŋĐžĐģĐžĐļĐĩĐŊŅ‹ `Dockerfile` и ĐŋаĐŋĐēа `app` ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ). -* ХОСдаК ĐžĐąŅ€Đ°Đˇ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI: +* ПĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ ĐŋŅ€ĐžĐĩĐēŅ‚Đ° (ĐŗĐ´Đĩ Đ˛Đ°Ņˆ `Dockerfile` и Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Ņ `app`). +* ХОйĐĩŅ€Đ¸Ņ‚Đĩ ĐžĐąŅ€Đ°Đˇ FastAPI:
@@ -308,15 +334,15 @@ $ docker build -t myimage . /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž в ĐēĐžĐŊ҆Đĩ ĐŊаĐŋĐ¸ŅĐ°ĐŊа Ņ‚ĐžŅ‡Đēа - `.`, ŅŅ‚Đž Ņ‚Đž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ Ņ‡Ņ‚Đž и `./`, Ņ‚ĐĩĐŧ ŅĐ°ĐŧŅ‹Đŧ ĐŧŅ‹ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧ Docker Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ, иС ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŊ҃ĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ ŅĐąĐžŅ€Đē҃ ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ ĐŊа Ņ‚ĐžŅ‡Đē҃ `.` в ĐēĐžĐŊ҆Đĩ — ŅŅ‚Đž Ņ‚Đž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ, Ņ‡Ņ‚Đž `./`. ĐĸаĐē ĐŧŅ‹ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧ Docker, иС ĐēаĐēОК Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ ŅĐžĐąĐ¸Ņ€Đ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. -В даĐŊĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž Ņ‚Đ° ĐļĐĩ ŅĐ°ĐŧĐ°Ņ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Ņ (`.`). +В даĐŊĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž Ņ‚ĐĩĐēŅƒŅ‰Đ°Ņ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Ņ (`.`). /// -### ЗаĐŋ҃ҁĐē Docker-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° +### ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Docker-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ { #start-the-docker-container } -* ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€, ĐžŅĐŊОваĐŊĐŊŅ‹Đš ĐŊа Đ˛Đ°ŅˆĐĩĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ: +* ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐŊа ĐžŅĐŊОвĐĩ Đ˛Đ°ŅˆĐĩĐŗĐž ĐžĐąŅ€Đ°ĐˇĐ°:
@@ -326,35 +352,35 @@ $ docker run -d --name mycontainer -p 80:80 myimage
-## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа +## ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа { #check-it } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž Đ’Đ°Ņˆ Docker-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐŋĐĩŅ€ĐĩĐšĐ´Ņ ĐŋĐž ҁҁҋĐģĐēĐĩ: http://192.168.99.100/items/5?q=somequery иĐģи http://127.0.0.1/items/5?q=somequery (иĐģи ĐŋĐžŅ…ĐžĐļĐĩĐš, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đ’Đ°Ņˆ Docker-Ņ…ĐžŅŅ‚). +ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ Ņ€Đ°ĐąĐžŅ‚Ņƒ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ Đ˛Đ°ŅˆĐĩĐŗĐž Docker-Ņ…ĐžŅŅ‚Đ°, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: http://192.168.99.100/items/5?q=somequery иĐģи http://127.0.0.1/items/5?q=somequery (иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đš URL Đ˛Đ°ŅˆĐĩĐŗĐž Docker-Ņ…ĐžŅŅ‚Đ°). -ĐĸаĐŧ Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ: +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Ņ‡Ņ‚Đž-Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ: ```JSON {"item_id": 5, "q": "somequery"} ``` -## ИĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API +## ИĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API { #interactive-api-docs } -ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŋĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ ĐŋĐž ҁҁҋĐģĐēĐĩ http://192.168.99.100/docs иĐģи http://127.0.0.1/docs (иĐģи ĐŋĐžŅ…ĐžĐļĐĩĐš, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đ’Đ°Ņˆ Docker-Ņ…ĐžŅŅ‚). +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐˇĐ°ĐšĐ´Đ¸Ņ‚Đĩ ĐŊа http://192.168.99.100/docs иĐģи http://127.0.0.1/docs (иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đš URL Đ˛Đ°ŅˆĐĩĐŗĐž Docker-Ņ…ĐžŅŅ‚Đ°). -ЗдĐĩҁҌ Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API (ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅƒŅŽ Swagger UI): +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API (ĐŊа йаСĐĩ Swagger UI): ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) -## АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API +## АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API { #alternative-api-docs } -ĐĸаĐēĐļĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ ĐŋĐž ҁҁҋĐģĐēĐĩ http://192.168.99.100/redoc or http://127.0.0.1/redoc (иĐģи ĐŋĐžŅ…ĐžĐļĐĩĐš, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đ’Đ°Ņˆ Docker-Ņ…ĐžŅŅ‚). +ĐĸаĐēĐļĐĩ ĐŧĐžĐļĐŊĐž ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ŅŒ http://192.168.99.100/redoc иĐģи http://127.0.0.1/redoc (иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đš URL Đ˛Đ°ŅˆĐĩĐŗĐž Docker-Ņ…ĐžŅŅ‚Đ°). -ЗдĐĩҁҌ Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅƒŅŽ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API (ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅƒŅŽ ReDoc): +Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊŅƒŅŽ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ (ĐŊа йаСĐĩ ReDoc): ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) -## ХОСдаĐŊиĐĩ Docker-ĐžĐąŅ€Đ°ĐˇĐ° ĐŊа ĐžŅĐŊОвĐĩ ОдĐŊĐžŅ„Đ°ĐšĐģĐžĐ˛ĐžĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI +## ĐĄĐžĐąŅ€Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ ОдĐŊĐžŅ„Đ°ĐšĐģĐžĐ˛ĐžĐŗĐž FastAPI { #build-a-docker-image-with-a-single-file-fastapi } -Đ•ŅĐģи Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI ĐŋĐžĐŧĐĩ҉ĐĩĐŊĐž в ОдиĐŊ Ņ„Đ°ĐšĐģ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `main.py` и ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Đ’Đ°ŅˆĐ¸Ņ… Ņ„Đ°ĐšĐģОв ĐŋĐžŅ…ĐžĐļа ĐŊа ŅŅ‚Ņƒ: +Đ•ŅĐģи Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI — ОдиĐŊ Ņ„Đ°ĐšĐģ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `main.py` ĐąĐĩС Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `./app`, ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Ņ„Đ°ĐšĐģОв ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ‚Đ°ĐēОК: ``` . @@ -363,7 +389,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage └── requirements.txt ``` -ВаĐŧ ĐŊ҃ĐļĐŊĐž иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ в `Dockerfile` ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Đĩ ĐŋŅƒŅ‚Đ¸ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ„Đ°ĐšĐģОв: +ĐĸĐžĐŗĐ´Đ° в `Dockerfile` ĐŊ҃ĐļĐŊĐž иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ĐŋŅƒŅ‚Đ¸ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ: ```{ .dockerfile .annotate hl_lines="10 13" } FROM python:3.9 @@ -374,360 +400,221 @@ COPY ./requirements.txt /code/requirements.txt RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt -# (1) +# (1)! COPY ./main.py /code/ -# (2) -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] +# (2)! +CMD ["fastapi", "run", "main.py", "--port", "80"] ``` -1. ĐĄĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž Ņ„Đ°ĐšĐģ `main.py` в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `/code` (ĐŊĐĩ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐšŅ‚Đĩ `./app`). +1. КоĐŋĐ¸Ņ€ŅƒĐĩĐŧ Ņ„Đ°ĐšĐģ `main.py` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в `/code` (ĐąĐĩС Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ `./app`). -2. ĐŸŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ Uvicorn ҃ĐēаĐļĐ¸Ņ‚Đĩ ĐĩĐŧ҃, Ņ‡Ņ‚Đž ĐžĐąŅŠĐĩĐēŅ‚ `app` ĐŊ҃ĐļĐŊĐž иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ иС Ņ„Đ°ĐšĐģа `main` (вĐŧĐĩŅŅ‚Đž иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ иС `app.main`). +2. Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ `fastapi run` Đ´ĐģŅ СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ иС ОдĐŊĐžĐŗĐž Ņ„Đ°ĐšĐģа `main.py`. -ĐĐ°ŅŅ‚Ņ€ĐžĐšŅ‚Đĩ Uvicorn ĐŊа Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ `main` вĐŧĐĩŅŅ‚Đž `app.main` Đ´ĐģŅ иĐŧĐŋĐžŅ€Ņ‚Đ° ĐžĐąŅŠĐĩĐēŅ‚Đ° `app`. +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚Đĩ Ņ„Đ°ĐšĐģ в `fastapi run`, ĐžĐŊ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚, Ņ‡Ņ‚Đž ŅŅ‚Đž ОдиĐŊĐžŅ‡ĐŊŅ‹Đš Ņ„Đ°ĐšĐģ, а ĐŊĐĩ Ņ‡Đ°ŅŅ‚ŅŒ ĐŋаĐēĐĩŅ‚Đ°, и ĐŋОКĐŧґ҂, ĐēаĐē ĐĩĐŗĐž иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Đ˛Đ°ŅˆĐĩ FastAPI-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. 😎 -## КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ +## КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ { #deployment-concepts } -Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ Đ˛ŅĐŋĐžĐŧĐŊиĐŧ Đž [КоĐŊ҆ĐĩĐŋŅ†Đ¸ŅŅ… Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ](concepts.md){.internal-link target=_blank} и ĐŋŅ€Đ¸ĐŧĐĩĐŊиĐŧ Đ¸Ņ… Đē ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ. +Đ•Ņ‰Ņ‘ Ņ€Đ°Đˇ Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ [ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ](concepts.md){.internal-link target=_blank} ĐŋŅ€Đ¸ĐŧĐĩĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐž Đē ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ. -КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ - ŅŅ‚Đž, в ĐžŅĐŊОвĐŊĐžĐŧ, иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ ҃ĐŋŅ€ĐžŅ‰Đ°ŅŽŅ‰Đ¸Đš **ŅĐąĐžŅ€Đē҃ и Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ и ĐžĐŊи ĐŊĐĩ ĐžĐąŅĐˇŅ‹Đ˛Đ°ŅŽŅ‚ Đē ĐŋŅ€Đ¸ĐŧĐĩĐŊĐĩĐŊĐ¸ŅŽ ĐēаĐēОК-Ņ‚Đž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊОК **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ**, а СĐŊĐ°Ņ‡Đ¸Ņ‚ ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ Đ˛Ņ‹ĐąĐ¸Ņ€Đ°Ņ‚ŅŒ ĐŊ҃ĐļĐŊŅƒŅŽ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸ŅŽ. +КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ ĐŗĐģавĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ҃ĐŋŅ€ĐžŅ‰Đ°ŅŽŅ‚ **ŅĐąĐžŅ€Đē҃ и Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, ĐŊĐž ĐŊĐĩ ĐŊĐ°Đ˛ŅĐˇŅ‹Đ˛Đ°ŅŽŅ‚ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš ĐŋĐžĐ´Ņ…ĐžĐ´ Đē ŅŅ‚Đ¸Đŧ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅĐŧ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ**, и ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš. -**ĐĨĐžŅ€ĐžŅˆĐ°Ņ ĐŊĐžĐ˛ĐžŅŅ‚ŅŒ** в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐž ĐžŅ‚ Đ˛Ņ‹ĐąŅ€Đ°ĐŊĐŊОК ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸, ĐŧŅ‹ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐŧĐžĐļĐĩĐŧ ĐŋĐžĐēŅ€Ņ‹Ņ‚ŅŒ Đ˛ŅĐĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ. 🎉 +**ĐĨĐžŅ€ĐžŅˆĐ°Ņ ĐŊĐžĐ˛ĐžŅŅ‚ŅŒ** в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŋŅ€Đ¸ ĐģŅŽĐąĐžĐš ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸ ĐĩŅŅ‚ŅŒ ҁĐŋĐžŅĐžĐą ĐžŅ…Đ˛Đ°Ņ‚Đ¸Ņ‚ŅŒ Đ˛ŅĐĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ. 🎉 -Đ Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ŅŅ‚Đ¸ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ** ĐŋŅ€Đ¸ĐŧĐĩĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐž Đē ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ: +Đ Đ°ŅŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ŅŅ‚Đ¸ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ** в Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛: -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS -* ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ПĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ +* HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ -## Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS +## HTTPS { #https } -Đ•ŅĐģи ĐŧŅ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģиĐŧŅŅ, Ņ‡Ņ‚Đž **ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°** ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI, Ņ‚Đž Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ HTTPS ĐŧĐžĐļĐŊĐž ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ҁĐŊĐ°Ņ€ŅƒĐļи** ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŋŅ€Đ¸ ĐŋĐžĐŧĐžŅ‰Đ¸ Đ´Ņ€ŅƒĐŗĐžĐŗĐž иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°. +Đ•ŅĐģи ĐŧŅ‹ Ņ€Đ°ŅŅĐŧĐ°Ņ‚Ņ€Đ¸Đ˛Đ°ĐĩĐŧ Ņ‚ĐžĐģҌĐēĐž **ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°** Đ´ĐģŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI (и даĐģĐĩĐĩ СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**), Ņ‚Đž HTTPS ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ŅŅ **вĐŊĐĩ҈ĐŊиĐŧ** иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ. -Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€, в ĐēĐžŅ‚ĐžŅ€ĐžĐŧ ĐĩŅŅ‚ŅŒ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Traefik, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Đš ҁ **HTTPS** и **ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž** ОйĐŊОвĐģŅŅŽŅ‰Đ¸Đš **ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹**. +Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ҁ Traefik, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąĐĩҀґ҂ ĐŊа ҁĐĩĐąŅ **HTTPS** и **Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ** ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ **ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛**. /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -Traefik ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đŧ ҁ Docker, Kubernetes и иĐŧ ĐŋОдОйĐŊŅ‹Đŧи иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Đŧи. ОĐŊ ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚ в ŅƒŅŅ‚Đ°ĐŊОвĐēĐĩ и ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ HTTPS Đ´ĐģŅ Đ’Đ°ŅˆĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛. +ĐŖ Traefik ĐĩŅŅ‚ŅŒ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ ҁ Docker, Kubernetes и Đ´Ņ€ŅƒĐŗĐ¸Đŧи, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ и ҁĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ HTTPS Đ´ĐģŅ Đ˛Đ°ŅˆĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛. /// -В ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹, Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ HTTPS ĐŧĐžĐļĐŊĐž дОвĐĩŅ€Đ¸Ņ‚ŅŒ ОйĐģĐ°Ņ‡ĐŊĐžĐŧ҃ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Ņƒ, ĐĩҁĐģи ĐžĐŊ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ Ņ‚Đ°ĐēŅƒŅŽ ҃ҁĐģŅƒĐŗŅƒ. +В ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹ HTTPS ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ€ĐĩаĐģиСОваĐŊ ĐēаĐē ҁĐĩŅ€Đ˛Đ¸Ņ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° (ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ). -## ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа и ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ +## ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēи { #running-on-startup-and-restarts } -ĐžĐąŅ‹Ņ‡ĐŊĐž **СаĐŋ҃ҁĐēĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ** СаĐŊиĐŧаĐĩŅ‚ŅŅ ĐēаĐēОК-Ņ‚Đž ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚. +ĐžĐąŅ‹Ņ‡ĐŊĐž ĐĩŅŅ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚, ĐžŅ‚Đ˛ĐĩŅ‡Đ°ŅŽŅ‰Đ¸Đš Са **СаĐŋ҃ҁĐē и Ņ€Đ°ĐąĐžŅ‚Ņƒ** Đ˛Đ°ŅˆĐĩĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. -Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ŅĐ°Đŧ **Docker**, **Docker Compose**, **Kubernetes**, **ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€** и Ņ‚.Đŋ. +Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ŅĐ°Đŧ **Docker**, **Docker Compose**, **Kubernetes**, **ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛Đ¸Ņ** и Ņ‚.Đŋ. -В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚ĐĩĐšŅˆĐ¸Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа и ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ (ĐŋŅ€Đ¸ ĐŋадĐĩĐŊии). НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžĐŧаĐŊĐ´Đĩ СаĐŋ҃ҁĐēа Docker-ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŧĐžĐļĐŊĐž Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐžĐŋŅ†Đ¸ŅŽ `--restart`. +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ (иĐģи вО Đ˛ŅĐĩŅ…) ҁĐģŅƒŅ‡Đ°Đĩв ĐĩŅŅ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Đ°Ņ ĐžĐŋŅ†Đ¸Ņ, Ņ‡Ņ‚ĐžĐąŅ‹ вĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ СаĐŋ҃ҁĐē ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēи ĐŋŅ€Đ¸ ŅĐąĐžŅŅ…. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в Docker ŅŅ‚Đž ĐžĐŋŅ†Đ¸Ņ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--restart`. -ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ СаĐŋ҃ҁĐēĐžĐŧ и ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēОК ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК ĐąĐĩС Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ - вĐĩҁҌĐŧа ĐˇĐ°Ņ‚Ņ€ŅƒĐ´ĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐž. Но ĐŋŅ€Đ¸ **Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи** - ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đš ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. ✨ +БĐĩС ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ОйĐĩҁĐŋĐĩŅ‡Đ¸Ņ‚ŅŒ СаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēи ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ҁĐģĐžĐļĐŊĐž. Но ĐŋŅ€Đ¸ **Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи** в йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ŅŅ‚ĐžŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģ Đ´ĐžŅŅ‚ŅƒĐŋĐĩĐŊ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. ✨ -## ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ - ĐŖĐēаСаĐŊиĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ +## Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ — ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ { #replication-number-of-processes } -Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐēĐģĐ°ŅŅ‚ĐĩŅ€ ĐŧĐ°ŅˆĐ¸ĐŊ ĐŋОд ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ **Kubernetes**, Docker Swarm Mode, Nomad иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊОК ҁĐģĐžĐļĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК ĐžŅ€ĐēĐĩŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, вĐŧĐĩŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ (Ņ‚Đ¸Đŋа Gunicorn и ĐĩĐŗĐž Đ˛ĐžŅ€ĐēĐĩҀҋ) в ĐēаĐļĐ´ĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ **҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°**. +Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐēĐģĐ°ŅŅ‚ĐĩŅ€ ĐŧĐ°ŅˆĐ¸ĐŊ ҁ **Kubernetes**, Docker Swarm Mode, Nomad иĐģи Đ´Ņ€ŅƒĐŗĐžĐš ĐŋĐžŅ…ĐžĐļĐĩĐš ŅĐ¸ŅŅ‚ĐĩĐŧОК Đ´ĐģŅ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧи ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ĐŊа ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŧĐ°ŅˆĐ¸ĐŊĐ°Ņ…, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ **҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ĐĩĐš** ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°**, а ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn ҁ Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи) в ĐēаĐļĐ´ĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ. -В ĐģŅŽĐąŅƒŅŽ иС ŅŅ‚Đ¸Ņ… ŅĐ¸ŅŅ‚ĐĩĐŧ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ĐžĐąŅ‹Ņ‡ĐŊĐž Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊ ҁĐŋĐžŅĐžĐą ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ **ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** Đ´ĐģŅ Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ **ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** ĐžŅ‚ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛ ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°**. +ОдĐŊа иС Ņ‚Đ°ĐēĐ¸Ņ… ŅĐ¸ŅŅ‚ĐĩĐŧ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧи ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи, ĐēаĐē Kubernetes, ĐžĐąŅ‹Ņ‡ĐŊĐž иĐŧĐĩĐĩŅ‚ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đš ҁĐŋĐžŅĐžĐą ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ **Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ĐĩĐš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Đē҃ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** Đ´ĐģŅ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛ — Đ˛ŅŅ‘ ŅŅ‚Đž ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°**. -В Ņ‚Đ°ĐēОК ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸Đ¸ Đ’Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ **ĐžĐąŅ€Đ°Đˇ Docker**, ĐēаĐē [ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ](#dockerfile), ҁ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ‹Đŧи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи и СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Đš **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn** вĐŧĐĩŅŅ‚Đž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚ĐžĐąŅ‹ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ Gunicorn ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи Uvicorn. +В Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ŅĐžĐąŅ€Đ°Ņ‚ŅŒ **Docker-ĐžĐąŅ€Đ°Đˇ ҁ ĐŊ҃ĐģŅ**, ĐēаĐē [ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ](#dockerfile), ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ и СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn** вĐŧĐĩŅŅ‚Đž ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ Uvicorn. -### БаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи +### БаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи { #load-balancer } -ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ОдиĐŊ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ **ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°ĐĩŅ‚ ĐŗĐģавĐŊŅ‹Đš ĐŋĐžŅ€Ņ‚**. Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš **ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ TLS** Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ **HTTPS** иĐģи Ņ‡Ņ‚Đž-Ņ‚Đž ĐŋОдОйĐŊĐžĐĩ. +ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ĐžĐąŅ‹Ņ‡ĐŊĐž ĐĩŅŅ‚ŅŒ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚, **ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đš ĐŗĐģавĐŊŅ‹Đš ĐŋĐžŅ€Ņ‚**. Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ — **ĐŋŅ€ĐžĐēŅĐ¸ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS** Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи **HTTPS** иĐģи ĐŋĐžŅ…ĐžĐļиК иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚. -ĐŸĐžŅĐēĐžĐģҌĐē҃ ŅŅ‚ĐžŅ‚ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ **ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ СаĐŋŅ€ĐžŅŅ‹** и Ņ€Đ°Đ˛ĐŊĐžĐŧĐĩŅ€ĐŊĐž **Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚** Đ¸Ņ… ĐŧĐĩĐļĐ´Ņƒ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚Đ°Đŧи, ĐĩĐŗĐž Ņ‚Đ°ĐēĐļĐĩ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**. +ĐŸĐžŅĐēĐžĐģҌĐē҃ ŅŅ‚ĐžŅ‚ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ **ĐŊĐ°ĐŗŅ€ŅƒĐˇĐē҃** СаĐŋŅ€ĐžŅĐžĐ˛ и Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅĐĩŅ‚ ĐĩŅ‘ ĐŧĐĩĐļĐ´Ņƒ Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи **ŅĐąĐ°ĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐž**, ĐĩĐŗĐž Ņ‡Đ°ŅŅ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**. /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -**ĐŸŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ TLS** ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**. +ĐĸĐžŅ‚ ĐļĐĩ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ **ĐŋŅ€ĐžĐēŅĐ¸ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ HTTPS, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**. /// -ĐĄĐ¸ŅŅ‚ĐĩĐŧа ĐžŅ€ĐēĐĩŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Đ´ĐģŅ СаĐŋ҃ҁĐēа и ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи, иĐŧĐĩĐĩŅ‚ Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ **ҁĐĩŅ‚ĐĩĐ˛ĐžĐŗĐž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ HTTP-СаĐŋŅ€ĐžŅĐžĐ˛) ĐŧĐĩĐļĐ´Ņƒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ҁ Đ’Đ°ŅˆĐ¸Đŧи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧи и **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ**). +ĐŸŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧа, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Đ´ĐģŅ СаĐŋ҃ҁĐēа и ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ иĐŧи, ҃ĐļĐĩ иĐŧĐĩĐĩŅ‚ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ ҁҀĐĩĐ´ŅŅ‚Đ˛Đ° Đ´ĐģŅ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ **ҁĐĩŅ‚ĐĩĐ˛ĐžĐŗĐž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, HTTP-СаĐŋŅ€ĐžŅĐžĐ˛) ĐžŅ‚ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đēа ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **ĐŋŅ€ĐžĐēŅĐ¸ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS**) Đē ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Ņƒ(-аĐŧ) ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. -### ОдиĐŊ йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē - МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ +### ОдиĐŊ йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē — ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛-Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ { #one-load-balancer-multiple-worker-containers } -ĐŸŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ **Kubernetes** иĐģи аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи ĐžŅ€ĐēĐĩŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Đ¸Ņ… вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐĩĐš ҁĐĩŅ‚Đ¸ ĐŋОСвОĐģŅĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ОдиĐŊ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°ĐĩŅ‚ **ĐŗĐģавĐŊŅ‹Đš** ĐŋĐžŅ€Ņ‚ и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ СаĐŋŅ€ĐžŅŅ‹ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Ņƒ СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ҁ Đ’Đ°ŅˆĐ¸Đŧи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧи. +ĐŸŅ€Đ¸ Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ **Kubernetes** иĐģи ĐŋĐžŅ…ĐžĐļиĐŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧи ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи Đ¸Ņ… вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ ĐŧĐĩŅ…Đ°ĐŊиСĐŧŅ‹ ҁĐĩŅ‚Đ¸ ĐŋОСвОĐģŅŅŽŅ‚ ОдĐŊĐžĐŧ҃ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē҃ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**, ҁĐģŅƒŅˆĐ°ŅŽŅ‰ĐĩĐŧ҃ ĐŗĐģавĐŊŅ‹Đš **ĐŋĐžŅ€Ņ‚**, ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ в **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, ĐŗĐ´Đĩ СаĐŋŅƒŅ‰ĐĩĐŊĐž Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. -В ĐēаĐļĐ´ĐžĐŧ иС ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ĐžĐąŅ‹Ņ‡ĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš Đ’Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ FastAPI). КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ **идĐĩĐŊŅ‚Đ¸Ņ‡ĐŊŅ‹Đŧи**, СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đŧи ĐŊа ĐžŅĐŊОвĐĩ ОдĐŊĐžĐŗĐž и Ņ‚ĐžĐŗĐž ĐļĐĩ ĐžĐąŅ€Đ°ĐˇĐ°, ĐŊĐž ҃ ĐēаĐļĐ´ĐžĐŗĐž ĐąŅƒĐ´ŅƒŅ‚ ŅĐ˛ĐžĐ¸ ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁ, ĐŋаĐŧŅŅ‚ŅŒ и Ņ‚.Đŋ. ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ĐŧŅ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩĐŧ ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° **Ņ€Đ°ŅĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиваĐŊĐ¸Ņ** Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐŋĐž **Ņ€Đ°ĐˇĐŊŅ‹Đŧ ŅĐ´Ņ€Đ°Đŧ** ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° иĐģи даĐļĐĩ **Ņ€Đ°ĐˇĐŊŅ‹Đŧ ĐŧĐ°ŅˆĐ¸ĐŊаĐŧ**. +КаĐļĐ´Ņ‹Đš Ņ‚Đ°ĐēОК ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ ĐžĐąŅ‹Ņ‡ĐŊĐž иĐŧĐĩĐĩŅ‚ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ FastAPI). Đ’ŅĐĩ ĐžĐŊи — **ОдиĐŊаĐēĐžĐ˛Ņ‹Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ**, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Đĩ ОдĐŊĐž и Ņ‚Đž ĐļĐĩ, ĐŊĐž ҃ ĐēаĐļĐ´ĐžĐŗĐž ŅĐ˛ĐžĐš ĐŋŅ€ĐžŅ†Đĩҁҁ, ĐŋаĐŧŅŅ‚ŅŒ и Ņ‚.Đŋ. ĐĸаĐē Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģиСĐŧ** ĐŋĐž **Ņ€Đ°ĐˇĐŊŅ‹Đŧ ŅĐ´Ņ€Đ°Đŧ** CPU иĐģи даĐļĐĩ **Ņ€Đ°ĐˇĐŊŅ‹Đŧ ĐŧĐ°ŅˆĐ¸ĐŊаĐŧ**. -ĐĄĐ¸ŅŅ‚ĐĩĐŧа ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ҁ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** ĐąŅƒĐ´ĐĩŅ‚ **Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹** Đē ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧи **ĐŋĐž ĐžŅ‡ĐĩŅ€Đĩди**. ĐĸĐž ĐĩŅŅ‚ŅŒ ĐēаĐļĐ´Ņ‹Đš СаĐŋŅ€ĐžŅ ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐŊ ОдĐŊиĐŧ иС ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° **ОдиĐŊаĐēĐžĐ˛Ņ‹Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ҁ ОдĐŊиĐŧ и Ņ‚ĐĩĐŧ ĐļĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. +ĐĄĐ¸ŅŅ‚ĐĩĐŧа Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ҁ **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸ĐēĐžĐŧ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** ĐąŅƒĐ´ĐĩŅ‚ **Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹** ĐŧĐĩĐļĐ´Ņƒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ **ĐŋĐž ĐžŅ‡ĐĩŅ€Đĩди**. ĐĸĐž ĐĩŅŅ‚ŅŒ ĐēаĐļĐ´Ņ‹Đš СаĐŋŅ€ĐžŅ ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒŅŅ ОдĐŊиĐŧ иС ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… **Ņ€ĐĩĐŋĐģĐ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**. -**БаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ Đē *Ņ€Đ°ĐˇĐŊŅ‹Đŧ* ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧ, Ņ€Đ°ŅĐŋĐžĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧ в Đ˛Đ°ŅˆĐĩĐŧ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи ҃ ĐŊĐ¸Ņ… Ņ€Đ°ĐˇĐŊŅ‹Đĩ Đ´ĐžĐŧĐĩĐŊŅ‹ иĐģи ĐŋŅ€ĐĩŅ„Đ¸Đēҁҋ ĐŋŅƒŅ‚Đ¸) и ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ ĐŊ҃ĐļĐŊĐžĐŧ҃ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Ņƒ ҁ ҂ҀĐĩĐąŅƒĐĩĐŧŅ‹Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. +ĐžĐąŅ‹Ņ‡ĐŊĐž Ņ‚Đ°ĐēОК **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи** ĐŧĐžĐļĐĩŅ‚ Ņ‚Đ°ĐēĐļĐĩ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ Đē *Đ´Ņ€ŅƒĐŗĐ¸Đŧ* ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧ в Đ˛Đ°ŅˆĐĩĐŧ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đē Đ´Ņ€ŅƒĐŗĐžĐŧ҃ Đ´ĐžĐŧĐĩĐŊ҃ иĐģи ĐŋОд Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋŅ€ĐĩŅ„Đ¸ĐēŅĐžĐŧ ĐŋŅƒŅ‚Đ¸ URL) и ĐŊаĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Đ¸Ņ… Đē ĐŊ҃ĐļĐŊŅ‹Đŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ ŅŅ‚ĐžĐŗĐž *Đ´Ņ€ŅƒĐŗĐžĐŗĐž* ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. -### ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ +### ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ { #one-process-per-container } -В ŅŅ‚ĐžĐŧ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚Đĩ **в ОдĐŊĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐąŅƒĐ´ĐĩŅ‚ СаĐŋŅƒŅ‰ĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ (Uvicorn)**, а ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ иСĐŧĐĩĐŊĐĩĐŊиĐĩĐŧ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐēĐžĐŋиК ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°. +В Ņ‚Đ°ĐēĐžĐŧ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, Đ˛Ņ‹ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ **ОдиĐŊ (Uvicorn) ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**, Ņ‚Đ°Đē ĐēаĐē Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ ҃ĐļĐĩ ҃ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°. -ЗдĐĩҁҌ **ĐŊĐĩ ĐŊ҃ĐļĐĩĐŊ** ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Ņ‚Đ¸Đŋа Gunicorn, ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи Uvicorn, иĐģи ĐļĐĩ Uvicorn, ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš Đ´Ņ€ŅƒĐŗĐ¸Đŧи ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи Uvicorn. Đ”ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž **Ņ‚ĐžĐģҌĐēĐž ОдĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° Uvicorn** ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ (ĐŊĐž СаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐŊĐĩ СаĐŋŅ€Đĩ҉ґĐŊ). +ĐŸĐžŅŅ‚ĐžĐŧ҃ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ **ĐŊĐĩ ĐŊ҃ĐļĐŊĐž** ĐŋОдĐŊиĐŧĐ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ҇ĐĩŅ€ĐĩС ĐžĐŋŅ†Đ¸ŅŽ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--workers`. ĐŅƒĐļĐĩĐŊ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn** ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ (ĐŊĐž, вОСĐŧĐžĐļĐŊĐž, ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛). -Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ (Gunicorn иĐģи Uvicorn) вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° Ņ‚ĐžĐģҌĐēĐž дОйавĐģŅĐĩŅ‚ **иСĐģĐ¸ŅˆĐŊĐĩĐĩ ҃ҁĐģĐžĐļĐŊĐĩĐŊиĐĩ**, Ņ‚Đ°Đē ĐēаĐē ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģŅŅ‚ŅŒ ŅĐ¸ŅŅ‚ĐĩĐŧОК ĐžŅ€ĐēĐĩŅŅ‚Ņ€Đ°Ņ†Đ¸Đ¸. +НаĐģĐ¸Ņ‡Đ¸Đĩ ĐžŅ‚Đ´ĐĩĐģҌĐŊĐžĐŗĐž ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° (ĐēаĐē ĐŋŅ€Đ¸ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Ņ…) Ņ‚ĐžĐģҌĐēĐž Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ **ĐģĐ¸ŅˆĐŊŅŽŅŽ ҁĐģĐžĐļĐŊĐžŅŅ‚ŅŒ**, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ҃ĐļĐĩ ĐąĐĩҀґ҂ ĐŊа ҁĐĩĐąŅ Đ˛Đ°ŅˆĐ° ĐēĐģĐ°ŅŅ‚ĐĩŅ€ĐŊĐ°Ņ ŅĐ¸ŅŅ‚ĐĩĐŧа. -### МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° Đ´ĐģŅ ĐžŅĐžĐąŅ‹Ņ… ҁĐģŅƒŅ‡Đ°Đĩв +### КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ ҁ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи и ĐžŅĐžĐąŅ‹Đĩ ҁĐģŅƒŅ‡Đ°Đ¸ { #containers-with-multiple-processes-and-special-cases } -БĐĩĐˇŅƒŅĐģОвĐŊĐž, ĐąŅ‹Đ˛Đ°ŅŽŅ‚ **ĐžŅĐžĐąŅ‹Đĩ ҁĐģŅƒŅ‡Đ°Đ¸**, ĐēĐžĐŗĐ´Đ° ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Gunicorn**, ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи **ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи Uvicorn**. +КоĐŊĐĩ҇ĐŊĐž, ĐĩŅŅ‚ŅŒ **ĐžŅĐžĐąŅ‹Đĩ ҁĐģŅƒŅ‡Đ°Đ¸**, ĐēĐžĐŗĐ´Đ° ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** ҁ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи **Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи Uvicorn** вĐŊŅƒŅ‚Ņ€Đ¸. -ДĐģŅ Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°Đĩв Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ** (ĐŋŅ€Đ¸Đŧ. ĐŋĐĩŅ€: - *СдĐĩҁҌ и даĐģĐĩĐĩ ĐŊа ŅŅ‚ĐžĐš ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đĩ, ĐĩҁĐģи Đ˛Ņ‹ Đ˛ŅŅ‚Ņ€ĐĩŅ‚Đ¸Ņ‚Đĩ ŅĐžŅ‡ĐĩŅ‚Đ°ĐŊиĐĩ "ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ" ĐąĐĩС ŅƒŅ‚ĐžŅ‡ĐŊĐĩĐŊиК, Ņ‚Đž Đ°Đ˛Ņ‚ĐžŅ€ иĐŧĐĩĐĩŅ‚ в Đ˛Đ¸Đ´Ņƒ иĐŧĐĩĐŊĐŊĐž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩĐŧŅ‹Đš иĐŧ ĐžĐąŅ€Đ°Đˇ*), ĐŗĐ´Đĩ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ **Gunicorn**, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰Đ¸Đš ĐŊĐĩҁĐēĐžĐģҌĐēĐž **ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ Uvicorn** и ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°ŅŽŅ‰Đ¸Đĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° ŅĐ´ĐĩŅ€ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°. Đ¯ Ņ€Đ°ŅŅĐēаĐļ҃ ваĐŧ Ой ŅŅ‚ĐžĐŧ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Ņ‚ŅƒŅ‚: [ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ ŅĐž Đ˛ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đŧи Gunicorn и Uvicorn](#docker-gunicorn-uvicorn). +В Ņ‚Đ°ĐēĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ†Đ¸ŅŽ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--workers`, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐŊ҃ĐļĐŊĐžĐĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛: -НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ ĐŋОдОйĐŊҋ҅ ҁĐģŅƒŅ‡Đ°Đĩв: +```{ .dockerfile .annotate } +FROM python:3.9 -#### ĐŸŅ€ĐžŅŅ‚ĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ +WORKDIR /code -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°, ĐĩҁĐģи Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **ĐŊĐ°ŅŅ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžŅŅ‚ĐžĐĩ**, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐŊĐĩŅ‚ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ (ĐŋĐž ĐēŅ€Đ°ĐšĐŊĐĩĐš ĐŧĐĩŅ€Đĩ, ĐŋĐžĐēа ĐŊĐĩŅ‚) в Ņ‚Ņ‰Đ°Ņ‚ĐĩĐģҌĐŊҋ҅ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐ°Ņ… ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ и ваĐŧ Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž иĐŧĐĩŅŽŅ‰Đ¸Ņ…ŅŅ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ (ĐĩҁĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ) Đ´ĐģŅ СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **Ņ‚ĐžĐģҌĐēĐž ĐŊа ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ**, а ĐŊĐĩ в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ. +COPY ./requirements.txt /code/requirements.txt -#### Docker Compose +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt -ĐĄ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **Docker Compose** ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐ˛ĐžŅ€Đ°Ņ‡Đ¸Đ˛Đ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ĐŊа **ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ** (ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ), ĐŊĐž ĐŋŅ€Đ¸ ŅŅ‚Đž ҃ Đ˛Đ°Ņ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžŅŅ‚ĐžĐŗĐž ҁĐŋĐžŅĐžĐąĐ° ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ҁ ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đŧ ŅĐžŅ…Ņ€Đ°ĐŊĐĩĐŊиĐĩĐŧ ĐžĐąŅ‰ĐĩĐš ҁĐĩŅ‚Đ¸ и **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Đēи ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**. +COPY ./app /code/app -В ŅŅ‚ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš **ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи**, вĐŊŅƒŅ‚Ņ€Đ¸ **ОдĐŊĐžĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**. +# (1)! +CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"] +``` -#### Prometheus и ĐŋŅ€ĐžŅ‡Đ¸Đĩ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊŅ‹ +1. ЗдĐĩҁҌ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ĐžĐŋŅ†Đ¸ŅŽ `--workers`, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ Ņ‡Đ¸ŅĐģĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ Ņ€Đ°Đ˛ĐŊŅ‹Đŧ 4. -ĐŖ Đ˛Đ°Ņ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ и **Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊŅ‹**, ĐēĐžĐŗĐ´Đ° Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** вĐŊŅƒŅ‚Ņ€Đ¸ **ОдĐŊĐžĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°** ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžŅ‰Đĩ, ĐŊĐĩĐļĐĩĐģи СаĐŋ҃ҁĐē **ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ҁ **ĐĩдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ** в ĐēаĐļĐ´ĐžĐŧ иС ĐŊĐ¸Ņ…. +ĐŸŅ€Đ¸ĐŧĐĩҀҋ, ĐēĐžĐŗĐ´Đ° ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ҃ĐŧĐĩҁ҂ĐŊĐž: -НаĐŋŅ€Đ¸ĐŧĐĩŅ€ (в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸), ҃ Đ˛Đ°Ņ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ ĐŋОдОйĐŊŅ‹Đĩ ŅĐēҁĐŋĐžŅ€Ņ‚Ņ‘Ņ€Ņƒ Prometheus, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ´ĐžĐģĐļĐŊŅ‹ иĐŧĐĩŅ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋ Đē **ĐēаĐļĐ´ĐžĐŧ҃ СаĐŋŅ€ĐžŅŅƒ** ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‰ĐĩĐŧ҃ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€. +#### ĐŸŅ€ĐžŅŅ‚ĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ { #a-simple-app } -Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐąŅƒĐ´ĐĩŅ‚ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, Ņ‚Đž Prometheus, ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, **ĐŋŅ€Đ¸ ŅĐąĐžŅ€Đĩ ĐŧĐĩŅ‚Ņ€Đ¸Đē** ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ Đ¸Ņ… **Ņ‚ĐžĐģҌĐēĐž ҁ ОдĐŊĐžĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš СаĐŋŅ€ĐžŅ, вĐŧĐĩŅŅ‚Đž **ŅĐąĐžŅ€Đ° ĐŧĐĩŅ‚Ņ€Đ¸Đē** ŅĐž Đ˛ŅĐĩŅ… Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛. +ВаĐŧ ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ, ĐĩҁĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž ĐŋŅ€ĐžŅŅ‚ĐžĐĩ**, Ņ‡Ņ‚ĐžĐąŅ‹ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒŅŅ ĐŊа **ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ**, а ĐŊĐĩ в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ. -В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€ĐžŅ‰Đĩ иĐŧĐĩŅ‚ŅŒ **ОдиĐŊ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** ŅĐž **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛ĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ҁ ĐŊ҃ĐļĐŊŅ‹Đŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ (Ņ‚Đ°ĐēиĐŧ ĐēаĐē ŅĐēҁĐŋĐžŅ€Ņ‚Ņ‘Ņ€ Prometheus) в ŅŅ‚ĐžĐŧ ĐļĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ и ŅĐžĐąĐ¸Ņ€Đ°ŅŽŅ‰ĐĩĐŧ ĐŧĐĩŅ‚Ņ€Đ¸Đēи ŅĐž Đ˛ŅĐĩŅ… вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐ¸Ņ… ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ŅŅ‚ĐžĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. +#### Docker Compose { #docker-compose } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐŊа **ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ** (ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ) ҁ **Docker Compose**, и ҃ Đ˛Đ°Ņ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžŅŅ‚ĐžĐŗĐž ҁĐŋĐžŅĐžĐąĐ° ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ĐĩĐš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ (в Docker Compose), ŅĐžŅ…Ņ€Đ°ĐŊŅŅ ĐžĐąŅ‰ŅƒŅŽ ҁĐĩŅ‚ŅŒ и **йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Đē҃ ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи**. + +ĐĸĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Ņ…ĐžŅ‚ĐĩŅ‚ŅŒ **ОдиĐŊ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** ҁ **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš СаĐŋ҃ҁĐēаĐĩŅ‚ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛** вĐŊŅƒŅ‚Ņ€Đ¸. --- -ХаĐŧĐžĐĩ ĐŗĐģавĐŊĐžĐĩ - **ĐŊи ОдĐŊĐž** иС ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ ĐŋŅ€Đ°Đ˛Đ¸Đģ ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ **Đ˛Ņ‹ŅĐĩ҇ĐĩĐŊĐŊŅ‹Đŧ ĐŊа ĐēаĐŧĐŊĐĩ** и Đ˛Ņ‹ ĐŊĐĩ ĐžĐąŅĐˇĐ°ĐŊŅ‹ ҁĐģĐĩĐŋĐž Đ¸Ņ… ĐŋĐžĐ˛Ņ‚ĐžŅ€ŅŅ‚ŅŒ. Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ идĐĩи ĐŋŅ€Đ¸ **Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€ĐĩĐŊии Đ˛Đ°ŅˆĐĩĐŗĐž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž ҁĐģŅƒŅ‡Đ°Ņ** и ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž Ņ€ĐĩŅˆĐ°Ņ‚ŅŒ, ĐēаĐēĐ°Ņ иС ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ ĐģŅƒŅ‡ŅˆĐĩ: +ГĐģавĐŊĐžĐĩ — **ĐŊи ОдĐŊĐž** иС ŅŅ‚Đ¸Ņ… ĐŋŅ€Đ°Đ˛Đ¸Đģ ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ **ŅŅ‚Ņ€ĐžĐŗĐž ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ**. Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ŅŅ‚Đ¸ идĐĩи, Ņ‡Ņ‚ĐžĐąŅ‹ **ĐžŅ†ĐĩĐŊĐ¸Ņ‚ŅŒ ŅĐ˛ĐžĐš ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš ҁĐģŅƒŅ‡Đ°Đš** и Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ, ĐēаĐēОК ĐŋĐžĐ´Ņ…ĐžĐ´ ĐģŅƒŅ‡ŅˆĐĩ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐš ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹, ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ: -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS -* ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ПĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ +* БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ŅŽ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ -## ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ +## ПаĐŧŅŅ‚ŅŒ { #memory } -ĐŸŅ€Đ¸ **СаĐŋ҃ҁĐēĐĩ ОдĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€** Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŋĐžĐŊŅŅ‚ĐŊŅ‹Đš, ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊŅ‹Đš и ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đš ĐžĐąŅŠŅ‘Đŧ ĐŋаĐŧŅŅ‚Đ¸, ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩĐŧŅ‹Đš ОдĐŊиĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐŧ. +Đ•ŅĐģи Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**, ҃ ĐēаĐļĐ´ĐžĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ĐąŅƒĐ´ĐĩŅ‚ йОĐģĐĩĐĩ-ĐŧĐĩĐŊĐĩĐĩ ҇ґ҂ĐēĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš, ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊŅ‹Đš и ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐŊŅ‹Đš ĐžĐąŅŠŅ‘Đŧ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩĐŧОК ĐŋаĐŧŅŅ‚Đ¸ (ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€Đ¸ Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Đ¸). -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đĩ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ĐŋаĐŧŅŅ‚Đ¸ ĐŋŅ€Đ¸ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊии ŅĐ˛ĐžĐĩĐš ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, **Kubernetes**). ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ ŅĐ¸ŅŅ‚ĐĩĐŧа ҁĐŧĐžĐļĐĩŅ‚ **иСĐŧĐĩĐŊŅŅ‚ŅŒ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ĐŊа **Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐĩĐš ĐŧĐ°ŅˆĐ¸ĐŊĐ°Ņ…** ĐŋŅ€Đ¸Đ˛ĐžĐ´Ņ в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đĩ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐŋаĐŧŅŅ‚Đ¸ ĐŊ҃ĐļĐŊОК ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧ ҁ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ ĐŋаĐŧŅŅ‚Đ¸ Đ´ĐžŅŅ‚ŅƒĐŋĐŊОК в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ (ĐŊĐ°ĐąĐžŅ€Đĩ Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐŧĐ°ŅˆĐ¸ĐŊ). +Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ Ņ‚Đ°ĐēиĐĩ ĐļĐĩ ĐģиĐŧĐ¸Ņ‚Ņ‹ и ҂ҀĐĩйОваĐŊĐ¸Ņ ĐŋĐž ĐŋаĐŧŅŅ‚Đ¸ в ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ Đ˛Đ°ŅˆĐĩĐš ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в **Kubernetes**). ĐĸаĐē ŅĐ¸ŅŅ‚ĐĩĐŧа ҁĐŧĐžĐļĐĩŅ‚ **Ņ€ĐĩĐŋĐģĐ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ** ĐŊа **Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ ĐŧĐ°ŅˆĐ¸ĐŊĐ°Ņ…**, ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ ĐžĐąŅŠŅ‘Đŧ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧОК ĐŋаĐŧŅŅ‚Đ¸ и Đ´ĐžŅŅ‚ŅƒĐŋĐŊОК ĐŋаĐŧŅŅ‚Đ¸ в ĐŧĐ°ŅˆĐ¸ĐŊĐ°Ņ… ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°. -Đ•ŅĐģи ҃ Đ˛Đ°Ņ **ĐŋŅ€ĐžŅŅ‚ĐĩĐŊҌĐēĐžĐĩ** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž ҃ Đ˛Đ°Ņ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ **ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸** ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒ Đļґҁ҂ĐēиĐĩ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐ¸Ņ ĐŊа Đ˛Ņ‹Đ´ĐĩĐģŅĐĩĐŧŅƒŅŽ ĐĩĐŧ҃ ĐŋаĐŧŅŅ‚ŅŒ. Но ĐĩҁĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŧĐŊĐžĐŗĐž ĐŋаĐŧŅŅ‚Đ¸** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŧОдĐĩĐģи **ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ**), ваĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ, ĐēаĐē ĐŧĐŊĐžĐŗĐž ĐŋаĐŧŅŅ‚Đ¸ ĐĩĐŧ҃ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ и ĐžŅ‚Ņ€ĐĩĐŗŅƒĐģĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ **ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŊа **ĐēаĐļдОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ** (ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ даĐļĐĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŧĐ°ŅˆĐ¸ĐŊ в ĐēĐģĐ°ŅŅ‚ĐĩŅ€). +Đ•ŅĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **ĐŋŅ€ĐžŅŅ‚ĐžĐĩ**, ŅŅ‚Đž, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, **ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧОК**, и Đļґҁ҂ĐēиĐĩ ĐģиĐŧĐ¸Ņ‚Ņ‹ ĐŋаĐŧŅŅ‚Đ¸ ĐŧĐžĐļĐŊĐž ĐŊĐĩ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ. Но ĐĩҁĐģи Đ˛Ņ‹ **Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐŧĐŊĐžĐŗĐž ĐŋаĐŧŅŅ‚Đ¸** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҁ ĐŧОдĐĩĐģŅĐŧи **ĐœĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ**), ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, ҁĐēĐžĐģҌĐēĐž ĐŋаĐŧŅŅ‚Đ¸ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩŅ‚ŅŅ, и ĐžŅ‚Ņ€ĐĩĐŗŅƒĐģĐ¸Ņ€ŅƒĐšŅ‚Đĩ **Ņ‡Đ¸ŅĐģĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ĐŊа **ĐēаĐļдОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ** (и, вОСĐŧĐžĐļĐŊĐž, Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ ĐŧĐ°ŅˆĐ¸ĐŊŅ‹ в ĐēĐģĐ°ŅŅ‚ĐĩŅ€). -Đ•ŅĐģи Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ**, Ņ‚Đž Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ ŅƒĐ˛ĐĩŅ€ĐĩĐŊŅ‹, Ņ‡Ņ‚Đž ŅŅ‚Đ¸ ĐŋŅ€ĐžŅ†Đĩҁҁҋ ĐŊĐĩ **СаКĐŧŅƒŅ‚ ĐŋаĐŧŅŅ‚Đ¸ йОĐģҌ҈Đĩ**, ҇ĐĩĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐž Đ´ĐģŅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. +Đ•ŅĐģи Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ**, ĐŊ҃ĐļĐŊĐž ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž Đ¸Ņ… ҁ҃ĐŧĐŧĐ°Ņ€ĐŊĐžĐĩ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģĐĩĐŊиĐĩ **ĐŊĐĩ ĐŋŅ€ĐĩĐ˛Ņ‹ŅĐ¸Ņ‚ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅƒŅŽ ĐŋаĐŧŅŅ‚ŅŒ**. -## ĐŸĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ +## ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ и ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ { #previous-steps-before-starting-and-containers } -Đ•ŅŅ‚ŅŒ два ĐžŅĐŊОвĐŊҋ҅ ĐŋĐžĐ´Ņ…ĐžĐ´Đ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ (Docker, Kubernetes и Ņ‚.Đŋ.). +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Docker, Kubernetes), ĐĩŅŅ‚ŅŒ два ĐžŅĐŊОвĐŊҋ҅ ĐŋĐžĐ´Ņ…ĐžĐ´Đ°. -### МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ +### НĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ { #multiple-containers } -ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, в ĐēаĐļĐ´ĐžĐŧ иС ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ **Kubernetes**), ĐŧĐžĐļĐĩŅ‚ вОСĐŊиĐēĐŊŅƒŅ‚ŅŒ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚ŅŒ иĐŧĐĩŅ‚ŅŒ **ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛Đ¸Ņ‚ **ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ** ĐžŅŅ‚Đ°ĐģҌĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€Đ¸ĐŧĐĩĐŊŅĐĩŅ‚ ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đ¸ Đē йаСĐĩ даĐŊĐŊҋ҅). +Đ•ŅĐģи ҃ Đ˛Đ°Ņ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, и, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐēаĐļĐ´Ņ‹Đš СаĐŋ҃ҁĐēаĐĩŅ‚ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ **Kubernetes**), Ņ‚Đž Đ˛Ņ‹, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ **ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**, Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅŽŅ‰Đ¸Đš **ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸** в ОдĐŊĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ и ОдĐŊĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ **Đ´Đž** СаĐŋ҃ҁĐēа Ņ€ĐĩĐŋĐģĐ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛-Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии Kubernetes, ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ИĐŊĐ¸Ņ†Đ¸Đ°ĐģĐ¸ĐˇĐ¸Ņ€ŅƒŅŽŅ‰Đ¸Đš ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€. +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Kubernetes, ŅŅ‚Đž, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐąŅƒĐ´ĐĩŅ‚ Init Container. /// -ĐŸŅ€Đ¸ ĐžŅ‚ŅŅƒŅ‚ŅŅ‚Đ˛Đ¸Đ¸ Ņ‚Đ°ĐēОК ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ (Đ´ĐžĐŋŅƒŅŅ‚Đ¸Đŧ, ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐŋŅ€Đ¸ĐŧĐĩĐŊŅŅ‚ŅŒ ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đ¸ Đē йаСĐĩ даĐŊĐŊҋ҅, а Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž ĐžĐŊа ĐŗĐžŅ‚ĐžĐ˛Đ° ĐŋŅ€Đ¸ĐŊиĐŧĐ°Ņ‚ŅŒ ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ), Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ˛ĐžĐ´Đ¸Ņ‚ŅŒ Ņ‚Đ°ĐēŅƒŅŽ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ в ĐēаĐļĐ´ĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐĩĐŗĐž ĐžŅĐŊОвĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° и СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ **ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž**. +Đ•ŅĐģи в Đ˛Đ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŊĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ ҁ Ņ‚ĐĩĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŅ‚ŅŒ ŅŅ‚Đ¸ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ **ĐŧĐŊĐžĐŗĐžĐēŅ€Đ°Ņ‚ĐŊĐž и ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŊĐĩ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐŧĐ¸ĐŗŅ€Đ°Ņ†Đ¸Đ¸ БД, а Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚Đĩ ĐŗĐžŅ‚ĐžĐ˛ĐŊĐžŅŅ‚ŅŒ БД), Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžŅŅ‚Đž Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ Đ¸Ņ… в ĐēаĐļĐ´ĐžĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐŋŅ€ŅĐŧĐž ĐŋĐĩŅ€ĐĩĐ´ ŅŅ‚Đ°Ņ€Ņ‚ĐžĐŧ ĐžŅĐŊОвĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°. -### ĐĸĐžĐģҌĐēĐž ОдиĐŊ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ +### ОдиĐŊ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ { #single-container } -Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐŊĐĩҁĐģĐžĐļĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž **ОдĐŊĐžĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°**, ĐŊĐž в ĐēĐžŅ‚ĐžŅ€ĐžĐŧ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** (иĐģи ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ), Ņ‚Đž ĐŋŅ€ĐžŅ…ĐžĐļĐ´ĐĩĐŊиĐĩ ĐŋŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ŅˆĐ°ĐŗĐžĐ˛ ĐŧĐžĐļĐŊĐž ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛Đ¸Ņ‚ŅŒ в ŅŅ‚ĐžĐŧ ĐļĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ Đ´Đž СаĐŋ҃ҁĐēа ĐžŅĐŊОвĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°. ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ Ņ‚Đ°ĐēиĐĩ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ. +Đ•ŅĐģи ҃ Đ˛Đ°Ņ ĐŋŅ€ĐžŅŅ‚Đ°Ņ ҁ҅ĐĩĐŧа ҁ **ОдĐŊиĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐŧ**, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐˇĐ°Ņ‚ĐĩĐŧ СаĐŋ҃ҁĐēаĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž **Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛** (иĐģи ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ), ĐŧĐžĐļĐŊĐž Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ в ŅŅ‚ĐžĐŧ ĐļĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. -## ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ ҁ Gunicorn и Uvicorn +### Đ‘Đ°ĐˇĐžĐ˛Ņ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ { #base-docker-image } -Đ¯ ĐŋĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Đģ Đ´ĐģŅ Đ˛Đ°Ņ Docker-ĐžĐąŅ€Đ°Đˇ, в ĐēĐžŅ‚ĐžŅ€Ņ‹Đš вĐēĐģŅŽŅ‡Ņ‘ĐŊ Gunicorn ҃ĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‰Đ¸Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи (Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи) Uvicorn, в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đ¸ ҁ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸ŅĐŧи Ņ€Đ°ŅŅĐŧĐžŅ‚Ņ€ĐĩĐŊĐŊŅ‹Đŧи в ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐš ĐŗĐģавĐĩ: [Đ Đ°ĐąĐžŅ‡Đ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° (Đ˛ĐžŅ€ĐēĐĩҀҋ) - Gunicorn ŅĐžĐ˛ĐŧĐĩҁ҂ĐŊĐž ҁ Uvicorn](server-workers.md){.internal-link target=_blank}. +РаĐŊĐĩĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Đģ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ FastAPI: tiangolo/uvicorn-gunicorn-fastapi. ĐĄĐĩĐšŅ‡Đ°Ņ ĐžĐŊ ĐŋĐžĐŧĐĩ҇ĐĩĐŊ ĐēаĐē ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐ¸Đš. â›”ī¸ -Đ­Ņ‚ĐžŅ‚ ĐžĐąŅ€Đ°Đˇ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐĩĐŊ Đ´ĐģŅ ŅĐ¸Ņ‚ŅƒĐ°Ņ†Đ¸Đš ĐžĐŋĐ¸ŅĐ°ĐŊĐŊҋ҅ Ņ‚ŅƒŅ‚: [МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° Đ´ĐģŅ ĐžŅĐžĐąŅ‹Ņ… ҁĐģŅƒŅ‡Đ°Đĩв](#_11). +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ваĐŧ **ĐŊĐĩ ŅŅ‚ĐžĐ¸Ņ‚** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐąĐ°ĐˇĐžĐ˛Ņ‹Đš ĐžĐąŅ€Đ°Đˇ (иĐģи ĐēаĐēОК-ĐģийО аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đš). -* tiangolo/uvicorn-gunicorn-fastapi. +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **Kubernetes** (иĐģи Đ´Ņ€ŅƒĐŗĐžĐĩ) и ҃ĐļĐĩ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩŅ‚Đĩ **Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ŅŽ** ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ° ҇ĐĩŅ€ĐĩС ĐŊĐĩҁĐēĐžĐģҌĐēĐž **ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**, в ŅŅ‚Đ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐģŅƒŅ‡ŅˆĐĩ **ŅĐžĐąŅ€Đ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Đˇ ҁ ĐŊ҃ĐģŅ**, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž Đ˛Ņ‹ŅˆĐĩ: [ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ FastAPI](#build-a-docker-image-for-fastapi). -/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ +А ĐĩҁĐģи ваĐŧ ĐŊ҃ĐļĐŊŅ‹ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛, ĐŋŅ€ĐžŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐžĐŋŅ†Đ¸ŅŽ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--workers`. -ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž ҃ Đ˛Đ°Ņ **ĐŊĐĩŅ‚ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸** в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ŅŅ‚ĐžĐŗĐž ĐžĐąŅ€Đ°ĐˇĐ° иĐģи ĐŋОдОйĐŊĐžĐŗĐž ĐĩĐŧ҃ и ĐģŅƒŅ‡ŅˆĐĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ŅĐ˛ĐžĐš ĐžĐąŅ€Đ°Đˇ ҁ ĐŊ҃ĐģŅ ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž Ņ‚ŅƒŅ‚: [ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ FastAPI](#docker-fastapi). +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐžŅŅ‚Đ¸ + +Đ­Ņ‚ĐžŅ‚ Docker-ĐžĐąŅ€Đ°Đˇ ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ в Ņ‚Đž Đ˛Ņ€ĐĩĐŧŅ, ĐēĐžĐŗĐ´Đ° Uvicorn ĐŊĐĩ ҃ĐŧĐĩĐģ ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ÂĢ҃ĐŋĐ°Đ˛ŅˆĐ¸Ņ…Âģ Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛, и ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸ĐģĐžŅŅŒ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Gunicorn вĐŧĐĩҁ҂Đĩ ҁ Uvicorn, Ņ‡Ņ‚Đž дОйавĐģŅĐģĐž СаĐŧĐĩŅ‚ĐŊŅƒŅŽ ҁĐģĐžĐļĐŊĐžŅŅ‚ŅŒ, ĐģĐ¸ŅˆŅŒ ĐąŅ‹ Gunicorn ҃ĐŋŅ€Đ°Đ˛ĐģŅĐģ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēаĐģ Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ Uvicorn. + +Но Ņ‚ĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° Uvicorn (и ĐēĐžĐŧаĐŊда `fastapi`) ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ `--workers`, ĐŊĐĩŅ‚ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐąĐ°ĐˇĐžĐ˛Ņ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ вĐŧĐĩŅŅ‚Đž ŅĐąĐžŅ€Đēи ŅĐ˛ĐžĐĩĐŗĐž (ĐēОда ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ŅŅ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž ŅŅ‚ĐžĐģҌĐēĐž ĐļĐĩ 😅). /// -В ŅŅ‚ĐžĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ ĐĩŅŅ‚ŅŒ **Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиК** ĐŧĐĩŅ…Đ°ĐŊиСĐŧ ĐŋĐžĐ´ŅŅ‚Ņ€ĐžĐšĐēи Đ´ĐģŅ СаĐŋ҃ҁĐēа **ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžĐŗĐž ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đ¸ ҁ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đŧ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ ŅĐ´ĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°. +## Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° { #deploy-the-container-image } -В ĐŊŅ‘Đŧ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊŅ‹ **Ņ€Đ°ĐˇŅƒĐŧĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ**, ĐŊĐž ĐŧĐžĐļĐŊĐž иСĐŧĐĩĐŊŅŅ‚ŅŒ и ОйĐŊОвĐģŅŅ‚ŅŒ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸ŅŽ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ** иĐģи ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊҋ҅ Ņ„Đ°ĐšĐģОв. - -ОĐŊ Ņ‚Đ°ĐēĐļĐĩ ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ ĐŋŅ€ĐžŅ…ĐžĐļĐ´ĐĩĐŊиĐĩ **ĐŸĐžĐ´ĐŗĐžŅ‚ĐžĐ˛Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ŅˆĐ°ĐŗĐžĐ˛ ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** ĐŋŅ€Đ¸ ĐŋĐžĐŧĐžŅ‰Đ¸ ҁĐēŅ€Đ¸ĐŋŅ‚Đ°. - -/// tip | ĐŸĐžĐ´ŅĐēаСĐēа - -ДĐģŅ ĐŋŅ€ĐžŅĐŧĐžŅ‚Ņ€Đ° Đ˛ŅĐĩŅ… вОСĐŧĐžĐļĐŊҋ҅ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē ĐŋĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ ĐŊа ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņƒ ŅŅ‚ĐžĐŗĐž Docker-ĐžĐąŅ€Đ°ĐˇĐ°: tiangolo/uvicorn-gunicorn-fastapi. - -/// - -### КоĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ в ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ Docker-ĐžĐąŅ€Đ°ĐˇĐĩ - -**КоĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛** в ŅŅ‚ĐžĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ **Đ˛Ņ‹Ņ‡Đ¸ŅĐģŅĐĩŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи** и ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐžĐŗĐž ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đ° **ŅĐ´ĐĩŅ€** ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°. - -Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ĐžĐŊ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ **Đ˛Ņ‹ĐļĐ°Ņ‚ŅŒ** иС ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ° ĐēаĐē ĐŧĐžĐļĐŊĐž йОĐģҌ҈Đĩ **ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸**. - -Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иСĐŧĐĩĐŊŅŅ‚ŅŒ и ОйĐŊОвĐģŅŅ‚ŅŒ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸ŅŽ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ** и Ņ‚.Đŋ. - -ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€Đ°, ĐŊа ĐēĐžŅ‚ĐžŅ€ĐžĐŧ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€, **ĐžĐąŅŠŅ‘Đŧ ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩĐŧОК ĐŋаĐŧŅŅ‚Đ¸** Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐˇĐ°Đ˛Đ¸ŅĐĩŅ‚ŅŒ ĐžŅ‚ ŅŅ‚ĐžĐŗĐž. - -А СĐŊĐ°Ņ‡Đ¸Ņ‚, ĐĩҁĐģи Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ ĐŧĐŊĐžĐŗĐž ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐžĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŧОдĐĩĐģи ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ) и Đ’Đ°Ņˆ ҁĐĩŅ€Đ˛ĐĩŅ€ иĐŧĐĩĐĩŅ‚ ҆ĐĩĐŊŅ‚Ņ€Đ°ĐģҌĐŊŅ‹Đš ĐŋŅ€ĐžŅ†ĐĩŅŅĐžŅ€ ҁ йОĐģŅŒŅˆĐ¸Đŧ ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ ŅĐ´ĐĩŅ€, ĐŊĐž **ĐŊĐĩ ҁĐģĐ¸ŅˆĐēĐžĐŧ йОĐģŅŒŅˆĐ¸Đŧ ĐžĐąŅŠŅ‘ĐŧĐžĐŧ ĐžĐŋĐĩŅ€Đ°Ņ‚Đ¸Đ˛ĐŊОК ĐŋаĐŧŅŅ‚Đ¸**, Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ Đ´ĐžĐšŅ‚Đ¸ Đ´Đž Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ ĐŋĐžĐŋŅ‹Ņ‚Đ°ĐĩŅ‚ŅŅ СаĐŊŅŅ‚ŅŒ ĐŋаĐŧŅŅ‚Đ¸ йОĐģҌ҈Đĩ, ҇ĐĩĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐŊĐž, иС-Са ҇ĐĩĐŗĐž ĐąŅƒĐ´ĐĩŅ‚ ĐŋадĐĩĐŊиĐĩ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ (иĐģи ҁĐĩŅ€Đ˛ĐĩŅ€ Đ˛ĐžĐ˛ŅĐĩ ҃ĐŋĐ°Đ´Ņ‘Ņ‚). 🚨 - - -### НаĐŋĐ¸ŅĐ°ĐŊиĐĩ `Dockerfile` - -Đ˜Ņ‚Đ°Đē, Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐŧŅ‹ ĐŧĐžĐļĐĩĐŧ ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ `Dockerfile` ĐžŅĐŊОваĐŊĐŊŅ‹Đš ĐŊа ŅŅ‚ĐžĐŧ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŧ Docker-ĐžĐąŅ€Đ°ĐˇĐĩ: - -```Dockerfile -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt - -COPY ./app /app -``` - -### БоĐģŅŒŅˆĐ¸Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ - -Đ•ŅĐģи Đ˛Ņ‹ ҃ҁĐŋĐĩĐģи ОСĐŊаĐēĐžĐŧĐ¸Ņ‚ŅŒŅŅ ҁ Ņ€Đ°ĐˇĐ´ĐĩĐģĐžĐŧ [ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đĩ ĐŧĐŊĐžĐŗĐž Ņ„Đ°ĐšĐģОв](../tutorial/bigger-applications.md){.internal-link target=_blank}, ŅĐžŅŅ‚ĐžŅŅ‰Đ¸Đĩ иС ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° Ņ„Đ°ĐšĐģОв, Đ’Đ°Ņˆ Dockerfile ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: - -```Dockerfile hl_lines="7" -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt - -COPY ./app /app/app -``` - -### КаĐē иĐŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ - -Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **Kubernetes** (иĐģи Ņ‡Ņ‚Đž-Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ Ņ‚ĐžĐŗĐž), ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž ваĐŧ **ĐŊĐĩ ĐŊ҃ĐļĐŊĐž** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš Docker-ĐžĐąŅ€Đ°Đˇ (иĐģи Đ´Ņ€ŅƒĐŗĐžĐš ĐŋĐžŅ…ĐžĐļиК) в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊĐžĐ˛Ņ‹, Ņ‚Đ°Đē ĐēаĐē ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ **ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛ĐžĐŧ СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛** Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐŊĐž ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đ°. В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐģŅƒŅ‡ŅˆĐĩ **ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Đˇ ҁ ĐŊ҃ĐģŅ**, ĐēаĐē ĐžĐŋĐ¸ŅĐ°ĐŊĐž в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ [Docker-ĐžĐąŅ€Đ°Đˇ Đ´ĐģŅ FastAPI](#docker-fastapi). - -ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐĩĐŊ в ĐžŅ‚Đ´ĐĩĐģҌĐŊҋ҅ ҁĐģŅƒŅ‡Đ°ŅŅ…, ĐžĐŋĐ¸ŅĐ°ĐŊĐŊҋ҅ Đ˛Ņ‹ŅˆĐĩ в Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ [МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ вĐŊŅƒŅ‚Ņ€Đ¸ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° Đ´ĐģŅ ĐžŅĐžĐąŅ‹Ņ… ҁĐģŅƒŅ‡Đ°Đĩв](#_11). НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž ĐŋŅ€ĐžŅŅ‚ĐžĐĩ**, ĐŊĐĩ ҂ҀĐĩĐąŅƒĐĩŅ‚ СаĐŋ҃ҁĐēа в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ и ҁĐŋĐžŅĐžĐąĐŊĐž ҃ĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒŅŅ в ОдиĐŊ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€, Ņ‚Đž ĐĩĐŗĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐąŅƒĐ´ŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ дОвОĐģҌĐŊĐž Ņ…ĐžŅ€ĐžŅˆĐž. ИĐģи ĐļĐĩ Đ˛Ņ‹ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐĩĐŗĐž ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **Docker Compose**, Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚Đĩ ĐŊа ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ и Ņ‚. Đ´ - -## Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° - -ĐŸĐžŅĐģĐĩ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐžĐąŅ€Đ°ĐˇĐ° ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҁĐŋĐžŅĐžĐąĐžĐ˛ ĐĩĐŗĐž Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ. +ĐŸĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž ĐēаĐē ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° (Docker), ĐĩĐŗĐž ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧи ҁĐŋĐžŅĐžĐąĐ°Đŧи. НаĐŋŅ€Đ¸ĐŧĐĩŅ€: -* ĐĄ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ **Docker Compose** ĐŋŅ€Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊии ĐŊа ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ -* ĐĄ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ **Kubernetes** в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ -* ĐĄ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ€ĐĩĐļиĐŧа Docker Swarm в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ -* ĐĄ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Đ´Ņ€ŅƒĐŗĐ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛, Ņ‚Đ°ĐēĐ¸Ņ… ĐēаĐē Nomad -* ĐĄ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛Đ¸ŅĐ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Ņ€Đ°ĐˇĐ˛ĐžŅ€Đ°Ņ‡Đ¸Đ˛Đ°ĐŊиĐĩĐŧ Đ˛Đ°ŅˆĐĩĐŗĐž ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° +* ĐĄ **Docker Compose** ĐŊа ОдĐŊĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ +* В ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ **Kubernetes** +* В ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ Docker Swarm Mode +* ĐĄ Đ´Ņ€ŅƒĐŗĐ¸Đŧ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Nomad +* ĐĄ ОйĐģĐ°Ņ‡ĐŊŅ‹Đŧ ҁĐĩŅ€Đ˛Đ¸ŅĐžĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ Đ˛Đ°Ņˆ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° и Ņ€Đ°ĐˇĐ˛ĐžŅ€Đ°Ņ‡Đ¸Đ˛Đ°ĐĩŅ‚ ĐĩĐŗĐž -## Docker-ĐžĐąŅ€Đ°Đˇ и Poetry +## Docker-ĐžĐąŅ€Đ°Đˇ ҁ `uv` { #docker-image-with-uv } -Đ•ŅĐģи Đ˛Ņ‹ ĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ĐĩҁҌ Poetry Đ´ĐģŅ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€ĐžĐĩĐēŅ‚Đ°, Ņ‚Đž ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŧĐŊĐžĐŗĐžŅŅ‚Đ°ĐŋĐŊŅƒŅŽ ŅĐąĐžŅ€Đē҃ ĐžĐąŅ€Đ°ĐˇĐ°: +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ uv Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи и ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐŧ, ҁĐģĐĩĐ´ŅƒĐšŅ‚Đĩ Đ¸Ņ… Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Ņƒ ĐŋĐž Docker Đ´ĐģŅ uv. -```{ .dockerfile .annotate } -# (1) -FROM python:3.9 as requirements-stage +## Đ ĐĩĐˇŅŽĐŧĐĩ { #recap } -# (2) -WORKDIR /tmp +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, **Docker** и **Kubernetes**), дОвОĐģҌĐŊĐž ĐŋŅ€ĐžŅŅ‚Đž СаĐēŅ€Ņ‹Ņ‚ŅŒ Đ˛ŅĐĩ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ**: -# (3) -RUN pip install poetry +* HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ -# (4) -COPY ./pyproject.toml ./poetry.lock* /tmp/ +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв Đ˛Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŊĐĩ ĐˇĐ°Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐēОК-ĐģийО ĐąĐ°ĐˇĐžĐ˛Ņ‹Đš ĐžĐąŅ€Đ°Đˇ, а вĐŧĐĩŅŅ‚Đž ŅŅ‚ĐžĐŗĐž **ŅĐžĐąĐĩҀґ҂Đĩ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ҁ ĐŊ҃ĐģŅ** ĐŊа ĐžŅĐŊОвĐĩ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŗĐž Docker-ĐžĐąŅ€Đ°ĐˇĐ° Python. -# (5) -RUN poetry export -f requirements.txt --output requirements.txt --without-hashes - -# (6) -FROM python:3.9 - -# (7) -WORKDIR /code - -# (8) -COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt - -# (9) -RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt - -# (10) -COPY ./app /code/app - -# (11) -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] -``` - -1. Đ­Ņ‚Đž ĐŋĐĩŅ€Đ˛Ņ‹Đš ŅŅ‚Đ°Đŋ, ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ ĐŧŅ‹ дадиĐŧ иĐŧŅ `requirements-stage`. - -2. ĐŖŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `/tmp` в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Ņ€Đ°ĐąĐžŅ‡ĐĩĐš Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸. - - В ĐŊĐĩĐš ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐˇĐ´Đ°ĐŊ Ņ„Đ°ĐšĐģ `requirements.txt` - -3. На ŅŅ‚ĐžĐŧ ŅˆĐ°ĐŗĐĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ Poetry. - -4. ĐĄĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ Ņ„Đ°ĐšĐģŅ‹ `pyproject.toml` и `poetry.lock` в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `/tmp`. - - ĐŸĐžŅĐēĐžĐģҌĐē҃ ĐŊаСваĐŊиĐĩ Ņ„Đ°ĐšĐģа ĐŊаĐŋĐ¸ŅĐ°ĐŊĐž ĐēаĐē `./poetry.lock*` (ҁ `*` в ĐēĐžĐŊ҆Đĩ), Ņ‚Đž ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩ ҁĐģĐžĐŧаĐĩŅ‚ŅŅ, ĐĩҁĐģи Ņ‚Đ°ĐēОК Ņ„Đ°ĐšĐģ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŊаКдĐĩĐŊ. - -5. ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `requirements.txt`. - -6. Đ­Ņ‚Đž Đ˛Ņ‚ĐžŅ€ĐžĐš (и ĐŋĐžŅĐģĐĩĐ´ĐŊиК) ŅŅ‚Đ°Đŋ ŅĐąĐžŅ€Đēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš и ŅĐžĐˇĐ´Đ°ŅŅ‚ ĐžĐēĐžĐŊŅ‡Đ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°. - -7. ĐŖŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `/code` в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Ņ€Đ°ĐąĐžŅ‡ĐĩĐš. - -8. ĐĄĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ Ņ„Đ°ĐšĐģ `requirements.txt` в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `/code`. - - Đ­Ņ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ в ĐžĐąŅ€Đ°ĐˇĐĩ, ŅĐžĐˇĐ´Đ°ĐŊĐŊĐžĐŧ ĐŊа ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐŧ ŅŅ‚Đ°ĐŋĐĩ, ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ ĐŧŅ‹ даĐģи иĐŧŅ requirements-stage, ĐŋĐžŅ‚ĐžĐŧ҃ ĐŋŅ€Đ¸ ĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°ĐŊии ĐŊ҃ĐļĐŊĐž ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ `--from-requirements-stage`. - -9. ĐŖŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, ҃ĐēаСаĐŊĐŊŅ‹Đĩ в Ņ„Đ°ĐšĐģĐĩ `requirements.txt`. - -10. ĐĄĐēĐžĐŋĐ¸Ņ€ŅƒĐšŅ‚Đĩ ĐŋаĐŋĐē҃ `app` в ĐŋаĐŋĐē҃ `/code`. - -11. ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ `uvicorn`, ҃ĐēаСав ĐĩĐŧ҃ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐąŅŠĐĩĐēŅ‚ `app`, Ņ€Đ°ŅĐŋĐžĐģĐžĐļĐĩĐŊĐŊŅ‹Đš в `app.main`. - -/// tip | ĐŸĐžĐ´ŅĐēаСĐēа - -Đ•ŅĐģи Ņ‚ĐēĐŊґ҂Đĩ ĐŊа ĐēŅ€ŅƒĐļĐžĐē ҁ ĐŋĐģŅŽŅĐžĐŧ, Ņ‚Đž ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ ĐžĐąŅŠŅŅĐŊĐĩĐŊĐ¸Ņ, Ņ‡Ņ‚Đž ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ в ŅŅ‚ĐžĐš ŅŅ‚Ņ€ĐžĐēĐĩ. - -/// - -**Đ­Ņ‚Đ°ĐŋŅ‹ ŅĐąĐžŅ€Đēи Docker-ĐžĐąŅ€Đ°ĐˇĐ°** ŅĐ˛ĐģŅŅŽŅ‚ŅŅ Ņ‡Đ°ŅŅ‚ŅŒŅŽ `Dockerfile` и Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ ĐēаĐē **Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐąŅ€Đ°ĐˇŅ‹ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛**. ОĐŊи ĐŊ҃ĐļĐŊŅ‹ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ Ņ„Đ°ĐšĐģОв, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ в даĐģҌĐŊĐĩĐšŅˆĐ¸Ņ… ŅŅ‚Đ°ĐŋĐ°Ņ…. - -ПĐĩŅ€Đ˛Ņ‹Đš ŅŅ‚Đ°Đŋ ĐąŅ‹Đģ ĐŊ҃ĐļĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ **ŅƒŅŅ‚Đ°ĐŊОвĐēи Poetry** и **ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ Ņ„Đ°ĐšĐģа `requirements.txt`**, в ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ ĐŋŅ€ĐžĐŋĐ¸ŅĐ°ĐŊŅ‹ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€ĐžĐĩĐēŅ‚Đ°, Đ˛ĐˇŅŅ‚Ņ‹Đĩ иС Ņ„Đ°ĐšĐģа `pyproject.toml`. - -На **ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐŧ ŅŅ‚Đ°ĐŋĐĩ** `pip` ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ„Đ°ĐšĐģ `requirements.txt`. - -В Đ¸Ņ‚ĐžĐŗĐžĐ˛ĐžĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒŅŅ **Ņ‚ĐžĐģҌĐēĐž ĐŋĐžŅĐģĐĩĐ´ĐŊиК ŅŅ‚Đ°Đŋ ŅĐąĐžŅ€Đēи**, ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Đĩ ŅŅ‚Đ°ĐŋŅ‹ ĐąŅƒĐ´ŅƒŅ‚ ĐžŅ‚ĐąŅ€ĐžŅˆĐĩĐŊŅ‹. - -ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии Poetry, иĐŧĐĩĐĩŅ‚ ҁĐŧҋҁĐģ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐŧĐŊĐžĐŗĐžŅŅ‚Đ°ĐŋĐŊŅƒŅŽ ŅĐąĐžŅ€Đē҃ Docker-ĐžĐąŅ€Đ°ĐˇĐ°**, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ ваĐŧ ĐŊĐĩ ĐŊ҃ĐļĐĩĐŊ Poetry и ĐĩĐŗĐž ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ в ĐžĐēĐžĐŊŅ‡Đ°Ņ‚ĐĩĐģҌĐŊĐžĐŧ ĐžĐąŅ€Đ°ĐˇĐĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°, ваĐŧ **ĐŊ҃ĐļĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž** ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš Ņ„Đ°ĐšĐģ `requirements.txt` Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐēи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€ĐžĐĩĐēŅ‚Đ°. - -А ĐŊа ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐŧ ŅŅ‚Đ°ĐŋĐĩ, ĐŋŅ€Đ¸Đ´ĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŅŅŒ ĐžĐŋĐ¸ŅĐ°ĐŊĐŊҋ҅ Ņ€Đ°ĐŊĐĩĐĩ ĐŋŅ€Đ°Đ˛Đ¸Đģ, ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ŅŅ Đ¸Ņ‚ĐžĐŗĐžĐ˛Ņ‹Đš ĐžĐąŅ€Đ°Đˇ - -### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS и Poetry - -И ҁĐŊОва ĐŋĐžĐ˛Ņ‚ĐžŅ€ŅŽŅŅŒ, ĐĩҁĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ (йаĐģаĐŊŅĐ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē ĐŊĐ°ĐŗŅ€ŅƒĐˇĐēи), Ņ‚Đ°ĐēОК ĐēаĐē Nginx иĐģи Traefik, Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ в ĐēĐžĐŧаĐŊĐ´Ņƒ СаĐŋ҃ҁĐēа ĐžĐŋŅ†Đ¸ŅŽ `--proxy-headers`: - -```Dockerfile -CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"] -``` - -## Đ ĐĩĐˇŅŽĐŧĐĩ - -ĐŸŅ€Đ¸ ĐŋĐžĐŧĐžŅ‰Đ¸ ŅĐ¸ŅŅ‚ĐĩĐŧ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ¸ĐˇĐ°Ņ†Đ¸Đ¸ (Ņ‚Đ°ĐēĐ¸Ņ…, ĐēаĐē **Docker** и **Kubernetes**), ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ дОвОĐģҌĐŊĐž ĐŋŅ€ĐžŅŅ‚Đž ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ Đ˛ŅĐĩ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ**: - -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS -* ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ПĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ - -В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ВаĐŧ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŊĐĩ ĐŊ҃ĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐēОК-ĐģийО ĐąĐ°ĐˇĐžĐ˛Ņ‹Đš ĐžĐąŅ€Đ°Đˇ, **ĐģŅƒŅ‡ŅˆĐĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Đˇ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ° ҁ ĐŊ҃ĐģŅ** ĐŊа ĐžŅĐŊОвĐĩ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊĐžĐŗĐž Docker-ĐžĐąŅ€Đ°ĐˇĐ° Python. - -ĐŸĐžĐˇĐ°ĐąĐžŅ‚Đ¸Đ˛ŅˆĐ¸ŅŅŒ Đž **ĐŋĐžŅ€ŅĐ´ĐēĐĩ ĐŊаĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ** иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Đš в `Dockerfile`, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐēŅŅˆ Docker'а**, **ĐŧиĐŊиĐŧĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Đ˛ Đ˛Ņ€ĐĩĐŧŅ ŅĐąĐžŅ€Đēи**, ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž ĐŋĐžĐ˛Ņ‹ŅĐ¸Đ˛ ŅĐ˛ĐžŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ (и ĐŊĐĩ ĐˇĐ°ŅĐēŅƒŅ‡Đ°Ņ‚ŅŒ). 😎 - -В ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžŅĐžĐąŅ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đš ĐžĐąŅ€Đ°Đˇ Docker Đ´ĐģŅ FastAPI. 🤓 +Đ—Đ°ĐąĐžŅ‚ŅŅŅŒ Đž **ĐŋĐžŅ€ŅĐ´ĐēĐĩ** иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Đš в `Dockerfile`и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ **ĐēŅŅˆ Docker**, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ **ĐŧиĐŊиĐŧĐ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ˛Ņ€ĐĩĐŧŅ ŅĐąĐžŅ€Đēи**, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐ˛Ņ‹ŅĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚Đ¸Đ˛ĐŊĐžŅŅ‚ŅŒ (и ĐŊĐĩ ҁĐēŅƒŅ‡Đ°Ņ‚ŅŒ). 😎 diff --git a/docs/ru/docs/deployment/https.md b/docs/ru/docs/deployment/https.md index d8877a9a1..05a03255e 100644 --- a/docs/ru/docs/deployment/https.md +++ b/docs/ru/docs/deployment/https.md @@ -1,207 +1,231 @@ -# Об HTTPS +# Об HTTPS { #about-https } -ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ, Ņ‡Ņ‚Đž HTTPS ŅŅ‚Đž ĐŊĐĩĐēĐ°Ņ ĐžĐŋŅ†Đ¸Ņ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐģийО "вĐēĐģŅŽŅ‡ĐĩĐŊа", ĐģийО ĐŊĐĩŅ‚. +ЛĐĩĐŗĐēĐž ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐžĐļĐ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž HTTPS — ŅŅ‚Đž Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž ĐŋŅ€ĐžŅŅ‚Đž ÂĢвĐēĐģŅŽŅ‡ĐĩĐŊĐžÂģ иĐģи ĐŊĐĩŅ‚. -Но Đ˛ŅŅ‘ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҁĐģĐžĐļĐŊĐĩĐĩ. +Но ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ Đ˛ŅŅ‘ ĐŗĐžŅ€Đ°ĐˇĐ´Đž ҁĐģĐžĐļĐŊĐĩĐĩ. -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -Đ•ŅĐģи Đ˛Ņ‹ Ņ‚ĐžŅ€ĐžĐŋĐ¸Ņ‚ĐĩҁҌ иĐģи ваĐŧ ĐŊĐĩ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊĐž, ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ ĐŊа ҁĐģĐĩĐ´ŅƒŅŽŅ‰ŅƒŅŽ ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņƒ ŅŅ‚ĐžĐŗĐž ĐŋĐžŅˆĐ°ĐŗĐžĐ˛ĐžĐŗĐž Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đ° ĐŋĐž Ņ€Đ°ĐˇĐŧĐĩ҉ĐĩĐŊĐ¸ŅŽ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Ņ… ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊҋ҅ Ņ‚ĐĩŅ…ĐŊĐžĐģĐžĐŗĐ¸Đš. +Đ•ŅĐģи Đ˛Ņ‹ Ņ‚ĐžŅ€ĐžĐŋĐ¸Ņ‚ĐĩҁҌ иĐģи ваĐŧ ŅŅ‚Đž ĐŊĐĩ ваĐļĐŊĐž, ĐŋĐĩŅ€ĐĩŅ…ĐžĐ´Đ¸Ņ‚Đĩ Đē ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ Ņ€Đ°ĐˇĐ´ĐĩĐģаĐŧ ҁ ĐŋĐžŅˆĐ°ĐŗĐžĐ˛Ņ‹Đŧи иĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸ŅĐŧи ĐŋĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ Đ˛ŅĐĩĐŗĐž Ņ€Đ°ĐˇĐŊŅ‹Đŧи ҁĐŋĐžŅĐžĐąĐ°Đŧи. /// -Đ§Ņ‚ĐžĐąŅ‹ **Đ¸ĐˇŅƒŅ‡Đ¸Ņ‚ŅŒ ĐžŅĐŊĐžĐ˛Ņ‹ HTTPS** Đ´ĐģŅ ĐēĐģиĐĩĐŊŅ‚Đ°, ĐŋĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ ĐŋĐž ҁҁҋĐģĐēĐĩ https://howhttps.works/. +Đ§Ņ‚ĐžĐąŅ‹ **Đ¸ĐˇŅƒŅ‡Đ¸Ņ‚ŅŒ ĐžŅĐŊĐžĐ˛Ņ‹ HTTPS** ҁ Ņ‚ĐžŅ‡Đēи ĐˇŅ€ĐĩĐŊĐ¸Ņ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ, ĐˇĐ°ĐŗĐģŅĐŊĐ¸Ņ‚Đĩ ĐŊа https://howhttps.works/. -ЗдĐĩҁҌ ĐļĐĩ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģĐĩĐŊŅ‹ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ **Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē** Đ´ĐžĐģĐļĐĩĐŊ иĐŧĐĩŅ‚ŅŒ в Đ˛Đ¸Đ´Ņƒ ĐŋŅ€Đ¸ Ņ€Đ°ĐˇĐŧŅ‹ŅˆĐģĐĩĐŊĐ¸ŅŅ… Ой HTTPS: +ĐĸĐĩĐŋĐĩŅ€ŅŒ, ŅĐž ŅŅ‚ĐžŅ€ĐžĐŊŅ‹ **Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа**, Đ˛ĐžŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž вĐĩ҉ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅŅ‚ĐžĐ¸Ņ‚ Đ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ в ĐŗĐžĐģОвĐĩ, Ņ€Đ°ĐˇĐŧŅ‹ŅˆĐģŅŅ Ой HTTPS: -* ĐŸŅ€ĐžŅ‚ĐžĐēĐžĐģ HTTPS ĐŋŅ€ĐĩĐ´ĐŋĐžĐģĐ°ĐŗĐ°ĐĩŅ‚, Ņ‡Ņ‚Đž **ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ** ĐŊ҃ĐļĐŊĐž **Ņ€Đ°ŅĐŋĐžĐģĐ°ĐŗĐ°Ņ‚ŅŒ "ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°Đŧи"** ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đŧи **҂ҀĐĩŅ‚ŅŒĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊОК**. - * На ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ ŅŅ‚Đ¸ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ **ĐŋŅ€Đ¸ĐžĐąŅ€ĐĩŅ‚ĐĩĐŊŅ‹** ҃ ҂ҀĐĩŅ‚ŅŒĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, а ĐŊĐĩ "ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹". -* ĐŖ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐĩŅŅ‚ŅŒ **ŅŅ€ĐžĐē ĐŗĐžĐ´ĐŊĐžŅŅ‚Đ¸**. - * ĐĄŅ€ĐžĐē ĐŗĐžĐ´ĐŊĐžŅŅ‚Đ¸ **Đ¸ŅŅ‚ĐĩĐēаĐĩŅ‚**. - * По Đ¸ŅŅ‚Đĩ҇ĐĩĐŊии ŅŅ€ĐžĐēа ĐŗĐžĐ´ĐŊĐžŅŅ‚Đ¸ Đ¸Ņ… ĐŊ҃ĐļĐŊĐž **ОйĐŊĐžĐ˛Đ¸Ņ‚ŅŒ**, Ņ‚Đž ĐĩŅŅ‚ŅŒ **ҁĐŊОва ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ** ҃ ҂ҀĐĩŅ‚ŅŒĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹. -* Đ¨Đ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ **ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа TCP**. - * ĐŸŅ€ĐžŅ‚ĐžĐēĐžĐģ TCP ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ ĐŊа ОдиĐŊ ŅƒŅ€ĐžĐ˛ĐĩĐŊҌ **ĐŊиĐļĐĩ ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTP**. - * ĐŸĐžŅŅ‚ĐžĐŧ҃ **ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ и ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ** ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ **Đ´Đž HTTP**. -* **TCP ĐŊĐĩ СĐŊаĐĩŅ‚ Đž "Đ´ĐžĐŧĐĩĐŊĐ°Ņ…"**, ĐŊĐž СĐŊаĐĩŅ‚ Ой IP-Đ°Đ´Ņ€ĐĩŅĐ°Ņ…. - * ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Đž **СаĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°ĐĩĐŧĐžĐŧ Đ´ĐžĐŧĐĩĐŊĐĩ** иСвĐģĐĩĐēаĐĩŅ‚ŅŅ иС СаĐŋŅ€ĐžŅĐ° **ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ HTTP**. -* **ĐĄĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ HTTPS** "ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ŅƒŅŽŅ‚" **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš Đ´ĐžĐŧĐĩĐŊ**, ĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ и ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ даĐŊĐŊҋ҅ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа TCP, Ņ‚Đž ĐĩŅŅ‚ŅŒ **Đ´Đž Ņ‚ĐžĐŗĐž**, ĐēаĐē ŅŅ‚Đ°ĐŊĐĩŅ‚ иСвĐĩҁ҂ĐĩĐŊ Đ´ĐžĐŧĐĩĐŊ-ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ĐĩĐģҌ даĐŊĐŊҋ҅. -* **По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ** ŅŅ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ HTTPS ĐŊа ОдиĐŊ IP-Đ°Đ´Ņ€Đĩҁ**. - * НĐĩ ваĐļĐŊĐž, ĐŊĐ°ŅĐēĐžĐģҌĐēĐž йОĐģŅŒŅˆĐžĐš ҃ Đ˛Đ°Ņ ҁĐĩŅ€Đ˛ĐĩŅ€ и ĐŊĐ°ŅĐēĐžĐģҌĐēĐž ĐŧаĐģĐĩĐŊҌĐēиĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŊа ĐŊŅ‘Đŧ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ. - * ОдĐŊаĐēĐž, ҃ ŅŅ‚ĐžĐš ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ ĐĩŅŅ‚ŅŒ **Ņ€Đĩ҈ĐĩĐŊиĐĩ**. -* ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ **Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ** ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа **TLS** (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ TCP, Ņ‚Đž ĐĩŅŅ‚ŅŒ Đ´Đž HTTP) ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧĐžĐĩ **SNI**. - * Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ SNI ĐŋОСвОĐģŅĐĩŅ‚ ОдĐŊĐžĐŧ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ (ҁ **ОдĐŊиĐŧ IP-Đ°Đ´Ņ€ĐĩŅĐžĐŧ**) иĐŧĐĩŅ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ HTTPS** и ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž HTTPS-Đ´ĐžĐŧĐĩĐŊОв/ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК**. - * Đ§Ņ‚ĐžĐąŅ‹ ŅŅ‚Đ° ĐēĐžĐŊŅŅ‚Ņ€ŅƒĐēŅ†Đ¸Ņ Ņ€Đ°ĐąĐžŅ‚Đ°Đģа, **ОдиĐŊ** ĐĩŅ‘ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ (ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа) СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ и ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đš **ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš IP-Đ°Đ´Ņ€Đĩҁ**, Đ´ĐžĐģĐļĐĩĐŊ иĐŧĐĩŅ‚ŅŒ **Đ˛ŅĐĩ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ HTTPS** Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. -* **ĐŸĐžŅĐģĐĩ** ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐ¸Ņ ĐˇĐ°Ņ‰Đ¸Ņ‰Ņ‘ĐŊĐŊĐžĐŗĐž ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ, ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģĐžĐŧ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ даĐŊĐŊҋ҅ **ĐžŅŅ‚Đ°Ņ‘Ņ‚ŅŅ HTTP**. - * Но даĐŊĐŊŅ‹Đĩ Ņ‚ĐĩĐŋĐĩŅ€ŅŒ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊŅ‹**, ĐŊĐĩҁĐŧĐžŅ‚Ņ€Ņ ĐŊа Ņ‚Đž, Ņ‡Ņ‚Đž ĐžĐŊи ĐŋĐĩŅ€ĐĩĐ´Đ°ŅŽŅ‚ŅŅ ĐŋĐž **ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ҃ HTTP**. +* ДĐģŅ HTTPS **ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ** ĐŊ҃ĐļĐŊĐž **иĐŧĐĩŅ‚ŅŒ ÂĢҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹Âģ**, ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ **҂ҀĐĩŅ‚ŅŒĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊОК**. + * Đ­Ņ‚Đ¸ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ ĐŊа ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ **ĐŋŅ€Đ¸ĐžĐąŅ€ĐĩŅ‚Đ°ŅŽŅ‚ŅŅ** ҃ ҂ҀĐĩŅ‚ŅŒĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, а ĐŊĐĩ ÂĢĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒŅŽŅ‚ŅŅÂģ. +* ĐŖ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐĩŅŅ‚ŅŒ **ŅŅ€ĐžĐē Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ**. + * ОĐŊи **Đ¸ŅŅ‚ĐĩĐēĐ°ŅŽŅ‚**. + * ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž Đ¸Ņ… ĐŊ҃ĐļĐŊĐž **ОйĐŊОвĐģŅŅ‚ŅŒ**, Ņ‚Đž ĐĩŅŅ‚ŅŒ **ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ СаĐŊОвО** ҃ ҂ҀĐĩŅ‚ŅŒĐĩĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹. +* Đ¨Đ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ TCP**. + * Đ­Ņ‚Đž ĐŊа ОдиĐŊ ŅƒŅ€ĐžĐ˛ĐĩĐŊҌ **ĐŊиĐļĐĩ HTTP**. + * ĐŸĐžŅŅ‚ĐžĐŧ҃ **ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ и ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ** ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ **Đ´Đž HTTP**. +* **TCP ĐŊĐĩ СĐŊаĐĩŅ‚ Đž ÂĢĐ´ĐžĐŧĐĩĐŊĐ°Ņ…Âģ**. ĐĸĐžĐģҌĐēĐž Ой IP-Đ°Đ´Ņ€ĐĩŅĐ°Ņ…. + * ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ Đž **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŧ Đ´ĐžĐŧĐĩĐŊĐĩ** ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ŅŅ в **даĐŊĐŊҋ҅ HTTP**. +* **HTTPS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹** ÂĢҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ŅƒŅŽŅ‚Âģ **ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš Đ´ĐžĐŧĐĩĐŊ**, ĐŊĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ и ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´ŅŅ‚ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ TCP, **Đ´Đž Ņ‚ĐžĐŗĐž ĐēаĐē** ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ иСвĐĩҁ҂ĐĩĐŊ Đ´ĐžĐŧĐĩĐŊ, ҁ ĐēĐžŅ‚ĐžŅ€Ņ‹Đŧ Đ¸Đ´Ņ‘Ņ‚ Ņ€Đ°ĐąĐžŅ‚Đ°. +* **По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ** ŅŅ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ иĐŧĐĩŅ‚ŅŒ **ĐģĐ¸ŅˆŅŒ ОдиĐŊ HTTPS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ ĐŊа ОдиĐŊ IP-Đ°Đ´Ņ€Đĩҁ**. + * НĐĩваĐļĐŊĐž, ĐŊĐ°ŅĐēĐžĐģҌĐēĐž ĐŧĐžŅ‰ĐŊŅ‹Đš ҃ Đ˛Đ°Ņ ҁĐĩŅ€Đ˛ĐĩŅ€ иĐģи ĐŊĐ°ŅĐēĐžĐģҌĐēĐž ĐŧаĐģĐĩĐŊҌĐēиĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐŊа ĐŊŅ‘Đŧ Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚. + * ОдĐŊаĐēĐž ҃ ŅŅ‚ĐžĐŗĐž ĐĩŅŅ‚ŅŒ **Ņ€Đĩ҈ĐĩĐŊиĐĩ**. +* Đ•ŅŅ‚ŅŒ **Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ** ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа **TLS** (Ņ‚ĐžĐŗĐž ŅĐ°ĐŧĐžĐŗĐž, Ņ‡Ņ‚Đž СаĐŊиĐŧаĐĩŅ‚ŅŅ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩĐŧ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ TCP, Đ´Đž HTTP) ĐŋОд ĐŊаСваĐŊиĐĩĐŧ **SNI**. + * Đ­Ņ‚Đž Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ SNI ĐŋОСвОĐģŅĐĩŅ‚ ОдĐŊĐžĐŧ҃ ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ (ҁ **ОдĐŊиĐŧ IP-Đ°Đ´Ņ€ĐĩŅĐžĐŧ**) иĐŧĐĩŅ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž HTTPS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛** и ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž HTTPS-Đ´ĐžĐŧĐĩĐŊОв/ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК**. + * Đ§Ņ‚ĐžĐąŅ‹ ŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐģĐž, **ОдиĐŊ** ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ (ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа), СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅ‹Đš ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ и ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đš **ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš IP-Đ°Đ´Ņ€Đĩҁ**, Đ´ĐžĐģĐļĐĩĐŊ иĐŧĐĩŅ‚ŅŒ **Đ˛ŅĐĩ HTTPS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹** ĐŊа ŅŅ‚ĐžĐŧ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ. +* **ĐŸĐžŅĐģĐĩ** ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐ¸Ņ ĐˇĐ°Ņ‰Đ¸Ņ‰Ņ‘ĐŊĐŊĐžĐŗĐž ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ, ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ ОйĐŧĐĩĐŊа даĐŊĐŊŅ‹Đŧи — **Đ˛ŅŅ‘ Đĩ҉ґ HTTP**. + * ХОдĐĩŅ€ĐļиĐŧĐžĐĩ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐž**, ĐŊĐĩҁĐŧĐžŅ‚Ņ€Ņ ĐŊа Ņ‚Đž, Ņ‡Ņ‚Đž ĐžĐŊĐž ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ ĐŋĐž **ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ҃ HTTP**. -ĐžĐąŅ‹Ņ‡ĐŊОК ĐŋŅ€Đ°ĐēŅ‚Đ¸ĐēОК ŅĐ˛ĐģŅĐĩŅ‚ŅŅ иĐŧĐĩŅ‚ŅŒ **ОдĐŊ҃ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃/HTTP-ҁĐĩŅ€Đ˛ĐĩŅ€** СаĐŋŅƒŅ‰ĐĩĐŊĐŊŅƒŅŽ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (ĐŧĐ°ŅˆĐ¸ĐŊĐĩ, Ņ…ĐžŅŅ‚Đĩ и Ņ‚.Đ´.) и **ĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ĐĩĐŊĐŊŅƒŅŽ Са Đ˛ŅŅŽ Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ HTTPS**: +ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (ĐŧĐ°ŅˆĐ¸ĐŊĐĩ, Ņ…ĐžŅŅ‚Đĩ и Ņ‚.Đŋ.) СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ **ОдĐŊ҃ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃/HTTPâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€**, ĐēĐžŅ‚ĐžŅ€Đ°Ņ **҃ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ Đ˛ŅĐĩĐš Ņ‡Đ°ŅŅ‚ŅŒŅŽ, ŅĐ˛ŅĐˇĐ°ĐŊĐŊОК ҁ HTTPS**: ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ HTTPS-СаĐŋŅ€ĐžŅŅ‹**, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ **Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ HTTP-СаĐŋŅ€ĐžŅŅ‹** в ŅĐ°ĐŧĐž HTTP‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰ĐĩĐĩ ĐŊа Ņ‚ĐžĐŧ ĐļĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI**), ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ **HTTP-ĐžŅ‚Đ˛ĐĩŅ‚** ĐžŅ‚ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, **ŅˆĐ¸Ņ„Ņ€ŅƒĐĩŅ‚ ĐĩĐŗĐž** ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰ĐĩĐŗĐž **HTTPSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°** и ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ ĐēĐģиĐĩĐŊŅ‚Ņƒ ĐŋĐž **HTTPS**. ĐĸаĐēОК ҁĐĩŅ€Đ˛ĐĩŅ€ Ņ‡Đ°ŅŅ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸**. -* ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ HTTPS-СаĐŋŅ€ĐžŅĐžĐ˛** -* ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēа **Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ HTTP СаĐŋŅ€ĐžŅĐžĐ˛** в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ĐĩĐĩ HTTP-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰ĐĩĐĩ ĐŊа Ņ‚ĐžĐŧ ĐļĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ, ŅŅ‚Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI**) -* ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ **HTTP-ĐžŅ‚Đ˛ĐĩŅ‚Đ°** ĐžŅ‚ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* **ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰Đ¸Đš **ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ HTTPS** -* ĐžŅ‚ĐŋŅ€Đ°Đ˛Đēа ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž **HTTPS-ĐžŅ‚Đ˛ĐĩŅ‚Đ° ĐēĐģиĐĩĐŊŅ‚Ņƒ**. -ĐĸаĐēОК ҁĐĩŅ€Đ˛ĐĩŅ€ Ņ‡Đ°ŅŅ‚Đž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **ĐŸŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ TLS** иĐģи ĐŋŅ€ĐžŅŅ‚Đž "ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€". +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ°Ņ€Đ¸Đ°ĐŊ҂ҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēаĐē ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸: -Đ’ĐžŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Đ°Ņ€Đ¸Đ°ĐŊ҂ҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Ņ‚Đ°ĐēĐžĐŗĐž ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°: - -* Traefik (ĐŧĐžĐļĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹) -* Caddy (ĐŧĐžĐļĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹) +* Traefik (҃ĐŧĐĩĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹) +* Caddy (҃ĐŧĐĩĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹) * Nginx * HAProxy -## Let's Encrypt (҆ĐĩĐŊ҂Ҁ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸) +## Let's Encrypt { #lets-encrypt } -До ĐŋĐžŅĐ˛ĐģĐĩĐŊĐ¸Ņ Let's Encrypt **ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ HTTPS** ĐŋŅ€Đ¸Ņ…ĐžĐ´Đ¸ĐģĐžŅŅŒ ĐŋĐžĐē҃ĐŋĐ°Ņ‚ŅŒ ҃ ҂ҀĐĩŅ‚ŅŒĐ¸Ņ… ŅŅ‚ĐžŅ€ĐžĐŊ. +До ĐŋĐžŅĐ˛ĐģĐĩĐŊĐ¸Ņ Let's Encrypt ŅŅ‚Đ¸ **HTTPS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹** ĐŋŅ€ĐžĐ´Đ°Đ˛Đ°ĐģĐ¸ŅŅŒ дОвĐĩŅ€ĐĩĐŊĐŊŅ‹Đŧи ҂ҀĐĩŅ‚ŅŒĐ¸Đŧи ŅŅ‚ĐžŅ€ĐžĐŊаĐŧи. -ĐŸŅ€ĐžŅ†Đĩҁҁ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ Ņ‚Đ°ĐēĐžĐŗĐž ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ° ĐąŅ‹Đģ Ņ‚Ņ€ŅƒĐ´ĐžŅ‘ĐŧĐēиĐŧ, ҂ҀĐĩйОваĐģ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐŋĐžĐ´Ņ‚Đ˛ĐĩŅ€ĐļĐ´Đ°ŅŽŅ‰Đ¸Ņ… Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚ĐžĐ˛ и ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ ŅŅ‚ĐžĐ¸Đģи Đ´ĐžŅ€ĐžĐŗĐž. +ĐŸŅ€ĐžŅ†Đĩҁҁ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ Ņ‚Đ°ĐēĐ¸Ņ… ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐąŅ‹Đģ ĐŊĐĩŅƒĐ´ĐžĐąĐŊŅ‹Đŧ, ҂ҀĐĩйОваĐģ ĐąŅƒĐŧаĐļĐŊОК вОĐģĐžĐēĐ¸Ņ‚Ņ‹, а ŅĐ°Đŧи ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ ĐąŅ‹Đģи дОвОĐģҌĐŊĐž Đ´ĐžŅ€ĐžĐŗĐ¸Đŧи. -Но ĐˇĐ°Ņ‚ĐĩĐŧ ĐēĐžĐŊŅĐžŅ€Ņ†Đ¸ŅƒĐŧĐžĐŧ Linux Foundation ĐąŅ‹Đģ ŅĐžĐˇĐ´Đ°ĐŊ ĐŋŅ€ĐžĐĩĐēŅ‚ **Let's Encrypt**. +Đ—Đ°Ņ‚ĐĩĐŧ ĐŋĐžŅĐ˛Đ¸ĐģŅŅ **Let's Encrypt**. -ОĐŊ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ **ĐąĐĩҁĐŋĐģĐ°Ņ‚ĐŊŅ‹Đĩ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ HTTPS**. Đ­Ņ‚Đ¸ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ Đ˛ŅĐĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ ĐēŅ€Đ¸ĐŋŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Ņ‡ĐĩҁĐēиĐĩ ҁĐŋĐžŅĐžĐąŅ‹ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ. ОĐŊи иĐŧĐĩŅŽŅ‚ ĐŊĐĩйОĐģŅŒŅˆĐžĐš ŅŅ€ĐžĐē ĐŗĐžĐ´ĐŊĐžŅŅ‚Đ¸ (ĐžĐēĐžĐģĐž 3 ĐŧĐĩŅŅŅ†Đĩв), ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ҇ĐĩĐŧ҃ ĐžĐŊи даĐļĐĩ **йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊŅ‹**. +Đ­Ņ‚Đž ĐŋŅ€ĐžĐĩĐēŅ‚ Linux Foundation. ОĐŊ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ **HTTPSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ ĐąĐĩҁĐŋĐģĐ°Ņ‚ĐŊĐž**, в Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŧ Ņ€ĐĩĐļиĐŧĐĩ. Đ­Ņ‚Đ¸ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ ĐēŅ€Đ¸ĐŋŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Ņ‡ĐĩҁĐēиĐĩ ĐŧĐĩŅ…Đ°ĐŊиСĐŧŅ‹ и иĐŧĐĩŅŽŅ‚ ĐēĐžŅ€ĐžŅ‚ĐēиК ŅŅ€ĐžĐē Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ (ĐžĐēĐžĐģĐž 3 ĐŧĐĩŅŅŅ†Đĩв), ĐŋĐžŅŅ‚ĐžĐŧ҃ **ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ Ņ„Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи Đ˛Ņ‹ŅˆĐĩ** ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ҃ĐŧĐĩĐŊҌ҈ĐĩĐŊĐŊĐžĐŧ҃ ŅŅ€ĐžĐē҃ ĐļиСĐŊи. -ĐŸŅ€Đ¸ СаĐŋŅ€ĐžŅĐĩ ĐŊа ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°, ĐžĐŊ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ŅŅ и Đ´ĐžĐŧĐĩĐŊ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚ŅŅ ĐŊа ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ. Đ­Ņ‚Đž ĐŋОСвОĐģŅĐĩŅ‚ ОйĐŊОвĐģŅŅ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи. +ДоĐŧĐĩĐŊŅ‹ ĐąĐĩСОĐŋĐ°ŅĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅŽŅ‚ŅŅ, а ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ Đ˛Ņ‹Đ´Đ°ŅŽŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи. Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ĐŋОСвОĐģŅĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ĐžŅ†Đĩҁҁ Đ¸Ņ… ĐŋŅ€ĐžĐ´ĐģĐĩĐŊĐ¸Ņ. -ĐĄŅƒŅ‚ŅŒ идĐĩи в Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŧ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊии и ОйĐŊОвĐģĐĩĐŊии ŅŅ‚Đ¸Ņ… ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ŅĐĩ ĐŧĐžĐŗĐģи ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ **ĐąĐĩСОĐŋĐ°ŅĐŊŅ‹Đŧ HTTPS. БĐĩҁĐŋĐģĐ°Ņ‚ĐŊĐž. В ĐģŅŽĐąĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ.** +ИдĐĩŅ — Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊиĐĩ и ĐŋŅ€ĐžĐ´ĐģĐĩĐŊиĐĩ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ Đ˛Đ°Ņ ĐąŅ‹Đģ **ĐąĐĩСОĐŋĐ°ŅĐŊŅ‹Đš HTTPS, ĐąĐĩҁĐŋĐģĐ°Ņ‚ĐŊĐž и ĐŊĐ°Đ˛ŅĐĩĐŗĐ´Đ°**. -## HTTPS Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв +## HTTPS Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв { #https-for-developers } -НиĐļĐĩ, ŅˆĐ°Đŗ Са ŅˆĐ°ĐŗĐžĐŧ, ҁ ĐˇĐ°ĐžŅŅ‚Ņ€ĐĩĐŊиĐĩĐŧ вĐŊиĐŧаĐŊĐ¸Ņ ĐŊа идĐĩŅŅ…, ваĐļĐŊҋ҅ Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа, ĐžĐŋĐ¸ŅĐ°ĐŊĐž, ĐēаĐē ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ HTTPS API. +НиĐļĐĩ ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņ‘ĐŊ ĐŋŅ€Đ¸ĐŧĐĩŅ€ Ņ‚ĐžĐŗĐž, ĐēаĐē ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ HTTPS‑API, ŅˆĐ°Đŗ Са ŅˆĐ°ĐŗĐžĐŧ, ҁ аĐē҆ĐĩĐŊŅ‚ĐžĐŧ ĐŊа идĐĩŅŅ…, ваĐļĐŊҋ҅ Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв. -### ИĐŧŅ Đ´ĐžĐŧĐĩĐŊа +### ИĐŧŅ Đ´ĐžĐŧĐĩĐŊа { #domain-name } -Đ§Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž, Đ˛ŅŅ‘ ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚ŅŅ ҁ **ĐŋŅ€Đ¸ĐžĐąŅ€ĐĩŅ‚ĐĩĐŊĐ¸Ņ иĐŧĐĩĐŊи Đ´ĐžĐŧĐĩĐŊа**. Đ—Đ°Ņ‚ĐĩĐŧ ĐŊ҃ĐļĐŊĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ DNS-ҁĐĩŅ€Đ˛ĐĩŅ€ (вĐĩŅ€ĐžŅŅ‚ĐŊĐž ҃ Ņ‚ĐžĐŗĐž ĐļĐĩ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹Đ´Đ°Đģ ваĐŧ Đ´ĐžĐŧĐĩĐŊ). +Đ§Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž Đ˛ŅŅ‘ ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚ŅŅ ҁ **ĐŋŅ€Đ¸ĐžĐąŅ€ĐĩŅ‚ĐĩĐŊĐ¸Ņ** **иĐŧĐĩĐŊи Đ´ĐžĐŧĐĩĐŊа**. Đ—Đ°Ņ‚ĐĩĐŧ Đ˛Ņ‹ ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩŅ‚Đĩ ĐĩĐŗĐž ĐŊа DNSâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đĩ (вОСĐŧĐžĐļĐŊĐž, ҃ Ņ‚ĐžĐŗĐž ĐļĐĩ ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°). -ДаĐģĐĩĐĩ, вОСĐŧĐžĐļĐŊĐž, Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ "ОйĐģĐ°Ņ‡ĐŊŅ‹Đš" ҁĐĩŅ€Đ˛ĐĩŅ€ (Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅƒŅŽ ĐŧĐ°ŅˆĐ¸ĐŊ҃) иĐģи Ņ‡Ņ‚Đž-Ņ‚Đž Ņ‚Đ¸Đŋа ŅŅ‚ĐžĐŗĐž, ҃ ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ĐĩŅŅ‚ŅŒ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊŅ‹Đš **ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš IP-Đ°Đ´Ņ€Đĩҁ**. +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ОйĐģĐ°Ņ‡ĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€ (Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊŅƒŅŽ ĐŧĐ°ŅˆĐ¸ĐŊ҃) иĐģи Ņ‡Ņ‚Đž-Ņ‚Đž ĐŋОдОйĐŊĐžĐĩ, и ҃ ĐŊĐĩĐŗĐž ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊŅ‹Đš **ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš IP-Đ°Đ´Ņ€Đĩҁ**. -На DNS-ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Ņ…) ваĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ŅƒŅŽ Ņ€ĐĩŅŅƒŅ€ŅĐŊŅƒŅŽ СаĐŋĐ¸ŅŅŒ ("`СаĐŋĐ¸ŅŅŒ A`"), ҃ĐēаСав, Ņ‡Ņ‚Đž **Đ’Đ°Ņˆ Đ´ĐžĐŧĐĩĐŊ** ŅĐ˛ŅĐˇĐ°ĐŊ ҁ ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đŧ **IP-Đ°Đ´Ņ€ĐĩŅĐžĐŧ Đ˛Đ°ŅˆĐĩĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°**. +На DNSâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đĩ(Đ°Ņ…) Đ˛Ņ‹ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚Đĩ СаĐŋĐ¸ŅŅŒ (ÂĢ`A record`Âģ - СаĐŋĐ¸ŅŅŒ Ņ‚Đ¸Đŋа A), ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‰ŅƒŅŽ, Ņ‡Ņ‚Đž **Đ˛Đ°Ņˆ Đ´ĐžĐŧĐĩĐŊ** Đ´ĐžĐģĐļĐĩĐŊ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ĐŊа ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš **IPâ€‘Đ°Đ´Ņ€Đĩҁ Đ˛Đ°ŅˆĐĩĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°**. -ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚Ņƒ СаĐŋĐ¸ŅŅŒ Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ ОдиĐŊ Ņ€Đ°Đˇ, ĐŋŅ€Đ¸ ĐŋĐĩŅ€Đ˛ĐžĐŊĐ°Ņ‡Đ°ĐģҌĐŊОК ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ Đ˛ŅĐĩĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. +ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚Đž Đ´ĐĩĐģаĐĩŅ‚ŅŅ ОдиĐŊ Ņ€Đ°Đˇ — ĐŋŅ€Đ¸ ĐŋĐĩŅ€Đ˛ĐžĐŊĐ°Ņ‡Đ°ĐģҌĐŊОК ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ Đ˛ŅĐĩĐŗĐž. -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -ĐŖŅ€ĐžĐ˛ĐŊи ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģОв, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ҁ иĐŧĐĩĐŊаĐŧи Đ´ĐžĐŧĐĩĐŊОв, ĐŊаĐŧĐŊĐžĐŗĐž ĐŊиĐļĐĩ HTTPS, ĐŊĐž Ой ŅŅ‚ĐžĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚ŅŒ СдĐĩҁҌ, Ņ‚Đ°Đē ĐēаĐē Đ˛ŅŅ‘ ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ Đ´ĐžĐŧĐĩĐŊОв и IP-Đ°Đ´Ņ€ĐĩŅĐžĐ˛. +Đ§Đ°ŅŅ‚ŅŒ ĐŋŅ€Đž Đ´ĐžĐŧĐĩĐŊĐŊĐžĐĩ иĐŧŅ ĐžŅ‚ĐŊĐžŅĐ¸Ņ‚ŅŅ Đē ŅŅ‚Đ°ĐŋаĐŧ СадОĐģĐŗĐž Đ´Đž HTTPS, ĐŊĐž Ņ‚Đ°Đē ĐēаĐē Đ˛ŅŅ‘ ĐˇĐ°Đ˛Đ¸ŅĐ¸Ņ‚ ĐžŅ‚ Đ´ĐžĐŧĐĩĐŊа и IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ°, СдĐĩҁҌ ŅŅ‚ĐžĐ¸Ņ‚ ŅŅ‚Đž ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚ŅŒ. /// -### DNS +### DNS { #dns } -ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ ŅŅ„ĐžĐēŅƒŅĐ¸Ņ€ŅƒĐĩĐŧŅŅ ĐŊа Ņ€Đ°ĐąĐžŅ‚Đĩ ҁ HTTPS. +ĐĸĐĩĐŋĐĩŅ€ŅŒ ŅŅ„ĐžĐēŅƒŅĐ¸Ņ€ŅƒĐĩĐŧŅŅ ĐŊа ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐž Ņ‡Đ°ŅŅ‚ŅŅ…, ŅĐ˛ŅĐˇĐ°ĐŊĐŊҋ҅ ҁ HTTPS. -Đ’ŅŅ‘ ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚ŅŅ ҁ Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ҁĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°ĐĩŅ‚ ҃ **DNS-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛**, ĐēаĐēОК **IP-Đ°Đ´Ņ€Đĩҁ ŅĐ˛ŅĐˇĐ°ĐŊ ҁ Đ´ĐžĐŧĐĩĐŊĐžĐŧ**, Đ´ĐģŅ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ° Đ˛ĐžĐˇŅŒĐŧŅ‘Đŧ Đ´ĐžĐŧĐĩĐŊ `someapp.example.com`. +ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ҁĐŋŅ€ĐžŅĐ¸Ņ‚ ҃ **DNSâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛**, ĐēаĐēОК **IP ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒĐĩŅ‚ Đ´ĐžĐŧĐĩĐŊ҃**, в ĐŊĐ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ `someapp.example.com`. -DNS-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐŋŅ€Đ¸ŅŅ‹ĐģĐ°ŅŽŅ‚ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Ņƒ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš **IP-Đ°Đ´Ņ€Đĩҁ**, Ņ‚ĐžŅ‚ ŅĐ°ĐŧŅ‹Đš ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš IP-Đ°Đ´Ņ€Đĩҁ Đ˛Đ°ŅˆĐĩĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ҃ĐēаСаĐģи в Ņ€ĐĩŅŅƒŅ€ŅĐŊОК "СаĐŋĐ¸ŅĐ¸ А" ĐŋŅ€Đ¸ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐĩ. +DNSâ€‘ŅĐĩŅ€Đ˛ĐĩҀҋ ĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Ņƒ, ĐēаĐēОК **ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš IPâ€‘Đ°Đ´Ņ€Đĩҁ** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ. Đ­Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš IPâ€‘Đ°Đ´Ņ€Đĩҁ Đ˛Đ°ŅˆĐĩĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ˛Ņ‹ ҃ĐēаСаĐģи в ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐ°Ņ… DNS. -### Đ ŅƒĐēĐžĐŋĐžĐļĐ°Ņ‚Đ¸Đĩ TLS +### ĐĐ°Ņ‡Đ°ĐģĐž TLS-Ņ€ŅƒĐēĐžĐŋĐžĐļĐ°Ņ‚Đ¸Ņ { #tls-handshake-start } -В даĐģҌĐŊĐĩĐšŅˆĐĩĐŧ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ĐąŅƒĐ´ĐĩŅ‚ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ ŅŅ‚Đ¸Đŧ IP-Đ°Đ´Ņ€ĐĩŅĐžĐŧ ҇ĐĩŅ€ĐĩС **port 443** (ĐžĐąŅ‰ĐĩĐŋŅ€Đ¸ĐŊŅŅ‚Ņ‹Đš ĐŊĐžĐŧĐĩŅ€ ĐŋĐžŅ€Ņ‚Đ° Đ´ĐģŅ HTTPS). +ДаĐģĐĩĐĩ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅ‰Đ°Ņ‚ŅŒŅŅ ҁ ŅŅ‚Đ¸Đŧ IPâ€‘Đ°Đ´Ņ€ĐĩŅĐžĐŧ ĐŊа **ĐŋĐžŅ€Ņ‚Ņƒ 443** (ĐŋĐžŅ€Ņ‚ HTTPS). -ПĐĩŅ€Đ˛Ņ‹Đŧ ŅˆĐ°ĐŗĐžĐŧ ĐąŅƒĐ´ĐĩŅ‚ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊиĐĩ ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ ĐŧĐĩĐļĐ´Ņƒ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ (ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ĐžĐŧ) и ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ и Đ˛Ņ‹ĐąĐžŅ€ ĐēŅ€Đ¸ĐŋŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Ņ‡ĐĩҁĐēĐžĐŗĐž ĐēĐģŅŽŅ‡Đ° (Đ´ĐģŅ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ). +ПĐĩŅ€Đ˛Đ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ — ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ ĐŧĐĩĐļĐ´Ņƒ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ и ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ и Đ´ĐžĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ŅŒŅŅ Đž ĐēŅ€Đ¸ĐŋŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… ĐēĐģŅŽŅ‡Đ°Ņ… и Ņ‚.Đŋ. -Đ­Ņ‚Đ° Ņ‡Đ°ŅŅ‚ŅŒ ĐēĐģиĐĩĐŊŅ‚-ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊĐžĐŗĐž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Ņ ŅƒŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚ TLS-ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ и ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ **TLS-Ņ€ŅƒĐēĐžĐŋĐžĐļĐ°Ņ‚Đ¸ĐĩĐŧ**. +Đ­Ņ‚Đž вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸Đĩ ĐēĐģиĐĩĐŊŅ‚Đ° и ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐ¸Ņ TLSâ€‘ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ **TLSâ€‘Ņ€ŅƒĐēĐžĐŋĐžĐļĐ°Ņ‚Đ¸ĐĩĐŧ**. -### TLS ҁ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩĐŧ SNI +### TLS ҁ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩĐŧ SNI { #tls-with-sni-extension } -На ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** ĐŧĐžĐļĐĩŅ‚ ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš **ĐŋĐžŅ€Ņ‚** ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊĐžĐŗĐž **IP-Đ°Đ´Ņ€ĐĩŅĐ°**. На ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ, ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋĐžŅ€Ņ‚Ņ‹ ŅŅ‚ĐžĐŗĐž ĐļĐĩ IP-Đ°Đ´Ņ€ĐĩŅĐ°, ĐŊĐž ĐŊиĐēаĐēОК ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŊĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€Đ¸Đ˛ŅĐˇĐ°ĐŊ Đē ҃ĐļĐĩ СаĐŊŅŅ‚ĐžĐš ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸Đ¸ IP-Đ°Đ´Ņ€Đĩҁ:ĐŋĐžŅ€Ņ‚. Đ­Ņ‚Đ° ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸Ņ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ "ŅĐžĐēĐĩŅ‚". +На ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ **Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ** ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš **ĐŋĐžŅ€Ņ‚** ĐŊа ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŧ **IPâ€‘Đ°Đ´Ņ€ĐĩҁĐĩ**. ĐœĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ, ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋĐžŅ€Ņ‚Ņ‹ ĐŊа Ņ‚ĐžĐŧ ĐļĐĩ IPâ€‘Đ°Đ´Ņ€ĐĩҁĐĩ, ĐŊĐž ĐŊĐĩ йОĐģĐĩĐĩ ОдĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° ĐŊа ĐēаĐļĐ´ŅƒŅŽ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ŅŽ IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ° и ĐŋĐžŅ€Ņ‚Đ°. -По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ TLS (HTTPS) Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŋĐžŅ€Ņ‚ `443`. ĐŸĐžŅ‚ĐžĐŧ҃ ŅŅ‚ĐžŅ‚ ĐļĐĩ ĐŋĐžŅ€Ņ‚ ĐąŅƒĐ´ĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ и ĐŧŅ‹. +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ TLS (HTTPS) Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŋĐžŅ€Ņ‚ `443`. ЗĐŊĐ°Ņ‡Đ¸Ņ‚, ĐžĐŊ ĐŊаĐŧ и ĐŊ҃ĐļĐĩĐŊ. -И Ņ€Đ°Đˇ ҃Đļ Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐŋĐžŅ€Ņ‚, Ņ‚Đž ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐžŅ†Đĩҁҁ **ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ TLS**. +ĐĸаĐē ĐēаĐē Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐŋĐžŅ€Ņ‚, Đ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ **ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸**. -ĐŸŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ Ņ€Đ°ĐąĐžŅ‚Ņ‹ TLS ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋ Đē ОдĐŊĐžĐŧ҃ иĐģи ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧ **TLS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°Đŧ** (ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ HTTPS). +ĐŖ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đ° TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ ĐąŅƒĐ´ĐĩŅ‚ Đ´ĐžŅŅ‚ŅƒĐŋ Đē ОдĐŊĐžĐŧ҃ иĐģи ĐŊĐĩҁĐēĐžĐģҌĐēиĐŧ **TLSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°Đŧ** (HTTPSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°Đŧ). -Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ **Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ SNI** ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚ĐžĐĩ Đ˛Ņ‹ŅˆĐĩ, ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ иС иĐŧĐĩŅŽŅ‰Đ¸Ņ…ŅŅ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ TLS (HTTPS) Đ˛Ņ‹ĐąĐĩŅ€ĐĩŅ‚ Ņ‚ĐžŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒĐĩŅ‚ иĐŧĐĩĐŊи Đ´ĐžĐŧĐĩĐŊа, ҃ĐēаСаĐŊĐŊĐžĐŧ҃ в СаĐŋŅ€ĐžŅĐĩ ĐžŅ‚ ĐēĐģиĐĩĐŊŅ‚Đ°. +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ **Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ SNI**, ҃ĐŋĐžĐŧŅĐŊŅƒŅ‚ĐžĐĩ Đ˛Ņ‹ŅˆĐĩ, ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚, ĐēаĐēОК иС Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ TLS (HTTPS)â€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐŊ҃ĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ, Đ˛Ņ‹ĐąŅ€Đ°Đ˛ Ņ‚ĐžŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒĐĩŅ‚ Đ´ĐžĐŧĐĩĐŊ҃, ĐžĐļидаĐĩĐŧĐžĐŧ҃ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ. -ĐĸĐž ĐĩŅŅ‚ŅŒ ĐąŅƒĐ´ĐĩŅ‚ Đ˛Ņ‹ĐąŅ€Đ°ĐŊ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ Đ´ĐģŅ Đ´ĐžĐŧĐĩĐŊа `someapp.example.com`. +В ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ŅŅ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ Đ´ĐģŅ `someapp.example.com`. -КĐģиĐĩĐŊŅ‚ ҃ĐļĐĩ **дОвĐĩŅ€ŅĐĩŅ‚** Ņ‚ĐžĐŧ҃, ĐēŅ‚Đž Đ˛Ņ‹Đ´Đ°Đģ ŅŅ‚ĐžŅ‚ TLS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ (в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ - Let's Encrypt, ĐŊĐž ĐŧŅ‹ Đĩ҉ґ ĐžĐąŅŅƒĐ´Đ¸Đŧ ŅŅ‚Đž), ĐŋĐžŅ‚ĐžĐŧ҃ ĐŧĐžĐļĐĩŅ‚ **ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ**, Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģĐĩĐŊ Đģи ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đš ĐžŅ‚ ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚. +КĐģиĐĩĐŊŅ‚ ҃ĐļĐĩ **дОвĐĩŅ€ŅĐĩŅ‚** ĐžŅ€ĐŗĐ°ĐŊĐ¸ĐˇĐ°Ņ†Đ¸Đ¸, Đ˛Ņ‹Đ´Đ°Đ˛ŅˆĐĩĐš ŅŅ‚ĐžŅ‚ TLSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ (в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ — Let's Encrypt, ĐŊĐž Ой ŅŅ‚ĐžĐŧ ĐŋОСĐļĐĩ), ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŧĐžĐļĐĩŅ‚ **ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ**, Ņ‡Ņ‚Đž ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģĐĩĐŊ. -Đ—Đ°Ņ‚ĐĩĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ŅŅ‚ĐžŅ‚ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚, ĐēĐģиĐĩĐŊŅ‚ и ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ **Đ˛Ņ‹ĐąĐ¸Ņ€Đ°ŅŽŅ‚ ҁĐŋĐžŅĐžĐą ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ** даĐŊĐŊҋ҅ Đ´ĐģŅ ŅƒŅŅ‚Đ°ĐŊавĐģиваĐĩĐŧĐžĐŗĐž **TCP-ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ**. На ŅŅ‚ĐžĐŧ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ **TLS-Ņ€ŅƒĐēĐžĐŋĐžĐļĐ°Ņ‚Đ¸Ņ** СавĐĩŅ€ŅˆĐĩĐŊа. +Đ—Đ°Ņ‚ĐĩĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚, ĐēĐģиĐĩĐŊŅ‚ и ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ **Đ´ĐžĐŗĐžĐ˛Đ°Ņ€Đ¸Đ˛Đ°ŅŽŅ‚ŅŅ Đž ҁĐŋĐžŅĐžĐąĐĩ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ** ĐžŅŅ‚Đ°ĐģҌĐŊОК **TCP‑ĐēĐžĐŧĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Đ¸**. На ŅŅ‚ĐžĐŧ **TLSâ€‘Ņ€ŅƒĐēĐžĐŋĐžĐļĐ°Ņ‚Đ¸Đĩ** СавĐĩŅ€ŅˆĐĩĐŊĐž. -В даĐģҌĐŊĐĩĐšŅˆĐĩĐŧ ĐēĐģиĐĩĐŊŅ‚ и ҁĐĩŅ€Đ˛ĐĩŅ€ ĐąŅƒĐ´ŅƒŅ‚ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐž **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŧ҃ TCP-ŅĐžĐĩдиĐŊĐĩĐŊĐ¸ŅŽ**, ĐēаĐē ĐŋŅ€ĐĩĐ´ĐģĐ°ĐŗĐ°ĐĩŅ‚ŅŅ в ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģĐĩ TLS. И ĐŊа ĐžŅĐŊОвĐĩ ŅŅ‚ĐžĐŗĐž TCP-ŅĐžĐĩĐ´ĐĩĐŊиĐŊĐ¸Ņ ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐˇĐ´Đ°ĐŊĐž **HTTP-ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ**. +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ҃ ĐēĐģиĐĩĐŊŅ‚Đ° и ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐĩŅŅ‚ŅŒ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ TCPâ€‘ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ** — ŅŅ‚Đž и ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ TLS. И ĐžĐŊи ĐŧĐžĐŗŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đž ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊĐ°Ņ‡Đ°Ņ‚ŅŒ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐž **HTTP‑обĐŧĐĩĐŊ**. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, **HTTPS** ŅŅ‚Đž Ņ‚ĐžŅ‚ ĐļĐĩ **HTTP**, ĐŊĐž вĐŊŅƒŅ‚Ņ€Đ¸ **ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž TLS-ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ** вĐŧĐĩŅŅ‚Đž Ņ‡Đ¸ŅŅ‚ĐžĐŗĐž (ĐŊĐĩĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž) TCP-ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ. +ĐĄĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐž, **HTTPS** — ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš **HTTP** вĐŊŅƒŅ‚Ņ€Đ¸ **ĐˇĐ°Ņ‰Đ¸Ņ‰Ņ‘ĐŊĐŊĐžĐŗĐž TLSâ€‘ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ**, вĐŧĐĩŅŅ‚Đž Ņ‡Đ¸ŅŅ‚ĐžĐŗĐž (ĐŊĐĩĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž) TCPâ€‘ŅĐžĐĩдиĐŊĐĩĐŊĐ¸Ņ. -/// tip | ЗаĐŧĐĩŅ‚Đēа +/// tip | ХОвĐĩŅ‚ -ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ TCP**, а ĐŊĐĩ ĐŊа йОĐģĐĩĐĩ Đ˛Ņ‹ŅĐžĐēĐžĐŧ ŅƒŅ€ĐžĐ˛ĐŊĐĩ HTTP. +ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ОйĐŧĐĩĐŊа ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŊа **ŅƒŅ€ĐžĐ˛ĐŊĐĩ TCP**, а ĐŊĐĩ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ HTTP. /// -### HTTPS-СаĐŋŅ€ĐžŅ +### HTTPS‑заĐŋŅ€ĐžŅ { #https-request } -ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° ĐŧĐĩĐļĐ´Ņƒ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ и ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ (в ĐŊĐ°ŅˆĐĩĐŧ ҁĐģŅƒŅ‡Đ°Đĩ, ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ĐžĐŧ и ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ) ŅĐžĐˇĐ´Đ°ĐŊĐž **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ TCP-ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ**, ĐžĐŊи ĐŧĐžĐŗŅƒŅ‚ ĐŊĐ°Ņ‡Đ°Ņ‚ŅŒ **ОйĐŧĐĩĐŊ даĐŊĐŊŅ‹Đŧи ĐŋĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ҃ HTTP**. +ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐēĐžĐŗĐ´Đ° ҃ ĐēĐģиĐĩĐŊŅ‚Đ° и ҁĐĩŅ€Đ˛ĐĩŅ€Đ° (ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐž ҃ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ° и ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đ° TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸) ĐĩŅŅ‚ŅŒ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ TCPâ€‘ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ**, ĐžĐŊи ĐŧĐžĐŗŅƒŅ‚ ĐŊĐ°Ņ‡Đ°Ņ‚ŅŒ **HTTP‑обĐŧĐĩĐŊ**. -ĐĸаĐē ĐēĐģиĐĩĐŊŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ **HTTPS-СаĐŋŅ€ĐžŅ**. ĐĸĐž ĐĩŅŅ‚ŅŒ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš HTTP-СаĐŋŅ€ĐžŅ, ĐŊĐž ҇ĐĩŅ€ĐĩС ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ TLS-ŅĐžĐ´Đ¸ĐŊĐĩĐŊиĐĩ. +КĐģиĐĩĐŊŅ‚ ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚ **HTTPS‑заĐŋŅ€ĐžŅ**. Đ­Ņ‚Đž ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš HTTP‑заĐŋŅ€ĐžŅ ҇ĐĩŅ€ĐĩС ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊĐžĐĩ TLSâ€‘ŅĐžĐĩдиĐŊĐĩĐŊиĐĩ. -### Đ Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đēа СаĐŋŅ€ĐžŅĐ° +### Đ Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đēа СаĐŋŅ€ĐžŅĐ° { #decrypt-the-request } -ĐŸŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ŅĐžĐŗĐģĐ°ŅĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ҁ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ ĐēĐģŅŽŅ‡, Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ŅƒĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đš **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš СаĐŋŅ€ĐžŅ** и ĐŋĐĩŅ€ĐĩĐ´Đ°ŅŅ‚ **ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš (ĐŊĐĩĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš) HTTP-СаĐŋŅ€ĐžŅ** ĐŋŅ€ĐžŅ†Đĩҁҁ҃, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰ĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžŅ†Đĩҁҁ҃ Uvicorn СаĐŋ҃ҁĐēĐ°ŅŽŅ‰ĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI). +ĐŸŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ŅĐžĐŗĐģĐ°ŅĐžĐ˛Đ°ĐŊĐŊĐžĐĩ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊиĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ **Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ**, и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‘Ņ‚ **ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš (Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš) HTTP‑заĐŋŅ€ĐžŅ** ĐŋŅ€ĐžŅ†Đĩҁҁ҃, СаĐŋ҃ҁĐēĐ°ŅŽŅ‰ĐĩĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžŅ†Đĩҁҁ҃ ҁ Uvicorn, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš СаĐŋ҃ҁĐēаĐĩŅ‚ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI). -### HTTP-ĐžŅ‚Đ˛ĐĩŅ‚ +### HTTPâ€‘ĐžŅ‚Đ˛ĐĩŅ‚ { #http-response } -ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ СаĐŋŅ€ĐžŅ и вĐĩŅ€ĐŊґ҂ **ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš (ĐŊĐĩĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš) HTTP-ĐžŅ‚Đ˛ĐĩŅ‚** ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ. +ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ СаĐŋŅ€ĐžŅ и ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ **ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš (ĐŊĐĩĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš) HTTPâ€‘ĐžŅ‚Đ˛ĐĩŅ‚** ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€Ņƒ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸. -### HTTPS-ĐžŅ‚Đ˛ĐĩŅ‚ +### HTTPSâ€‘ĐžŅ‚Đ˛ĐĩŅ‚ { #https-response } -ĐŸŅ€ĐēĐžŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ŅƒĐĩŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ€Đ°ĐŊĐĩĐĩ ŅĐžĐŗĐģĐ°ŅĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ҁ ĐēĐģиĐĩĐŊŅ‚ĐžĐŧ ҁĐŋĐžŅĐžĐą ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ (ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŅ в ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đĩ Đ´ĐģŅ Đ´ĐžĐŧĐĩĐŊа `someapp.example.com`) и ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ ĐĩĐŗĐž ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Ņƒ. +Đ—Đ°Ņ‚ĐĩĐŧ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ **ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ŅƒĐĩŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚** ҁ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩĐŧ Ņ€Đ°ĐŊĐĩĐĩ ŅĐžĐŗĐģĐ°ŅĐžĐ˛Đ°ĐŊĐŊĐžĐŗĐž ҁĐŋĐžŅĐžĐąĐ° ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŊĐ°Ņ‡Đ°Đģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐģŅ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ° Đ´ĐģŅ `someapp.example.com`) и ĐžŅ‚ĐŋŅ€Đ°Đ˛Đ¸Ņ‚ ĐĩĐŗĐž ĐžĐąŅ€Đ°Ņ‚ĐŊĐž в ĐąŅ€Đ°ŅƒĐˇĐĩŅ€. -НаĐēĐžĐŊĐĩ҆, ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ ĐžŅ‚Đ˛ĐĩŅ‚, в Ņ‚ĐžĐŧ Ņ‡Đ¸ŅĐģĐĩ, Ņ‡Ņ‚Đž Ņ‚ĐžŅ‚ ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊ ҁ ĐŊ҃ĐļĐŊŅ‹Đŧ ĐēĐģŅŽŅ‡ĐžĐŧ, **Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ŅƒĐĩŅ‚ ĐĩĐŗĐž** и ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚. +ДаĐģĐĩĐĩ ĐąŅ€Đ°ŅƒĐˇĐĩŅ€ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚, Ņ‡Ņ‚Đž ĐžŅ‚Đ˛ĐĩŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐĩĐŊ и ĐˇĐ°ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊŅ‹Đŧ ĐēŅ€Đ¸ĐŋŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Ņ‡ĐĩҁĐēиĐŧ ĐēĐģŅŽŅ‡ĐžĐŧ и Ņ‚.Đŋ., ĐˇĐ°Ņ‚ĐĩĐŧ **Ņ€Đ°ŅŅˆĐ¸Ņ„Ņ€ŅƒĐĩŅ‚ ĐžŅ‚Đ˛ĐĩŅ‚** и ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐĩĐŗĐž. -КĐģиĐĩĐŊŅ‚ (ĐąŅ€Đ°ŅƒĐˇĐĩŅ€) СĐŊаĐĩŅ‚, Ņ‡Ņ‚Đž ĐžŅ‚Đ˛ĐĩŅ‚ ĐŋŅ€Đ¸ŅˆŅ‘Đģ ĐžŅ‚ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, Ņ‚Đ°Đē ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐŧĐĩŅ‚ĐžĐ´Ņ‹ ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, ŅĐžĐŗĐģĐ°ŅĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ иĐŧи Ņ€Đ°ĐŊĐŊĐĩĐĩ ҇ĐĩŅ€ĐĩС **HTTPS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚**. +КĐģиĐĩĐŊŅ‚ (ĐąŅ€Đ°ŅƒĐˇĐĩŅ€) ŅƒĐˇĐŊаĐĩŅ‚, Ņ‡Ņ‚Đž ĐžŅ‚Đ˛ĐĩŅ‚ ĐŋŅ€Đ¸ŅˆŅ‘Đģ ĐžŅ‚ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ҁĐŋĐžŅĐžĐą ŅˆĐ¸Ņ„Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, Đž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ ĐžĐŊи Đ´ĐžĐŗĐžĐ˛ĐžŅ€Đ¸ĐģĐ¸ŅŅŒ Ņ€Đ°ĐŊĐĩĐĩ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ **HTTPSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°**. -### МĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК +### НĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК { #multiple-applications } -На ОдĐŊĐžĐŧ и Ņ‚ĐžĐŧ ĐļĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (иĐģи ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Ņ…) ĐŧĐžĐļĐŊĐž Ņ€Đ°ĐˇĐŧĐĩŅŅ‚Đ¸Ņ‚ŅŒ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ҁ API иĐģи ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅. +На ОдĐŊĐžĐŧ и Ņ‚ĐžĐŧ ĐļĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (иĐģи ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Ņ…) ĐŧĐžĐŗŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ҁ API иĐģи йаСа даĐŊĐŊҋ҅. -НаĐŋĐžĐŧĐŊŅŽ, Ņ‡Ņ‚Đž Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€) ĐŧĐžĐļĐĩŅ‚ ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš ĐŋĐžŅ€Ņ‚ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊĐžĐŗĐž IP-Đ°Đ´Ņ€ĐĩŅĐ°. -Но Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŋŅ€ĐžŅ†Đĩҁҁҋ и ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ Ņ‚ĐžĐļĐĩ ĐŧĐžĐŗŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐŊа ŅŅ‚ĐžĐŧ ĐļĐĩ ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ (ҁĐĩŅ€Đ˛ĐĩŅ€Đ°Ņ…), ĐĩҁĐģи ĐžĐŊи ĐŊĐĩ ĐŋŅ‹Ņ‚Đ°ŅŽŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҃ĐļĐĩ СаĐŊŅŅ‚ŅƒŅŽ **ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ŅŽ IP-Đ°Đ´Ņ€ĐĩŅĐ° и ĐŋĐžŅ€Ņ‚Đ°** (ŅĐžĐēĐĩŅ‚). +ĐĸĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅƒŅŽ ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ŅŽ IP и ĐŋĐžŅ€Ņ‚Đ° (в ĐŊĐ°ŅˆĐĩĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ — ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸), ĐŊĐž ĐžŅŅ‚Đ°ĐģҌĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ/ĐŋŅ€ĐžŅ†Đĩҁҁҋ Ņ‚ĐžĐļĐĩ ĐŧĐžĐŗŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ(Đ°Ņ…), ĐŋĐžĐēа ĐžĐŊи ĐŊĐĩ ĐŋŅ‹Ņ‚Đ°ŅŽŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Ņƒ ĐļĐĩ **ĐēĐžĐŧйиĐŊĐ°Ņ†Đ¸ŅŽ ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŗĐž IP и ĐŋĐžŅ€Ņ‚Đ°**. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ҁĐĩŅ€Đ˛ĐĩŅ€ СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ HTTPS-СаĐŋŅ€ĐžŅŅ‹ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ Đ´ĐģŅ **ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đ° Đ´ĐžĐŧĐĩĐŊОв** иĐģи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК и ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊŅ‹Đŧ Đ°Đ´Ņ€ĐĩŅĐ°Ņ‚Đ°Đŧ (Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧ). +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ ĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ HTTPS и ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ Đ´ĐģŅ **ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… Đ´ĐžĐŧĐĩĐŊОв** (Đ´ĐģŅ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК), а ĐˇĐ°Ņ‚ĐĩĐŧ ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ ĐŊ҃ĐļĐŊĐžĐŧ҃ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ в ĐēаĐļĐ´ĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ. -### ОбĐŊОвĐģĐĩĐŊиĐĩ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ° +### ĐŸŅ€ĐžĐ´ĐģĐĩĐŊиĐĩ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ° { #certificate-renewal } -В ĐŊĐĩдаĐģŅ‘ĐēĐžĐŧ ĐąŅƒĐ´ŅƒŅ‰ĐĩĐŧ ĐģŅŽĐąĐžĐš ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ ŅŅ‚Đ°ĐŊĐĩŅ‚ **ĐŋŅ€ĐžŅŅ€ĐžŅ‡ĐĩĐŊĐŊŅ‹Đŧ** (ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž ҇ĐĩŅ€ĐĩС Ņ‚Ņ€Đ¸ ĐŧĐĩŅŅŅ†Đ° ĐŋĐžŅĐģĐĩ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ). +ĐĄĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊĐĩĐŧ ĐēаĐļĐ´Ņ‹Đš ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ **Đ¸ŅŅ‚Đĩ҇ґ҂** (ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž ҇ĐĩŅ€ĐĩС 3 ĐŧĐĩŅŅŅ†Đ° ĐŋĐžŅĐģĐĩ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ). -ĐšĐžĐŗĐ´Đ° ŅŅ‚Đž ĐŋŅ€ĐžĐ¸ĐˇĐžĐšĐ´Ņ‘Ņ‚, ĐŧĐžĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐŋОдĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŅ Đē Let's Encrypt и ОйĐŊĐžĐ˛Đ¸Ņ‚ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚(Ņ‹). ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‚ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩҀҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐŗŅƒŅ‚ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Đĩ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž. +Đ—Đ°Ņ‚ĐĩĐŧ ĐąŅƒĐ´ĐĩŅ‚ Đ´Ņ€ŅƒĐŗĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа (иĐŊĐžĐŗĐ´Đ° ŅŅ‚Đž ĐžŅ‚Đ´ĐĩĐģҌĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, иĐŊĐžĐŗĐ´Đ° — Ņ‚ĐžŅ‚ ĐļĐĩ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸), ĐēĐžŅ‚ĐžŅ€Đ°Ņ ŅĐ˛ŅĐļĐĩŅ‚ŅŅ ҁ Let's Encrypt и ĐŋŅ€ĐžĐ´ĐģĐ¸Ņ‚ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚(Ņ‹). -**TLS-ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹** ĐŊĐĩ ĐŋŅ€Đ¸Đ˛ŅĐˇĐ°ĐŊŅ‹ Đē IP-Đ°Đ´Ņ€Đĩҁ҃, ĐŊĐž **ŅĐ˛ŅĐˇĐ°ĐŊŅ‹ ҁ иĐŧĐĩĐŊĐĩĐŧ Đ´ĐžĐŧĐĩĐŊа**. +**TLSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹** **ŅĐ˛ŅĐˇĐ°ĐŊŅ‹ ҁ иĐŧĐĩĐŊĐĩĐŧ Đ´ĐžĐŧĐĩĐŊа**, а ĐŊĐĩ ҁ IPâ€‘Đ°Đ´Ņ€ĐĩŅĐžĐŧ. -ĐĸаĐē Ņ‡Ņ‚Đž ĐŋŅ€Đ¸ ОйĐŊОвĐģĐĩĐŊии ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа Đ´ĐžĐģĐļĐŊа **ĐŋĐžĐ´Ņ‚Đ˛ĐĩŅ€Đ´Đ¸Ņ‚ŅŒ** ҆ĐĩĐŊŅ‚Ņ€Ņƒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ (Let's Encrypt), Ņ‡Ņ‚Đž ОйĐŊОвĐģĐĩĐŊиĐĩ СаĐŋŅ€ĐžŅĐ¸Đģ **"вĐģадĐĩĐģĐĩ҆", ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐēĐžĐŊŅ‚Ņ€ĐžĐģĐ¸Ņ€ŅƒĐĩŅ‚ ŅŅ‚ĐžŅ‚ Đ´ĐžĐŧĐĩĐŊ**. +ĐŸĐžŅŅ‚ĐžĐŧ҃, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐžĐ´ĐģĐ¸Ņ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹, ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐŋŅ€ĐžĐ´ĐģĐĩĐŊĐ¸Ņ Đ´ĐžĐģĐļĐŊа **Đ´ĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒ** ŅƒĐ´ĐžŅŅ‚ĐžĐ˛ĐĩŅ€ŅŅŽŅ‰ĐĩĐŧ҃ ҆ĐĩĐŊŅ‚Ņ€Ņƒ (Let's Encrypt), Ņ‡Ņ‚Đž ĐžĐŊа Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž **ÂĢвĐģадĐĩĐĩŅ‚Âģ и ĐēĐžĐŊŅ‚Ņ€ĐžĐģĐ¸Ņ€ŅƒĐĩŅ‚ ŅŅ‚ĐžŅ‚ Đ´ĐžĐŧĐĩĐŊ**. -Đ•ŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅƒŅ‚ĐĩĐš ĐžŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐģĐĩĐŊĐ¸Ņ ŅŅ‚ĐžĐŗĐž. ХаĐŧŅ‹Đĩ ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊŅ‹Đĩ иС ĐŊĐ¸Ņ…: +ДĐģŅ ŅŅ‚ĐžĐŗĐž, ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°Ņ Ņ€Đ°ĐˇĐŊŅ‹Đĩ ĐŋĐžŅ‚Ņ€ĐĩĐąĐŊĐžŅŅ‚Đ¸ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК, ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҁĐŋĐžŅĐžĐąĐžĐ˛. ПоĐŋ҃ĐģŅŅ€ĐŊŅ‹Đĩ иС ĐŊĐ¸Ņ…: -* **ИСĐŧĐĩĐŊĐĩĐŊиĐĩ СаĐŋĐ¸ŅĐĩĐš DNS**. - * ДĐģŅ Ņ‚Đ°ĐēĐžĐŗĐž Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚Đ° Đ’Đ°ŅˆĐ° ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ОйĐŊОвĐģĐĩĐŊĐ¸Ņ Đ´ĐžĐģĐļĐŊа ҃ĐŧĐĩŅ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ API DNS-ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°, ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°ŅŽŅ‰ĐĩĐŗĐž Đ’Đ°ŅˆĐ¸ DNS-СаĐŋĐ¸ŅĐ¸. НĐĩ ҃ Đ˛ŅĐĩŅ… ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ĐžĐ˛ ĐĩŅŅ‚ŅŒ Ņ‚Đ°ĐēОК API, Ņ‚Đ°Đē Ņ‡Ņ‚Đž ŅŅ‚ĐžŅ‚ ҁĐŋĐžŅĐžĐą ĐŊĐĩ Đ˛ŅĐĩĐŗĐ´Đ° ĐŋŅ€Đ¸ĐŧĐĩĐŊиĐŧ. -* **ЗаĐŋ҃ҁĐē в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°** (ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ, ĐŊа Đ˛Ņ€ĐĩĐŧŅ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛) ĐŊа ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŧ IP-Đ°Đ´Ņ€ĐĩҁĐĩ Đ´ĐžĐŧĐĩĐŊа. - * КаĐē ҃ĐļĐĩ ĐŊĐĩ Ņ€Đ°Đˇ ҃ĐŋĐžĐŧиĐŊаĐģĐžŅŅŒ, Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ĐŋŅ€ĐžŅĐģŅƒŅˆĐ¸Đ˛Đ°Ņ‚ŅŒ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš ĐŋĐžŅ€Ņ‚ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊĐžĐŗĐž IP-Đ°Đ´Ņ€ĐĩŅĐ°. - * Đ­Ņ‚Đž ОдĐŊа иС ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Đĩ҉ґ и в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛. - * В ҁĐģŅƒŅ‡Đ°Đĩ, ĐĩҁĐģи ОйĐŊОвĐģĐĩĐŊиĐĩĐŧ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ СаĐŊиĐŧаĐĩŅ‚ŅŅ Đ´Ņ€ŅƒĐŗĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, ваĐŧ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ ĐžŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€, СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐŊа ŅĐžĐēĐĩŅ‚Đĩ, ĐŋŅ€ĐĩĐ´ĐŊаСĐŊĐ°Ņ‡ĐĩĐŊĐŊĐžĐŧ Đ´ĐģŅ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°, ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŊа Ņ€Đ°ĐąĐžŅ‚Ņƒ ҁ ĐŊĐžĐ˛Ņ‹Đŧи ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Đ°Đŧи и ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐĩĐŗĐž. Đ­Ņ‚Đ° ҁ҅ĐĩĐŧа даĐģĐĩĐēа ĐžŅ‚ идĐĩаĐģҌĐŊОК, Ņ‚Đ°Đē ĐēаĐē Đ’Đ°ŅˆĐ¸ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ĐąŅƒĐ´ŅƒŅ‚ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹ ĐŊа Đ˛Ņ€ĐĩĐŧŅ ĐžŅ‚ĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ°. +* **ИСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ DNS‑заĐŋĐ¸ŅĐ¸**. + * ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐŋŅ€ĐžĐ´ĐģĐĩĐŊĐ¸Ņ Đ´ĐžĐģĐļĐŊа ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ API DNS‑ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ°, ĐŋĐžŅŅ‚ĐžĐŧ҃, в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧĐžĐŗĐž ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€Đ° DNS, ŅŅ‚ĐžŅ‚ Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋĐĩĐŊ иĐģи ĐŊĐĩŅ‚. +* **ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒŅŅ ĐēаĐē ҁĐĩŅ€Đ˛ĐĩŅ€** (ĐēаĐē ĐŧиĐŊиĐŧ҃Đŧ ĐŊа Đ˛Ņ€ĐĩĐŧŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛) ĐŊа ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŧ IPâ€‘Đ°Đ´Ņ€ĐĩҁĐĩ, ŅĐ˛ŅĐˇĐ°ĐŊĐŊĐžĐŧ ҁ Đ´ĐžĐŧĐĩĐŊĐžĐŧ. + * КаĐē ҁĐēаСаĐŊĐž Đ˛Ņ‹ŅˆĐĩ, Ņ‚ĐžĐģҌĐēĐž ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŧĐžĐļĐĩŅ‚ ҁĐģŅƒŅˆĐ°Ņ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš IP и ĐŋĐžŅ€Ņ‚. + * Đ­Ņ‚Đž ОдĐŊа иС ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊ, ĐŋĐžŅ‡ĐĩĐŧ҃ ĐžŅ‡ĐĩĐŊҌ ŅƒĐ´ĐžĐąĐŊĐž, ĐēĐžĐŗĐ´Đ° Ņ‚ĐžŅ‚ ĐļĐĩ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ Ņ‚Đ°ĐēĐļĐĩ СаĐŊиĐŧаĐĩŅ‚ŅŅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐŧ ĐŋŅ€ĐžĐ´ĐģĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛. + * В ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ваĐŧ, вОСĐŧĐžĐļĐŊĐž, ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ Đ˛Ņ€ĐĩĐŧĐĩĐŊĐŊĐž ĐžŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸, СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ ĐŋŅ€ĐžĐ´ĐģĐĩĐŊĐ¸Ņ Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛, ĐˇĐ°Ņ‚ĐĩĐŧ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ Đ¸Ņ… в ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đĩ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ и ĐŋĐĩŅ€ĐĩСаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐĩĐŗĐž. Đ­Ņ‚Đž ĐŊĐĩ идĐĩаĐģҌĐŊĐž, Ņ‚Đ°Đē ĐēаĐē Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ(Ņ) ĐąŅƒĐ´ŅƒŅ‚ ĐŊĐĩĐ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹, ĐŋĐžĐēа ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸ ĐžŅŅ‚Đ°ĐŊОвĐģĐĩĐŊ. -ВĐĩҁҌ ŅŅ‚ĐžŅ‚ ĐŋŅ€ĐžŅ†Đĩҁҁ ОйĐŊОвĐģĐĩĐŊĐ¸Ņ, ОдĐŊĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš ҁ ĐžĐąŅĐģ҃ĐļиваĐŊиĐĩĐŧ СаĐŋŅ€ĐžŅĐžĐ˛, ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ОдĐŊОК иС ĐžŅĐŊОвĐŊҋ҅ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊ, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐļĐĩĐģĐ°Ņ‚ĐĩĐģҌĐŊĐž иĐŧĐĩŅ‚ŅŒ **ĐžŅ‚Đ´ĐĩĐģҌĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ HTTPS** в видĐĩ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€Đ° СавĐĩŅ€ŅˆĐĩĐŊĐ¸Ņ TLS, а ĐŊĐĩ ĐŋŅ€ĐžŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚Ņ‹ TLS ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ҁ ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn). +ВĐĩҁҌ ŅŅ‚ĐžŅ‚ ĐŋŅ€ĐžŅ†Đĩҁҁ ĐŋŅ€ĐžĐ´ĐģĐĩĐŊĐ¸Ņ, ŅĐžĐ˛ĐŧĐĩ҉ґĐŊĐŊŅ‹Đš ҁ ĐžĐąŅĐģ҃ĐļиваĐŊиĐĩĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, — ОдĐŊа иС ĐŗĐģавĐŊҋ҅ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊ иĐŧĐĩŅ‚ŅŒ **ĐžŅ‚Đ´ĐĩĐģҌĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ HTTPS** в видĐĩ ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đ° TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸, вĐŧĐĩŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ TLSâ€‘ŅĐĩŅ€Ņ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ‚ĐžĐ˛ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ в ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn). -## Đ ĐĩĐˇŅŽĐŧĐĩ +## ПĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸ { #proxy-forwarded-headers } -НаĐģĐ¸Ņ‡Đ¸Đĩ **HTTPS** ĐžŅ‡ĐĩĐŊҌ ваĐļĐŊĐž и дОвОĐģҌĐŊĐž **ĐēŅ€Đ¸Ņ‚Đ¸Ņ‡ĐŊĐž** в йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв. ОдĐŊаĐēĐž, ВаĐŧ, ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē҃, ĐŊĐĩ ĐŊ҃ĐļĐŊĐž Ņ‚Ņ€Đ°Ņ‚Đ¸Ņ‚ŅŒ ĐŧĐŊĐžĐŗĐž ŅĐ¸Đģ ĐŊа ŅŅ‚Đž, Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž **ĐŋĐžĐŊиĐŧĐ°Ņ‚ŅŒ ŅŅ‚Đ¸ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸** и ĐŋŅ€Đ¸ĐŊŅ†Đ¸ĐŋŅ‹ Đ¸Ņ… Ņ€Đ°ĐąĐžŅ‚Ņ‹. +ĐšĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐŋŅ€ĐžĐēŅĐ¸ Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи HTTPS, Đ˛Đ°Ņˆ **ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn ҇ĐĩŅ€ĐĩС FastAPI CLI) ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩ СĐŊаĐĩŅ‚ Đž ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ HTTPS, ĐžĐŊ ĐžĐąŅ‰Đ°ĐĩŅ‚ŅŅ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧ HTTP ҁ **ĐŋŅ€ĐžĐēŅĐ¸â€‘ŅĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ TLS-Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ†Đ¸Đ¸**. -Но ŅƒĐˇĐŊав ĐąĐ°ĐˇĐžĐ˛Ņ‹Đĩ ĐžŅĐŊĐžĐ˛Ņ‹ **HTTPS** Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐģĐĩĐŗĐēĐž ŅĐžĐ˛ĐŧĐĩŅ‰Đ°Ņ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐžĐŧĐžĐŗŅƒŅ‚ ваĐŧ в даĐģҌĐŊĐĩĐšŅˆĐĩĐš Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ. +ĐžĐąŅ‹Ņ‡ĐŊĐž ŅŅ‚ĐžŅ‚ **ĐŋŅ€ĐžĐēŅĐ¸** ĐŊа ĐģĐĩŅ‚Ņƒ дОйавĐģŅĐĩŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ HTTPâ€‘ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋĐĩŅ€ĐĩĐ´ Ņ‚ĐĩĐŧ, ĐēаĐē ĐŋĐĩŅ€ĐĩҁĐģĐ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ ĐŊа **ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ**, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ‚ĐžŅ‚ СĐŊаĐģ, Ņ‡Ņ‚Đž СаĐŋŅ€ĐžŅ ĐąŅ‹Đģ **ĐŋŅ€ĐžĐēŅĐ¸Ņ€ĐžĐ˛Đ°ĐŊ**. -В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ… Ņ ĐŋĐžĐēаĐļ҃ ваĐŧ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐžĐ˛, ĐēаĐē ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°Ņ‚ŅŒ **HTTPS** Đ´ĐģŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК **FastAPI**. 🔒 +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +Đ—Đ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸: + +* X-Forwarded-For +* X-Forwarded-Proto +* X-Forwarded-Host + +/// + +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, Ņ‚Đ°Đē ĐēаĐē **ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** ĐŊĐĩ СĐŊаĐĩŅ‚, Ņ‡Ņ‚Đž ĐžĐŊ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŅ Са дОвĐĩŅ€ĐĩĐŊĐŊŅ‹Đŧ **ĐŋŅ€ĐžĐēŅĐ¸**, ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐžĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ дОвĐĩŅ€ŅŅ‚ŅŒ ŅŅ‚Đ¸Đŧ ĐˇĐ°ĐŗĐžĐģОвĐēаĐŧ. + +Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ **ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ**, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ дОвĐĩŅ€ŅĐģ *ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đŧ* ĐˇĐ°ĐŗĐžĐģОвĐēаĐŧ, ĐžŅ‚ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐŊŅ‹Đŧ **ĐŋŅ€ĐžĐēŅĐ¸**. Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI CLI, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ *ĐžĐŋŅ†Đ¸ŅŽ CLI* `--forwarded-allow-ips`, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ, ҁ ĐēаĐēĐ¸Ņ… IPâ€‘Đ°Đ´Ņ€ĐĩŅĐžĐ˛ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ дОвĐĩŅ€ŅŅ‚ŅŒ ŅŅ‚Đ¸Đŧ *ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đŧ* ĐˇĐ°ĐŗĐžĐģОвĐēаĐŧ. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи **ҁĐĩŅ€Đ˛ĐĩŅ€ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ СаĐŋŅ€ĐžŅŅ‹ Ņ‚ĐžĐģҌĐēĐž ĐžŅ‚ дОвĐĩŅ€ĐĩĐŊĐŊĐžĐŗĐž **ĐŋŅ€ĐžĐēŅĐ¸**, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ `--forwarded-allow-ips="*"`, Ņ‡Ņ‚ĐžĐąŅ‹ дОвĐĩŅ€ŅŅ‚ŅŒ Đ˛ŅĐĩĐŧ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đŧ IP, Ņ‚Đ°Đē ĐēаĐē ĐžĐŊ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅŅ‹ Ņ‚ĐžĐģҌĐēĐž ҁ IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ°, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧĐžĐŗĐž **ĐŋŅ€ĐžĐēŅĐ¸**. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁĐŧĐžĐļĐĩŅ‚ СĐŊĐ°Ņ‚ŅŒ ŅĐ˛ĐžĐš ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊŅ‹Đš URL, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Đģи ĐžĐŊĐž HTTPS, ĐēаĐēОК Đ´ĐžĐŧĐĩĐŊ и Ņ‚.Đŋ. + +Đ­Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐģĐĩСĐŊĐž, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´ĐģŅ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊОК ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи Ņ€ĐĩĐ´Đ¸Ņ€ĐĩĐēŅ‚ĐžĐ˛. + +/// tip | ХОвĐĩŅ‚ + +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Ой ŅŅ‚ĐžĐŧ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸: [За ĐŋŅ€ĐžĐēŅĐ¸ — ВĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩҁҋĐģаĐĩĐŧŅ‹Đĩ ĐˇĐ°ĐŗĐžĐģОвĐēи ĐŋŅ€ĐžĐēŅĐ¸](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} + +/// + +## Đ ĐĩĐˇŅŽĐŧĐĩ { #recap } + +НаĐģĐ¸Ņ‡Đ¸Đĩ **HTTPS** ĐžŅ‡ĐĩĐŊҌ ваĐļĐŊĐž и вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… дОвОĐģҌĐŊĐž **ĐēŅ€Đ¸Ņ‚Đ¸Ņ‡ĐŊĐž**. БоĐģŅŒŅˆĐ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ ŅƒŅĐ¸ĐģиК, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ваĐŧ, ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē҃, ĐŊ҃ĐļĐŊĐž ĐŋŅ€Đ¸ĐģĐžĐļĐ¸Ņ‚ŅŒ вОĐēŅ€ŅƒĐŗ HTTPS, — ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž **ĐŋĐžĐŊиĐŧаĐŊиĐĩ ŅŅ‚Đ¸Ņ… ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš** и Ņ‚ĐžĐŗĐž, ĐēаĐē ĐžĐŊи Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚. + +ЗĐŊĐ°Ņ ĐąĐ°ĐˇĐžĐ˛ŅƒŅŽ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Đž **HTTPS Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв**, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐģĐĩĐŗĐēĐž ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ и ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°Ņ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ĐŋŅ€Đ°Đ˛ĐģŅŅ‚ŅŒ Đ˛ŅĐĩĐŧ ŅŅ‚Đ¸Đŧ ĐŋŅ€ĐžŅŅ‚Ņ‹Đŧ ҁĐŋĐžŅĐžĐąĐžĐŧ. + +В ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… иС ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģав Ņ ĐŋĐžĐēаĐļ҃ ваĐŧ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊҋ҅ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐžĐ˛ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи **HTTPS** Đ´ĐģŅ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК **FastAPI**. 🔒 diff --git a/docs/ru/docs/deployment/index.md b/docs/ru/docs/deployment/index.md index e88ddc3e2..c85fa0d52 100644 --- a/docs/ru/docs/deployment/index.md +++ b/docs/ru/docs/deployment/index.md @@ -1,16 +1,16 @@ -# Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ +# Đ Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ { #deployment } РаСвĐĩŅ€ĐŊŅƒŅ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** дОвОĐģҌĐŊĐž ĐŋŅ€ĐžŅŅ‚Đž. -## Да Ņ‡Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ŅŅ‚Đž Đ˛Đ°ŅˆĐĩ - "Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ"?! +## Đ§Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ { #what-does-deployment-mean } ĐĸĐĩŅ€ĐŧиĐŊ **Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊиĐĩ** (ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ) ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚ Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ ŅˆĐ°ĐŗĐžĐ˛, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đŧ Đ´ĐģŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš**. -ĐžĐąŅ‹Ņ‡ĐŊĐž **вĐĩĐą-ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** Ņ€Đ°ĐˇĐŧĐĩŅ‰Đ°ŅŽŅ‚ ĐŊа ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐžĐŧ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ ҁ ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ĐĩŅ‚ Ņ…ĐžŅ€ĐžŅˆŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ, ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊĐžŅŅ‚ŅŒ и Ņ‚. Đ´., Đ§Ņ‚ĐžĐąŅ‹ Đ˛Đ°ŅˆĐ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģи ĐŧĐžĐŗĐģи ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊĐž, ĐąĐĩҁĐŋŅ€ĐĩŅ€Ņ‹Đ˛ĐŊĐž и ĐąĐĩҁĐŋŅ€ĐžĐąĐģĐĩĐŧĐŊĐž ĐžĐąŅ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ Đē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ. +ДĐģŅ **вĐĩĐą-API** ŅŅ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚ Ņ€Đ°ĐˇĐŧĐĩ҉ĐĩĐŊиĐĩ ĐĩĐŗĐž ĐŊа **ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ** ҁ **ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧОК**, ОйĐĩҁĐŋĐĩŅ‡Đ¸Đ˛Đ°ŅŽŅ‰ĐĩĐš Ņ…ĐžŅ€ĐžŅˆŅƒŅŽ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ, ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊĐžŅŅ‚ŅŒ и Ņ‚.Đ´., Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛Đ°ŅˆĐ¸ **ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģи** ĐŧĐžĐŗĐģи **ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋ** Đē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊĐž и ĐąĐĩС ĐŋĐĩŅ€ĐĩйОĐĩв иĐģи ĐŋŅ€ĐžĐąĐģĐĩĐŧ. -Đ­Ņ‚Đž ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ **Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи**, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž ĐŧĐĩĐŊŅĐĩŅ‚Đĩ ĐēОд, Đ´ĐĩĐģаĐĩŅ‚Đĩ в ĐŊŅ‘Đŧ ĐŊаĐŧĐĩŅ€ĐĩĐŊĐŊŅ‹Đĩ ĐžŅˆĐ¸ĐąĐēи и Đ¸ŅĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚Đĩ Đ¸Ņ…, ĐžŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚Đĩ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи и Ņ‚. Đ´. +Đ­Ņ‚Đž ĐžŅ‚ĐģĐ¸Ņ‡Đ°ĐĩŅ‚ŅŅ ĐžŅ‚ ŅŅ‚Đ°ĐŋОв **Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи**, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž ĐŧĐĩĐŊŅĐĩŅ‚Đĩ ĐēОд, ĐģĐžĐŧаĐĩŅ‚Đĩ ĐĩĐŗĐž и Đ¸ŅĐŋŅ€Đ°Đ˛ĐģŅĐĩŅ‚Đĩ, ĐžŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚Đĩ и ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи и Ņ‚.Đ´. -## ĐĄŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ +## ĐĄŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ { #deployment-strategies } В ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ Đ˛Đ°ŅˆĐĩĐŗĐž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊĐžĐŗĐž ҁĐģŅƒŅ‡Đ°Ņ, ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҁĐŋĐžŅĐžĐąĐžĐ˛ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚Đž. diff --git a/docs/ru/docs/deployment/manually.md b/docs/ru/docs/deployment/manually.md index 9b1d32be8..37fed5780 100644 --- a/docs/ru/docs/deployment/manually.md +++ b/docs/ru/docs/deployment/manually.md @@ -1,33 +1,82 @@ -# ЗаĐŋ҃ҁĐē ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ - Uvicorn +# ЗаĐŋ҃ҁĐē ҁĐĩŅ€Đ˛ĐĩŅ€Đ° Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ { #run-a-server-manually } -ДĐģŅ СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ **FastAPI** ĐŊа ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊОК ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ ваĐŧ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐŊŅ‹Đš ҁĐĩŅ€Đ˛ĐĩŅ€, ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‰Đ¸Đš ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ ASGI, Ņ‚Đ°ĐēОК ĐēаĐē **Uvicorn**. +## Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐēĐžĐŧаĐŊĐ´Ņƒ `fastapi run` { #use-the-fastapi-run-command } -ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ Ņ‚Ņ€Đ¸ ĐŊаийОĐģĐĩĐĩ Ņ€Đ°ŅĐŋŅ€ĐžŅŅ‚Ņ€Đ°ĐŊŅ‘ĐŊĐŊŅ‹Đĩ аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹: +ĐšĐžŅ€ĐžŅ‚ĐēĐž: Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ `fastapi run`, Ņ‡Ņ‚ĐžĐąŅ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI: -* Uvicorn: Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ASGI ҁĐĩŅ€Đ˛ĐĩŅ€. -* Hypercorn: ASGI ҁĐĩŅ€Đ˛ĐĩŅ€, ĐŋĐžĐŧиĐŧĐž ĐŋŅ€ĐžŅ‡ĐĩĐŗĐž ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‰Đ¸Đš HTTP/2 и Trio. -* Daphne: ASGI ҁĐĩŅ€Đ˛ĐĩŅ€, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš Đ´ĐģŅ Django Channels. +
-## ĐĄĐĩŅ€Đ˛ĐĩŅ€ ĐēаĐē ĐŧĐ°ŅˆĐ¸ĐŊа и ҁĐĩŅ€Đ˛ĐĩŅ€ ĐēаĐē ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа +```console +$ fastapi run main.py -В ŅŅ‚Đ¸Ņ… Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ… ĐĩŅŅ‚ŅŒ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ€Đ°ĐˇĐģĐ¸Ņ‡Đ¸Ņ и ваĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ СаĐŋĐžĐŧĐŊĐ¸Ņ‚ŅŒ Đ¸Ņ…. 💡 + FastAPI Starting production server 🚀 -ĐĄĐģОвО "**ҁĐĩŅ€Đ˛ĐĩŅ€**" Ņ‡Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в Đ´Đ˛ŅƒŅ… ĐēĐžĐŊŅ‚ĐĩĐēŅŅ‚Đ°Ņ…: + Searching for package file structure from directories + with __init__.py files + Importing from /home/user/code/awesomeapp -- ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš иĐģи Ņ€Đ°ŅĐŋĐžĐģĐžĐļĐĩĐŊĐŊŅ‹Đš в "ОйĐģаĐēĐĩ" ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€ (Ņ„Đ¸ĐˇĐ¸Ņ‡ĐĩҁĐēĐ°Ņ иĐģи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа). -- ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа, СаĐŋŅƒŅ‰ĐĩĐŊĐŊĐ°Ņ ĐŊа Ņ‚Đ°ĐēĐžĐŧ ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn). + module 🐍 main.py -ĐŸŅ€ĐžŅŅ‚Đž СаĐŋĐžĐŧĐŊĐ¸Ņ‚Đĩ, ĐĩҁĐģи ваĐŧ Đ˛ŅŅ‚Ņ€ĐĩŅ‚Đ¸ĐģŅŅ Ņ‚ĐĩŅ€ĐŧиĐŊ "ҁĐĩŅ€Đ˛ĐĩŅ€", Ņ‚Đž ĐžĐąŅ‹Ņ‡ĐŊĐž ĐžĐŊ ĐŋĐžĐ´Ņ€Đ°ĐˇŅƒĐŧĐĩваĐĩŅ‚ Ņ‡Ņ‚Đž-Ņ‚Đž иС ŅŅ‚Đ¸Ņ… Đ´Đ˛ŅƒŅ… ҁĐŧҋҁĐģОв. + code Importing the FastAPI app object from the module with + the following code: -ĐšĐžĐŗĐ´Đ° иĐŧĐĩŅŽŅ‚ в Đ˛Đ¸Đ´Ņƒ иĐŧĐĩĐŊĐŊĐž ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€, Ņ‡Đ°ŅŅ‚Đž ĐŗĐžĐ˛ĐžŅ€ŅŅ‚ ĐŋŅ€ĐžŅŅ‚Đž **ҁĐĩŅ€Đ˛ĐĩŅ€**, ĐŊĐž Đĩ҉ґ ĐĩĐŗĐž ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **ĐŧĐ°ŅˆĐ¸ĐŊа**, **ВМ** (Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа), **ĐŊОда**. Đ’ŅĐĩ ŅŅ‚Đ¸ Ņ‚ĐĩŅ€ĐŧиĐŊŅ‹ ОйОСĐŊĐ°Ņ‡Đ°ŅŽŅ‚ ОдĐŊĐž и Ņ‚Đž ĐļĐĩ - ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊŅ‹Đš ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŋОд ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ Linux, ĐŊа ĐēĐžŅ‚ĐžŅ€ĐžĐŧ Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹. + from main import app -## ĐŖŅŅ‚Đ°ĐŊОвĐēа ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧĐŊĐžĐŗĐž ҁĐĩŅ€Đ˛ĐĩŅ€Đ° + app Using import string: main:app -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ҁĐĩŅ€Đ˛ĐĩŅ€, ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đš ҁ ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģĐžĐŧ ASGI, Ņ‚Đ°Đē: + server Server started at http://0.0.0.0:8000 + server Documentation at http://0.0.0.0:8000/docs -//// tab | Uvicorn + Logs: -* Uvicorn, ĐžŅ‡ĐĩĐŊҌ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đš ASGI ҁĐĩŅ€Đ˛ĐĩŅ€, ĐžŅĐŊОваĐŊĐŊŅ‹Đš ĐŊа йийĐģĐ¸ĐžŅ‚ĐĩĐēĐ°Ņ… uvloop и httptools. + INFO Started server process [2306215] + INFO Waiting for application startup. + INFO Application startup complete. + INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C + to quit) +``` + +
+ +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ŅŅ‚ĐžĐŗĐž Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž. 😎 + +Đ­Ņ‚ĐžĐš ĐēĐžĐŧаĐŊдОК, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŧĐžĐļĐŊĐž СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đĩ, ĐŊа ҁĐĩŅ€Đ˛ĐĩŅ€Đĩ и Ņ‚.Đ´. + +## ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩҀҋ { #asgi-servers } + +Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ ĐŊĐĩĐŧĐŊĐžĐŗĐž ŅƒĐŗĐģŅƒĐąĐ¸ĐŧŅŅ в Đ´ĐĩŅ‚Đ°Đģи. + +FastAPI Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ Đ´ĐģŅ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊĐ¸Ņ Python‑вĐĩĐąâ€‘Ņ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв и ҁĐĩŅ€Đ˛ĐĩŅ€ĐžĐ˛ ĐŋОд ĐŊаСваĐŊиĐĩĐŧ ASGI. FastAPI — ASGI-вĐĩĐąâ€‘Ņ„Ņ€ĐĩĐšĐŧĐ˛ĐžŅ€Đē. + +ГĐģавĐŊĐžĐĩ, Ņ‡Ņ‚Đž ваĐŧ ĐŊ҃ĐļĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** (иĐģи ĐģŅŽĐąĐžĐĩ Đ´Ņ€ŅƒĐŗĐžĐĩ ASGI‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ) ĐŊа ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊОК ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ, — ŅŅ‚Đž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đ°, Ņ‚Đ°ĐēĐ°Ņ ĐēаĐē **Uvicorn**; иĐŧĐĩĐŊĐŊĐž ĐžĐŊ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ в ĐēĐžĐŧаĐŊĐ´Đĩ `fastapi`. + +Đ•ŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +* Uvicorn: Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€. +* Hypercorn: ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€, ҁҀĐĩди ĐŋŅ€ĐžŅ‡ĐĩĐŗĐž ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đš ҁ HTTP/2 и Trio. +* Daphne: ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš Đ´ĐģŅ Django Channels. +* Granian: HTTPâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€ ĐŊа Rust Đ´ĐģŅ Python‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. +* NGINX Unit: NGINX Unit — ĐģŅ‘ĐŗĐēĐ°Ņ и ĐŧĐŊĐžĐŗĐžŅ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐ°Ņ ҁҀĐĩда Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊĐ¸Ņ вĐĩб‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК. + +## ĐĄĐĩŅ€Đ˛ĐĩŅ€ ĐēаĐē ĐŧĐ°ŅˆĐ¸ĐŊа и ҁĐĩŅ€Đ˛ĐĩŅ€ ĐēаĐē ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа { #server-machine-and-server-program } + +Đ•ŅŅ‚ŅŒ ĐŊĐĩйОĐģŅŒŅˆĐžĐš ĐŊŅŽĐ°ĐŊҁ в Ņ‚ĐĩŅ€ĐŧиĐŊĐžĐģĐžĐŗĐ¸Đ¸, Đž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ ŅŅ‚ĐžĐ¸Ņ‚ ĐŋĐžĐŧĐŊĐ¸Ņ‚ŅŒ. 💡 + +ĐĄĐģОвО ÂĢҁĐĩŅ€Đ˛ĐĩŅ€Âģ ĐžĐąŅ‹Ņ‡ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‚ и Đ´ĐģŅ ОйОСĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊĐžĐŗĐž/ОйĐģĐ°Ņ‡ĐŊĐžĐŗĐž ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đ° (Ņ„Đ¸ĐˇĐ¸Ņ‡ĐĩҁĐēОК иĐģи Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊŅ‹), и Đ´ĐģŅ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰ĐĩĐš ĐŊа ŅŅ‚ĐžĐš ĐŧĐ°ŅˆĐ¸ĐŊĐĩ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn). + +ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž ҁĐģОвО ÂĢҁĐĩŅ€Đ˛ĐĩŅ€Âģ в ҆ĐĩĐģĐžĐŧ ĐŧĐžĐļĐĩŅ‚ ОСĐŊĐ°Ņ‡Đ°Ņ‚ŅŒ ĐģŅŽĐąĐžĐĩ иС ŅŅ‚Đ¸Ņ… Đ´Đ˛ŅƒŅ…. + +ĐšĐžĐŗĐ´Đ° Ņ€ĐĩŅ‡ŅŒ Đ¸Đ´Ņ‘Ņ‚ Ой ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊĐĩ, ĐĩŅ‘ ĐˇĐ°Ņ‡Đ°ŅŅ‚ŅƒŅŽ ĐŊĐ°ĐˇŅ‹Đ˛Đ°ŅŽŅ‚ **ҁĐĩŅ€Đ˛ĐĩŅ€**, а Ņ‚Đ°ĐēĐļĐĩ **ĐŧĐ°ŅˆĐ¸ĐŊа**, **VM** (Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐ°Ņ ĐŧĐ°ŅˆĐ¸ĐŊа), **ĐŊОда**. Đ’ŅŅ‘ ŅŅ‚Đž — Đ˛Đ°Ņ€Đ¸Đ°ĐŊ҂ҋ ĐŊаСваĐŊĐ¸Ņ ŅƒĐ´Đ°ĐģŅ‘ĐŊĐŊОК ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŋОд ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩĐŧ Linux, ĐŊа ĐēĐžŅ‚ĐžŅ€ĐžĐš Đ˛Ņ‹ СаĐŋ҃ҁĐēаĐĩŅ‚Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹. + +## ĐŖŅŅ‚Đ°ĐŊОвĐēа ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ { #install-the-server-program } + +ĐŸŅ€Đ¸ ŅƒŅŅ‚Đ°ĐŊОвĐēĐĩ FastAPI ĐžĐŊ ĐŋĐžŅŅ‚Đ°Đ˛ĐģŅĐĩŅ‚ŅŅ ҁ ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€ĐžĐŧ Uvicorn, и Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐĩĐŗĐž ĐēĐžĐŧаĐŊдОК `fastapi run`. + +Но Đ˛Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ. + +ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ [Đ˛Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊĐžĐĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊиĐĩ](../virtual-environments.md){.internal-link target=_blank}, аĐēŅ‚Đ¸Đ˛Đ¸Ņ€ŅƒĐšŅ‚Đĩ ĐĩĐŗĐž и ĐˇĐ°Ņ‚ĐĩĐŧ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ Uvicorn:
@@ -39,39 +88,21 @@ $ pip install "uvicorn[standard]"
-/// tip | ĐŸĐžĐ´ŅĐēаСĐēа +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°ŅŽŅ‚ŅŅ и Đ´Ņ€ŅƒĐŗĐ¸Đĩ ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩҀҋ. -ĐĄ ĐžĐŋŅ†Đ¸ĐĩĐš `standard`, Uvicorn ĐąŅƒĐ´ĐĩŅ‚ ŅƒŅŅ‚Đ°ĐŊавĐģĐ¸Đ˛Đ°Ņ‚ŅŒŅŅ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ ҁ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đŧи Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи Ņ€ĐĩĐēĐžĐŧĐĩĐŊдОваĐŊĐŊŅ‹Đŧи ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи. +/// tip | ХОвĐĩŅ‚ -В ĐŊĐ¸Ņ… Đ˛Ņ…ĐžĐ´Đ¸Ņ‚ `uvloop`, Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ СаĐŧĐĩĐŊа `asyncio`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž ҃ҁĐēĐžŅ€ŅĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Ņƒ Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ. +ĐĄ дОйавĐģĐĩĐŊиĐĩĐŧ `standard` Uvicorn ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ и ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ€ŅĐ´ Ņ€ĐĩĐēĐžĐŧĐĩĐŊдОваĐŊĐŊҋ҅ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. + +В Đ¸Ņ… Ņ‡Đ¸ŅĐģĐĩ `uvloop` — Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ СаĐŧĐĩĐŊа `asyncio`, Đ´Đ°ŅŽŅ‰Đ°Ņ ҁĐĩŅ€ŅŒŅ‘ĐˇĐŊŅ‹Đš ĐŋŅ€Đ¸Ņ€ĐžŅŅ‚ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚Đ¸ ĐŋŅ€Đ¸ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊОК Ņ€Đ°ĐąĐžŅ‚Đĩ. + +Đ•ŅĐģи Đ˛Ņ‹ ŅƒŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚Đĩ FastAPI, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Ņ‚Đ°Đē: `pip install "fastapi[standard]"`, Đ˛Ņ‹ ҃ĐļĐĩ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ и `uvicorn[standard]`. /// -//// +## ЗаĐŋ҃ҁĐē ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ { #run-the-server-program } -//// tab | Hypercorn - -* Hypercorn, ASGI ҁĐĩŅ€Đ˛ĐĩŅ€, ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‰Đ¸Đš ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģ HTTP/2. - -
- -```console -$ pip install hypercorn - ----> 100% -``` - -
- -...иĐģи ĐēаĐēОК-ĐģийО Đ´Ņ€ŅƒĐŗĐžĐš ASGI ҁĐĩŅ€Đ˛ĐĩŅ€. - -//// - -## ЗаĐŋ҃ҁĐē ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊОК ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ - -Đ—Đ°Ņ‚ĐĩĐŧ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Ņ‚Đ°Đē ĐļĐĩ, ĐēаĐē ĐąŅ‹ĐģĐž ҃ĐēаСаĐŊĐž в Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đĩ Ņ€Đ°ĐŊĐĩĐĩ, ĐŊĐž ĐąĐĩС ĐžĐŋŅ†Đ¸Đ¸ `--reload`: - -//// tab | Uvicorn +Đ•ŅĐģи Đ˛Ņ‹ ŅƒŅŅ‚Đ°ĐŊОвиĐģи ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ, ĐžĐąŅ‹Ņ‡ĐŊĐž ĐŊ҃ĐļĐŊĐž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ŅŅ‚Ņ€ĐžĐē҃ иĐŧĐŋĐžŅ€Ņ‚Đ° в ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊĐžĐŧ Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ ҁĐŧĐžĐŗ иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ FastAPI:
@@ -83,81 +114,44 @@ $ uvicorn main:app --host 0.0.0.0 --port 80
-//// +/// note | ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊиĐĩ -//// tab | Hypercorn +КоĐŧаĐŊда `uvicorn main:app` ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚: -
+* `main`: Ņ„Đ°ĐšĐģ `main.py` (Python‑ÂĢĐŧĐžĐ´ŅƒĐģҌÂģ). +* `app`: ĐžĐąŅŠĐĩĐēŅ‚, ŅĐžĐˇĐ´Đ°ĐŊĐŊŅ‹Đš в `main.py` ŅŅ‚Ņ€ĐžĐēОК `app = FastAPI()`. -```console -$ hypercorn main:app --bind 0.0.0.0:80 +Đ­ĐēвиваĐģĐĩĐŊŅ‚ĐŊĐž: -Running on 0.0.0.0:8080 over http (CTRL + C to quit) +```Python +from main import app ``` -
- -//// - -/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ - -НĐĩ ĐˇĐ°ĐąŅƒĐ´ŅŒŅ‚Đĩ ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ ĐžĐŋŅ†Đ¸ŅŽ `--reload`, ĐĩҁĐģи Ņ€Đ°ĐŊĐĩĐĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐģĐ¸ŅŅŒ ĐĩŅŽ. - -ВĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ ĐžĐŋŅ†Đ¸Đ¸ `--reload` ҂ҀĐĩĐąŅƒĐĩŅ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛, вĐģĐ¸ŅĐĩŅ‚ ĐŊа ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊĐžŅŅ‚ŅŒ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ и ĐŧĐžĐļĐĩŅ‚ ĐŋОвĐģĐĩŅ‡ŅŒ ĐŋŅ€ĐžŅ‡Đ¸Đĩ ĐŊĐĩĐŋŅ€Đ¸ŅŅ‚ĐŊĐžŅŅ‚Đ¸. - -ОĐŊа ŅĐ¸ĐģҌĐŊĐž ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚ вО Đ˛Ņ€ĐĩĐŧŅ **Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи**, ĐŊĐž **ĐŊĐĩ ҁĐģĐĩĐ´ŅƒĐĩŅ‚** Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩŅ‘ ĐŋŅ€Đ¸ **Ņ€ĐĩаĐģҌĐŊОК Ņ€Đ°ĐąĐžŅ‚Đĩ** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. - /// -## Hypercorn ҁ Trio +ĐŖ ĐēаĐļĐ´ĐžĐŗĐž аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐžĐŗĐž ASGIâ€‘ŅĐĩŅ€Đ˛ĐĩŅ€Đ° ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžŅ…ĐžĐļĐ°Ņ ĐēĐžĐŧаĐŊда; ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ҁĐŧ. в Đ¸Ņ… Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. -Starlette и **FastAPI** ĐžŅĐŊОваĐŊŅ‹ ĐŊа AnyIO, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Đ´ĐĩĐģаĐĩŅ‚ Đ¸Ņ… ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧи ĐēаĐē ҁ asyncio - ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊОК йийĐģĐ¸ĐžŅ‚ĐĩĐēОК Python, Ņ‚Đ°Đē и ҁ Trio. +/// warning | ĐŸŅ€ĐĩĐ´ŅƒĐŋŅ€ĐĩĐļĐ´ĐĩĐŊиĐĩ +Uvicorn и Đ´Ņ€ŅƒĐŗĐ¸Đĩ ҁĐĩŅ€Đ˛ĐĩҀҋ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŽŅ‚ ĐžĐŋŅ†Đ¸ŅŽ `--reload`, ĐŋĐžĐģĐĩСĐŊŅƒŅŽ в ĐŋĐĩŅ€Đ¸ĐžĐ´ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи. -ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ Uvicorn ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đŧ Ņ‚ĐžĐģҌĐēĐž ҁ asyncio и ĐžĐąŅ‹Ņ‡ĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ŅĐžĐ˛ĐŧĐĩҁ҂ĐŊĐž ҁ `uvloop`, Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊОК СаĐŧĐĩĐŊОК `asyncio`. +ОĐŋŅ†Đ¸Ņ `--reload` ĐŋĐžŅ‚Ņ€ĐĩĐąĐģŅĐĩŅ‚ СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊĐž йОĐģҌ҈Đĩ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛, ĐŧĐĩĐŊĐĩĐĩ ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊа и Ņ‚.Đŋ. -Но ĐĩҁĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **Trio** ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ, Ņ‚Đž ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ **Hypercorn**, Ņ‚Đ°Đē ĐēаĐē ĐžĐŊи ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹. ✨ +ОĐŊа ŅĐ¸ĐģҌĐŊĐž ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚ вО Đ˛Ņ€ĐĩĐŧŅ **Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи**, ĐŊĐž в **ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ** ĐĩŅ‘ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **ĐŊĐĩ ҁĐģĐĩĐ´ŅƒĐĩŅ‚**. -### ĐŖŅŅ‚Đ°ĐŊОвĐēа Hypercorn ҁ Trio +/// -ДĐģŅ ĐŊĐ°Ņ‡Đ°Đģа, ваĐŧ ĐŊ҃ĐļĐŊĐž ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŒ Hypercorn ҁ ĐŋОддĐĩŅ€ĐļĐēОК Trio: +## КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ { #deployment-concepts } -
+В ŅŅ‚Đ¸Ņ… ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°Ņ… ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊĐ°Ņ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Uvicorn) СаĐŋ҃ҁĐēаĐĩŅ‚ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**, ҁĐģŅƒŅˆĐ°ŅŽŅ‰Đ¸Đš Đ˛ŅĐĩ IPâ€‘Đ°Đ´Ņ€ĐĩŅĐ° (`0.0.0.0`) ĐŊа ĐˇĐ°Ņ€Đ°ĐŊĐĩĐĩ СадаĐŊĐŊĐžĐŧ ĐŋĐžŅ€Ņ‚Ņƒ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `80`). -```console -$ pip install "hypercorn[trio]" ----> 100% -``` +Đ­Ņ‚Đž ĐąĐ°ĐˇĐžĐ˛Đ°Ņ идĐĩŅ. Но, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ваĐŧ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ ĐŋĐžĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ŅŒŅŅ и Đž ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ вĐĩŅ‰Đ°Ņ…, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: -
+* БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ -### ЗаĐŋ҃ҁĐē ҁ Trio - -ДаĐģĐĩĐĩ СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ Hypercorn ҁ ĐžĐŋŅ†Đ¸ĐĩĐš `--worker-class` и Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐŧ `trio`: - -
- -```console -$ hypercorn main:app --worker-class trio -``` - -
- -Hypercorn, в ŅĐ˛ĐžŅŽ ĐžŅ‡ĐĩŅ€ĐĩĐ´ŅŒ, СаĐŋŅƒŅŅ‚Đ¸Ņ‚ Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰ĐĩĐĩ Trio. - -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Trio в ŅĐ˛ĐžŅ‘Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии. Но ĐģŅƒŅ‡ŅˆĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ AnyIO, Đ´ĐģŅ ŅĐžŅ…Ņ€Đ°ĐŊĐĩĐŊĐ¸Ņ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐžŅŅ‚Đ¸ и ҁ Trio, и ҁ asyncio. 🎉 - -## КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Ņ€Đ°ĐˇĐ˛Ņ‘Ņ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸Ņ - -В Đ˛Ņ‹ŅˆĐĩĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņ‘ĐŊĐŊҋ҅ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°Ņ… ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊŅ‹Đĩ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧŅ‹ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Uvicorn) СаĐŋ҃ҁĐēаĐģи Ņ‚ĐžĐģҌĐēĐž **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ**, ĐŋŅ€Đ¸ĐŊиĐŧĐ°ŅŽŅ‰Đ¸Đš Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ СаĐŋŅ€ĐžŅŅ‹ ҁ ĐģŅŽĐąĐžĐŗĐž IP (ĐŊа ŅŅ‚Đž ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Đģ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ `0.0.0.0`) ĐŊа ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš ĐŋĐžŅ€Ņ‚ (в ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°Ņ… ĐŧŅ‹ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°Đģи ĐŋĐžŅ€Ņ‚ `80`). - -Đ­Ņ‚Đž ĐžŅĐŊОвĐŊĐ°Ņ идĐĩŅ. Но вОСĐŧĐžĐļĐŊĐž, Đ˛Ņ‹ ĐžĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ĐĩҁҌ дОйавĐģĐĩĐŊиĐĩĐŧ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊҋ҅ вОСĐŧĐžĐļĐŊĐžŅŅ‚ĐĩĐš, Ņ‚Đ°ĐēĐ¸Ņ… ĐēаĐē: - -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ йОĐģĐĩĐĩ ĐąĐĩСОĐŋĐ°ŅĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‚ĐžĐēĐžĐģа HTTPS -* ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи СаĐŋ҃ҁĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ПĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ЗаĐŋ҃ҁĐē ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ŅĐēСĐĩĐŧĐŋĐģŅŅ€ĐžĐ˛ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ -* ĐŖĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ ĐŋаĐŧŅŅ‚ŅŒŅŽ -* Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģĐĩĐŊĐŊҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. - -Đ¯ Ņ€Đ°ŅŅĐēаĐļ҃ ваĐŧ йОĐģҌ҈Đĩ Đž ĐēаĐļдОК иС ŅŅ‚Đ¸Ņ… ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš в ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ…, ҁ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đŧи ĐŋŅ€Đ¸ĐŧĐĩŅ€Đ°Đŧи ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ ĐŊиĐŧи. 🚀 +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… ĐŗĐģĐ°Đ˛Đ°Ņ… Ņ Ņ€Đ°ŅŅĐēаĐļ҃ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ ĐŋŅ€Đž ĐēаĐļĐ´ŅƒŅŽ иС ŅŅ‚Đ¸Ņ… ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš, Đž Ņ‚ĐžĐŧ, ĐēаĐē Đž ĐŊĐ¸Ņ… Đ´ŅƒĐŧĐ°Ņ‚ŅŒ, и ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņƒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đĩ ĐŋŅ€Đ¸ĐŧĐĩҀҋ ŅĐž ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸ŅĐŧи, ĐēаĐē ҁ ĐŊиĐŧи Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ. 🚀 diff --git a/docs/ru/docs/deployment/server-workers.md b/docs/ru/docs/deployment/server-workers.md new file mode 100644 index 000000000..e756ab377 --- /dev/null +++ b/docs/ru/docs/deployment/server-workers.md @@ -0,0 +1,139 @@ +# ĐĄĐĩŅ€Đ˛ĐĩŅ€ĐŊŅ‹Đĩ Đ˛ĐžŅ€ĐēĐĩҀҋ — Uvicorn ҁ Đ˛ĐžŅ€ĐēĐĩŅ€Đ°Đŧи { #server-workers-uvicorn-with-workers } + +Đ”Đ°Đ˛Đ°ĐšŅ‚Đĩ ҁĐŊОва Đ˛ŅĐŋĐžĐŧĐŊиĐŧ Ņ‚Đĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Đ´ĐĩĐŋĐģĐžŅ, Đž ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŗĐžĐ˛ĐžŅ€Đ¸Đģи Ņ€Đ°ĐŊĐĩĐĩ: + +* БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS +* ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ +* ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи +* **Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛)** +* ПаĐŧŅŅ‚ŅŒ +* ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ + +До ŅŅ‚ĐžĐŗĐž ĐŧĐžĐŧĐĩĐŊŅ‚Đ°, ҁĐģĐĩĐ´ŅƒŅ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đ°Đŧ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, Đ˛Ņ‹, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, СаĐŋ҃ҁĐēаĐģи **ҁĐĩŅ€Đ˛ĐĩŅ€ĐŊŅƒŅŽ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃**, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐēĐžĐŧаĐŊĐ´Ņ‹ `fastapi`, ĐēĐžŅ‚ĐžŅ€Đ°Ņ СаĐŋ҃ҁĐēаĐĩŅ‚ Uvicorn в **ОдĐŊĐžĐŧ ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ**. + +ĐŸŅ€Đ¸ Đ´ĐĩĐŋĐģĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ ваĐŧ, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐˇĐ°Ņ…ĐžŅ‡ĐĩŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ŅŽ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**, Ņ‡Ņ‚ĐžĐąŅ‹ СадĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ŅĐ´ĐĩŅ€** и иĐŧĐĩŅ‚ŅŒ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ йОĐģҌ҈Đĩ СаĐŋŅ€ĐžŅĐžĐ˛. + +КаĐē Đ˛Ņ‹ видĐĩĐģи в ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰ĐĩĐš ĐŗĐģавĐĩ Đž [КоĐŊ҆ĐĩĐŋŅ†Đ¸ŅŅ… Đ´ĐĩĐŋĐģĐžŅ](concepts.md){.internal-link target=_blank}, ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đš. + +ЗдĐĩҁҌ Ņ ĐŋĐžĐēаĐļ҃, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **Uvicorn** ҁ **Đ˛ĐžŅ€ĐēĐĩŅ€-ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°Đŧи** ҇ĐĩŅ€ĐĩС ĐēĐžĐŧаĐŊĐ´Ņƒ `fastapi` иĐģи ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ҇ĐĩŅ€ĐĩС ĐēĐžĐŧаĐŊĐ´Ņƒ `uvicorn`. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Docker иĐģи Kubernetes, Ņ Ņ€Đ°ŅŅĐēаĐļ҃ Ой ŅŅ‚ĐžĐŧ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ в ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐš ĐŗĐģавĐĩ: [FastAPI в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ… — Docker](docker.md){.internal-link target=_blank}. + +В Ņ‡Đ°ŅŅ‚ĐŊĐžŅŅ‚Đ¸, ĐŋŅ€Đ¸ СаĐŋ҃ҁĐēĐĩ в **Kubernetes** ваĐŧ, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, **ĐŊĐĩ** ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ˛ĐžŅ€ĐēĐĩҀҋ — вĐŧĐĩŅŅ‚Đž ŅŅ‚ĐžĐŗĐž СаĐŋ҃ҁĐēĐ°ĐšŅ‚Đĩ **ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn ĐŊа ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€**, ĐŊĐž Ой ŅŅ‚ĐžĐŧ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ даĐģĐĩĐĩ в Ņ‚ĐžĐš ĐŗĐģавĐĩ. + +/// + +## НĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ { #multiple-workers } + +МоĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐžĐŋŅ†Đ¸Đ¸ ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--workers`: + +//// tab | `fastapi` + +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐēĐžĐŧаĐŊĐ´Ņƒ `fastapi`: + +
+ +```console +$ fastapi run --workers 4 main.py + + FastAPI Starting production server 🚀 + + Searching for package file structure from directories with + __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with the + following code: + + from main import app + + app Using import string: main:app + + server Server started at http://0.0.0.0:8000 + server Documentation at http://0.0.0.0:8000/docs + + Logs: + + INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to + quit) + INFO Started parent process [27365] + INFO Started server process [27368] + INFO Started server process [27369] + INFO Started server process [27370] + INFO Started server process [27367] + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Waiting for application startup. + INFO Application startup complete. + INFO Application startup complete. + INFO Application startup complete. + INFO Application startup complete. +``` + +
+ +//// + +//// tab | `uvicorn` + +Đ•ŅĐģи Đ˛Ņ‹ ĐŋŅ€ĐĩĐ´ĐŋĐžŅ‡Đ¸Ņ‚Đ°ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐēĐžĐŧаĐŊĐ´Ņƒ `uvicorn` ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ: + +
+ +```console +$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4 +INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit) +INFO: Started parent process [27365] +INFO: Started server process [27368] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Started server process [27369] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Started server process [27370] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Started server process [27367] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +
+ +//// + +ЕдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊĐ°Ņ ĐŊĐžĐ˛Đ°Ņ ĐžĐŋŅ†Đ¸Ņ СдĐĩҁҌ — `--workers`, ĐžĐŊа ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Uvicorn СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ 4 Đ˛ĐžŅ€ĐēĐĩŅ€-ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°. + +ĐĸаĐēĐļĐĩ видĐŊĐž, Ņ‡Ņ‚Đž Đ˛Ņ‹Đ˛ĐžĐ´Đ¸Ņ‚ŅŅ **PID** ĐēаĐļĐ´ĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°: `27365` — Đ´ĐģŅ Ņ€ĐžĐ´Đ¸Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐ° (ŅŅ‚Đž **ĐŧĐĩĐŊĐĩĐ´ĐļĐĩŅ€ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛**) и ĐŋĐž ОдĐŊĐžĐŧ҃ Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž Đ˛ĐžŅ€ĐēĐĩŅ€-ĐŋŅ€ĐžŅ†ĐĩŅŅĐ°: `27368`, `27369`, `27370` и `27367`. + +## КоĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Đ´ĐĩĐŋĐģĐžŅ { #deployment-concepts } + +ЗдĐĩҁҌ Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´ĐĩĐģи, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž **Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛**, Ņ‡Ņ‚ĐžĐąŅ‹ **Ņ€Đ°ŅĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģĐ¸Ņ‚ŅŒ** Đ˛Ņ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, СадĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ŅĐ´ĐĩŅ€** CPU и ĐžĐąŅĐģ҃ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ **йОĐģҌ҈Đĩ СаĐŋŅ€ĐžŅĐžĐ˛**. + +ИС ҁĐŋĐ¸ŅĐēа ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš Đ´ĐĩĐŋĐģĐžŅ Đ˛Ņ‹ŅˆĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ Đ˛ĐžŅ€ĐēĐĩŅ€ĐžĐ˛ в ĐžŅĐŊОвĐŊĐžĐŧ ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚ ҁ **Ņ€ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸ĐĩĐš**, и ĐŊĐĩĐŧĐŊĐžĐŗĐž — ҁ **ĐŋĐĩŅ€ĐĩСаĐŋ҃ҁĐēаĐŧи**, ĐŊĐž Ой ĐžŅŅ‚Đ°ĐģҌĐŊҋ҅ ĐŋĐž-ĐŋŅ€ĐĩĐļĐŊĐĩĐŧ҃ ĐŊ҃ĐļĐŊĐž ĐŋĐžĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ŅŒŅŅ: + +* **БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ — HTTPS** +* **ЗаĐŋ҃ҁĐē ĐŋŅ€Đ¸ ŅŅ‚Đ°Ņ€Ņ‚Đĩ** +* ***ПĐĩŅ€ĐĩСаĐŋ҃ҁĐēи*** +* Đ ĐĩĐŋĐģиĐēĐ°Ņ†Đ¸Ņ (ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž СаĐŋŅƒŅ‰ĐĩĐŊĐŊҋ҅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛) +* **ПаĐŧŅŅ‚ŅŒ** +* **ĐŸŅ€ĐĩĐ´Đ˛Đ°Ņ€Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ŅˆĐ°ĐŗĐ¸ ĐŋĐĩŅ€ĐĩĐ´ СаĐŋ҃ҁĐēĐžĐŧ** + +## КоĐŊŅ‚ĐĩĐšĐŊĐĩҀҋ и Docker { #containers-and-docker } + +В ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐš ĐŗĐģавĐĩ Đž [FastAPI в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ… — Docker](docker.md){.internal-link target=_blank} Ņ ĐžĐąŅŠŅŅĐŊŅŽ ŅŅ‚Ņ€Đ°Ņ‚ĐĩĐŗĐ¸Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐģŅ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ ĐžŅŅ‚Đ°ĐģҌĐŊҋ҅ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đš Đ´ĐĩĐŋĐģĐžŅ**. + +Đ¯ ĐŋĐžĐēаĐļ҃, ĐēаĐē **ŅĐžĐąŅ€Đ°Ņ‚ŅŒ ŅĐ˛ĐžĐš ĐžĐąŅ€Đ°Đˇ ҁ ĐŊ҃ĐģŅ**, Ņ‡Ņ‚ĐžĐąŅ‹ СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ОдиĐŊ ĐŋŅ€ĐžŅ†Đĩҁҁ Uvicorn. Đ­Ņ‚Đž ĐŋŅ€ĐžŅŅ‚ĐžĐš ĐŋĐžĐ´Ņ…ĐžĐ´ и, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, иĐŧĐĩĐŊĐŊĐž Ņ‚Đž, Ņ‡Ņ‚Đž ваĐŧ ĐŊ҃ĐļĐŊĐž ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧŅ‹ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Đŧи, Ņ‚Đ°ĐēОК ĐēаĐē **Kubernetes**. + +## Đ ĐĩĐˇŅŽĐŧĐĩ { #recap } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛ĐžŅ€ĐēĐĩŅ€-ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ҁ ĐžĐŋŅ†Đ¸ĐĩĐš ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи `--workers` в ĐēĐžĐŧаĐŊĐ´Đ°Ņ… `fastapi` иĐģи `uvicorn`, Ņ‡Ņ‚ĐžĐąŅ‹ СадĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ **ĐŧĐŊĐžĐŗĐžŅĐ´ĐĩŅ€ĐŊŅ‹Đĩ CPU**, СаĐŋ҃ҁĐēĐ°Ņ **ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛ ĐŋĐ°Ņ€Đ°ĐģĐģĐĩĐģҌĐŊĐž**. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ и идĐĩи, ĐĩҁĐģи ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ĐĩŅ‚Đĩ **ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ Đ´ĐĩĐŋĐģĐžŅ** и ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž СаĐēŅ€Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐžŅŅ‚Đ°ĐģҌĐŊŅ‹Đĩ ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Đ´ĐĩĐŋĐģĐžŅ. + +ПĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ Đē ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐš ĐŗĐģавĐĩ, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ Đž **FastAPI** в ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€Đ°Ņ… (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Docker и Kubernetes). Đ’Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ŅŅ‚Đ¸ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ Ņ‚ĐžĐļĐĩ ĐŋŅ€ĐĩĐ´ĐģĐ°ĐŗĐ°ŅŽŅ‚ ĐŋŅ€ĐžŅŅ‚Ņ‹Đĩ ҁĐŋĐžŅĐžĐąŅ‹ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ **ĐēĐžĐŊ҆ĐĩĐŋŅ†Đ¸Đ¸ Đ´ĐĩĐŋĐģĐžŅ**. ✨ diff --git a/docs/ru/docs/deployment/versions.md b/docs/ru/docs/deployment/versions.md index e8db30ce8..58d5aa110 100644 --- a/docs/ru/docs/deployment/versions.md +++ b/docs/ru/docs/deployment/versions.md @@ -1,42 +1,42 @@ -# О вĐĩŅ€ŅĐ¸ŅŅ… FastAPI +# О вĐĩŅ€ŅĐ¸ŅŅ… FastAPI { #about-fastapi-versions } -**FastAPI** ҃ĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐĩĐŊĐĩ вО ĐŧĐŊĐžĐŗĐ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ… и ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ…. ПоĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ŅŅ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ 100%. ОдĐŊаĐēĐž ĐĩĐŗĐž Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа Đ˛ŅĐĩ Đĩ҉Đĩ ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩŅ‚ŅŅ. +**FastAPI** ҃ĐļĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐĩĐŊĐĩ вО ĐŧĐŊĐžĐŗĐ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ… и ŅĐ¸ŅŅ‚ĐĩĐŧĐ°Ņ…. ПоĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ŅŅ ĐŊа ŅƒŅ€ĐžĐ˛ĐŊĐĩ 100%. Но ĐĩĐŗĐž Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа Đ˛ŅŅ‘ Đĩ҉ґ двиĐļĐĩŅ‚ŅŅ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Đŧи Ņ‚ĐĩĐŧĐŋаĐŧи. Đ§Đ°ŅŅ‚Đž дОйавĐģŅŅŽŅ‚ŅŅ ĐŊĐžĐ˛Ņ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸, Ņ€ĐĩĐŗŅƒĐģŅŅ€ĐŊĐž Đ¸ŅĐŋŅ€Đ°Đ˛ĐģŅŅŽŅ‚ŅŅ ĐąĐ°ĐŗĐ¸, ĐēОд ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩŅ‚ ĐŋĐžŅŅ‚ĐžŅĐŊĐŊĐž ŅĐžĐ˛ĐĩŅ€ŅˆĐĩĐŊŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒŅŅ. -По ҃ĐēаСаĐŊĐŊŅ‹Đŧ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊаĐŧ Ņ‚ĐĩĐēŅƒŅ‰Đ¸Đĩ вĐĩŅ€ŅĐ¸Đ¸ Đ´Đž ŅĐ¸Ņ… ĐŋĐžŅ€ `0.x.x`. Đ­Ņ‚Đž ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Đž Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐēаĐļĐ´Đ°Ņ вĐĩŅ€ŅĐ¸Ņ ĐŧĐžĐļĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Ņ‚ĐŊĐž ĐŊĐĩŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đĩ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ, ҁĐģĐĩĐ´ŅƒŅ ŅĐžĐŗĐģĐ°ŅˆĐĩĐŊĐ¸ŅŽ Đž ĐĄĐĩĐŧаĐŊŅ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŧ ВĐĩŅ€ŅĐ¸ĐžĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊии. +По ҃ĐēаСаĐŊĐŊŅ‹Đŧ ĐŋŅ€Đ¸Ņ‡Đ¸ĐŊаĐŧ Ņ‚ĐĩĐēŅƒŅ‰Đ¸Đĩ вĐĩŅ€ŅĐ¸Đ¸ Đ´Đž ŅĐ¸Ņ… ĐŋĐžŅ€ `0.x.x`. Đ­Ņ‚Đž ĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ Đž Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐēаĐļĐ´Đ°Ņ вĐĩŅ€ŅĐ¸Ņ ĐŧĐžĐļĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ ĐžĐąŅ€Đ°Ņ‚ĐŊĐž ĐŊĐĩŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đĩ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ, ҁĐģĐĩĐ´ŅƒŅ ĐĄĐĩĐŧаĐŊŅ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŧ҃ вĐĩŅ€ŅĐ¸ĐžĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸ŅŽ. -ĐŖĐļĐĩ ҁĐĩĐšŅ‡Đ°Ņ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐĩĐŊĐĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ **FastAPI** (и ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž Ņ‚Đ°Đē и Đ´ĐĩĐģаĐĩŅ‚Đĩ), ĐŗĐģавĐŊĐžĐĩ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ вĐĩŅ€ŅĐ¸ŅŽ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐēОдОĐŧ. +ĐŖĐļĐĩ ҁĐĩĐšŅ‡Đ°Ņ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐĩĐŊĐĩ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ **FastAPI** (и ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž Ņ‚Đ°Đē и Đ´ĐĩĐģаĐĩŅ‚Đĩ), ĐŗĐģавĐŊĐžĐĩ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ вĐĩŅ€ŅĐ¸ŅŽ, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐēОдОĐŧ. -## ЗаĐēŅ€ĐĩĐŋĐ¸Ņ‚Đĩ Đ˛Đ°ŅˆŅƒ вĐĩŅ€ŅĐ¸ŅŽ `fastapi` +## ЗаĐēŅ€ĐĩĐŋĐ¸Ņ‚Đĩ Đ˛Đ°ŅˆŅƒ вĐĩŅ€ŅĐ¸ŅŽ `fastapi` { #pin-your-fastapi-version } ПĐĩŅ€Đ˛Ņ‹Đŧ Đ´ĐĩĐģĐžĐŧ ваĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ "СаĐēŅ€ĐĩĐŋĐ¸Ņ‚ŅŒ" ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅƒŅŽ ĐŋĐžŅĐģĐĩĐ´ĐŊŅŽŅŽ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅƒŅŽ вĐĩŅ€ŅĐ¸ŅŽ **FastAPI**, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ҁ Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. -НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ŅĐ˛ĐžŅ‘Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ вĐĩŅ€ŅĐ¸ŅŽ `0.45.0`. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ŅĐ˛ĐžŅ‘Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ вĐĩŅ€ŅĐ¸ŅŽ `0.112.0`. Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Ņ„Đ°ĐšĐģ `requirements.txt`, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ вĐĩŅ€ŅĐ¸ŅŽ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ҁĐŋĐžŅĐžĐąĐžĐŧ: ```txt -fastapi==0.45.0 +fastapi[standard]==0.112.0 ``` -ŅŅ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ иĐŧĐĩĐŊĐŊĐž вĐĩŅ€ŅĐ¸ŅŽ `0.45.0`. +ŅŅ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ иĐŧĐĩĐŊĐŊĐž вĐĩŅ€ŅĐ¸ŅŽ `0.112.0`. ИĐģи Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐēŅ€ĐĩĐŋĐ¸Ņ‚ŅŒ вĐĩŅ€ŅĐ¸ŅŽ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đŧ ҁĐŋĐžŅĐžĐąĐžĐŧ: ```txt -fastapi>=0.45.0,<0.46.0 +fastapi[standard]>=0.112.0,<0.113.0 ``` -ŅŅ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ вĐĩŅ€ŅĐ¸Đ¸ `0.45.0` иĐģи Đ˛Ņ‹ŅˆĐĩ, ĐŊĐž ĐŧĐĩĐŊҌ҈Đĩ ҇ĐĩĐŧ `0.46.0`. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, вĐĩŅ€ŅĐ¸Ņ `0.45.2` Đ˛ŅĐĩ Đĩ҉Đĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ŅŒ. +ŅŅ‚Đž СĐŊĐ°Ņ‡Đ¸Ņ‚, Ņ‡Ņ‚Đž Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ вĐĩŅ€ŅĐ¸Đ¸ `0.112.0` иĐģи Đ˛Ņ‹ŅˆĐĩ, ĐŊĐž ĐŧĐĩĐŊҌ҈Đĩ ҇ĐĩĐŧ `0.113.0`. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, вĐĩŅ€ŅĐ¸Ņ `0.112.2` Đ˛ŅŅ‘ Đĩ҉ґ ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚ŅŒ. -Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐģŅŽĐąĐžĐš Đ´Ņ€ŅƒĐŗĐžĐš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ Đ´ĐģŅ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ Poetry, Pipenv иĐģи Đ´Ņ€., ҃ ĐŊĐ¸Ņ… ҃ Đ˛ŅĐĩŅ… иĐŧĐĩĐĩŅ‚ŅŅ ҁĐŋĐžŅĐžĐą ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐĩҁĐēОК вĐĩŅ€ŅĐ¸Đ¸ Đ´ĐģŅ Đ˛Đ°ŅˆĐ¸Ņ… ĐŋаĐēĐĩŅ‚ĐžĐ˛. +Đ•ŅĐģи Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐģŅŽĐąĐžĐš Đ´Ņ€ŅƒĐŗĐžĐš иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ Đ´ĐģŅ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ ŅƒŅŅ‚Đ°ĐŊОвĐēаĐŧи/ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `uv`, Poetry, Pipenv иĐģи Đ´Ņ€., ҃ ĐŊĐ¸Ņ… ҃ Đ˛ŅĐĩŅ… иĐŧĐĩĐĩŅ‚ŅŅ ҁĐŋĐžŅĐžĐą ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐĩҁĐēОК вĐĩŅ€ŅĐ¸Đ¸ Đ´ĐģŅ Đ˛Đ°ŅˆĐ¸Ņ… ĐŋаĐēĐĩŅ‚ĐžĐ˛. -## Đ”ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ +## Đ”ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ { #available-versions } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ ĐŋĐžŅĐģĐĩĐ´ĐŊŅŽŅŽ ĐŊа даĐŊĐŊŅ‹Đš ĐŧĐžĐŧĐĩĐŊŅ‚) в [ĐŋŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊĐ¸ŅŅ… Đē Đ˛Ņ‹Đŋ҃ҁĐē҃](../release-notes.md){.internal-link target=_blank}. +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ ĐŋĐžŅĐģĐĩĐ´ĐŊŅŽŅŽ ĐŊа даĐŊĐŊŅ‹Đš ĐŧĐžĐŧĐĩĐŊŅ‚) в [ĐŸŅ€Đ¸ĐŧĐĩŅ‡Đ°ĐŊĐ¸ŅŅ… Đē Đ˛Ņ‹Đŋ҃ҁĐē҃](../release-notes.md){.internal-link target=_blank}. -## О вĐĩŅ€ŅĐ¸ŅŅ… +## О вĐĩŅ€ŅĐ¸ŅŅ… { #about-versions } ĐĄĐģĐĩĐ´ŅƒŅ ŅĐžĐŗĐģĐ°ŅˆĐĩĐŊĐ¸ŅŽ Đž ĐĄĐĩĐŧаĐŊŅ‚Đ¸Ņ‡ĐĩҁĐēĐžĐŧ ВĐĩŅ€ŅĐ¸ĐžĐŊĐ¸Ņ€ĐžĐ˛Đ°ĐŊии, ĐģŅŽĐąŅ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ ĐŊиĐļĐĩ `1.0.0` ĐŋĐžŅ‚ĐĩĐŊŅ†Đ¸Đ°ĐģҌĐŊĐž ĐŧĐžĐŗŅƒŅ‚ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐžĐąŅ€Đ°Ņ‚ĐŊĐž ĐŊĐĩŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đĩ иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ. @@ -44,7 +44,7 @@ FastAPI ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ŅĐžĐŗĐģĐ°ŅˆĐĩĐŊĐ¸ŅŽ в Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐģŅŽĐąŅ‹Đĩ иСĐŧ /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -"ПАĐĸЧ" - ŅŅ‚Đž ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐĩ Ņ‡Đ¸ŅĐģĐž. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в `0.2.3`, ПАĐĸЧ-вĐĩŅ€ŅĐ¸Ņ - ŅŅ‚Đž `3`. +"ПАĐĸЧ" — ŅŅ‚Đž ĐŋĐžŅĐģĐĩĐ´ĐŊĐĩĐĩ Ņ‡Đ¸ŅĐģĐž. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в `0.2.3`, ПАĐĸЧ-вĐĩŅ€ŅĐ¸Ņ — ŅŅ‚Đž `3`. /// @@ -58,11 +58,11 @@ fastapi>=0.45.0,<0.46.0 /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -"ĐœĐ˜ĐĐžĐ ĐĐĐ¯" вĐĩŅ€ŅĐ¸Ņ - ŅŅ‚Đž Ņ‡Đ¸ŅĐģĐž в ҁĐĩŅ€ĐĩдиĐŊĐĩ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в `0.2.3` ĐœĐ˜ĐĐžĐ ĐĐĐ¯ вĐĩŅ€ŅĐ¸Ņ - ŅŅ‚Đž `2`. +"ĐœĐ˜ĐĐžĐ ĐĐĐ¯" вĐĩŅ€ŅĐ¸Ņ — ŅŅ‚Đž Ņ‡Đ¸ŅĐģĐž в ҁĐĩŅ€ĐĩдиĐŊĐĩ. НаĐŋŅ€Đ¸ĐŧĐĩŅ€, в `0.2.3` ĐœĐ˜ĐĐžĐ ĐĐĐ¯ вĐĩŅ€ŅĐ¸Ņ — ŅŅ‚Đž `2`. /// -## ОбĐŊОвĐģĐĩĐŊиĐĩ вĐĩŅ€ŅĐ¸Đš FastAPI +## ОбĐŊОвĐģĐĩĐŊиĐĩ вĐĩŅ€ŅĐ¸Đš FastAPI { #upgrading-the-fastapi-versions } ВаĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ‚Đĩҁ҂ҋ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. @@ -70,9 +70,9 @@ fastapi>=0.45.0,<0.46.0 ĐŸĐžŅĐģĐĩ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ Ņ‚ĐĩŅŅ‚ĐžĐ˛ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ОйĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ŅĐ˛ĐžŅŽ вĐĩŅ€ŅĐ¸ŅŽ **FastAPI** Đ´Đž йОĐģĐĩĐĩ ĐŊОвОК. ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ҁĐģĐĩĐ´ŅƒĐĩŅ‚ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž Đ˛Đ°Ņˆ ĐēОд Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž, СаĐŋŅƒŅŅ‚Đ¸Đ˛ Ņ‚Đĩҁ҂ҋ. -Đ•ŅĐģи Đ˛ŅĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž, иĐģи ĐŋĐžŅĐģĐĩ вĐŊĐĩҁĐĩĐŊĐ¸Ņ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ иСĐŧĐĩĐŊĐĩĐŊиК Đ˛ŅĐĩ Đ˛Đ°ŅˆĐ¸ Ņ‚Đĩҁ҂ҋ ĐŋŅ€ĐžŅ…ĐžĐ´ŅŅ‚, Ņ‚ĐžĐģҌĐēĐž Ņ‚ĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐēŅ€ĐĩĐŋĐ¸Ņ‚ŅŒ Đ˛Đ°ŅˆŅƒ ĐŊĐžĐ˛ŅƒŅŽ вĐĩŅ€ŅĐ¸ŅŽ `fastapi`. +Đ•ŅĐģи Đ˛ŅŅ‘ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊĐž, иĐģи ĐŋĐžŅĐģĐĩ вĐŊĐĩҁĐĩĐŊĐ¸Ņ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ иСĐŧĐĩĐŊĐĩĐŊиК Đ˛ŅĐĩ Đ˛Đ°ŅˆĐ¸ Ņ‚Đĩҁ҂ҋ ĐŋŅ€ĐžŅ…ĐžĐ´ŅŅ‚, Ņ‚ĐžĐģҌĐēĐž Ņ‚ĐžĐŗĐ´Đ° Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐēŅ€ĐĩĐŋĐ¸Ņ‚ŅŒ Đ˛Đ°ŅˆŅƒ ĐŊĐžĐ˛ŅƒŅŽ вĐĩŅ€ŅĐ¸ŅŽ `fastapi`. -## О Starlette +## О Starlette { #about-starlette } НĐĩ ҁĐģĐĩĐ´ŅƒĐĩŅ‚ СаĐēŅ€ĐĩĐŋĐģŅŅ‚ŅŒ вĐĩŅ€ŅĐ¸ŅŽ `starlette`. @@ -80,14 +80,14 @@ fastapi>=0.45.0,<0.46.0 ĐĸаĐē Ņ‡Ņ‚Đž Ņ€Đĩ҈ĐĩĐŊиĐĩ Ой Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧОК вĐĩŅ€ŅĐ¸Đ¸ Starlette, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ **FastAPI**. -## О Pydantic +## О Pydantic { #about-pydantic } Pydantic вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ŅĐ˛ĐžĐ¸ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊŅ‹Đĩ Ņ‚Đĩҁ҂ҋ Đ´ĐģŅ **FastAPI**, Ņ‚Đ°Đē Ņ‡Ņ‚Đž ĐŊĐžĐ˛Ņ‹Đĩ вĐĩŅ€ŅĐ¸Đ¸ Pydantic (Đ˛Ņ‹ŅˆĐĩ `1.0.0`) Đ˛ŅĐĩĐŗĐ´Đ° ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹ ҁ FastAPI. -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐēŅ€ĐĩĐŋĐ¸Ņ‚ŅŒ ĐģŅŽĐąŅƒŅŽ вĐĩŅ€ŅĐ¸ŅŽ Pydantic, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ваĐŧ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚, Đ˛Ņ‹ŅˆĐĩ `1.0.0` и ĐŊиĐļĐĩ `2.0.0`. +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐēŅ€ĐĩĐŋĐ¸Ņ‚ŅŒ ĐģŅŽĐąŅƒŅŽ вĐĩŅ€ŅĐ¸ŅŽ Pydantic, ĐēĐžŅ‚ĐžŅ€Đ°Ņ ваĐŧ ĐŋĐžĐ´Ņ…ĐžĐ´Đ¸Ņ‚, Đ˛Ņ‹ŅˆĐĩ `1.0.0`. НаĐŋŅ€Đ¸ĐŧĐĩŅ€: ```txt -pydantic>=1.2.0,<2.0.0 +pydantic>=2.7.0,<3.0.0 ``` diff --git a/docs/ru/docs/environment-variables.md b/docs/ru/docs/environment-variables.md index a6c7b0c77..6291b79d2 100644 --- a/docs/ru/docs/environment-variables.md +++ b/docs/ru/docs/environment-variables.md @@ -1,6 +1,6 @@ -# ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ +# ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ { #environment-variables } -/// tip +/// tip | ХОвĐĩŅ‚ Đ•ŅĐģи Đ˛Ņ‹ ҃ĐļĐĩ СĐŊаĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ ÂĢĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸ŅÂģ и ĐēаĐē Đ¸Ņ… Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ, ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ŅŅ‚Đž. @@ -10,7 +10,7 @@ ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊŅ‹ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ **ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи** ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК, ĐēаĐē Ņ‡Đ°ŅŅ‚ŅŒ **ŅƒŅŅ‚Đ°ĐŊОвĐēи** Python и Ņ‚.Đ´. -## ХОСдаĐŊиĐĩ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ +## ХОСдаĐŊиĐĩ и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ { #create-and-use-env-vars } МоĐļĐŊĐž **ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ** и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ в **ОйОĐģĐžŅ‡ĐēĐĩ (Ņ‚ĐĩŅ€ĐŧиĐŊаĐģĐĩ)**, ĐŊĐĩ ĐŋŅ€Đ¸ĐąĐĩĐŗĐ°Ņ Đē ĐŋĐžĐŧĐžŅ‰Đ¸ Python: @@ -50,7 +50,7 @@ Hello Wade Wilson //// -## Đ§Ņ‚ĐĩĐŊиĐĩ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ в python +## Đ§Ņ‚ĐĩĐŊиĐĩ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ в python { #read-env-vars-in-python } ĐĸаĐē ĐļĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ **вĐŊĐĩ** Python, в Ņ‚ĐĩŅ€ĐŧиĐŊаĐģĐĩ (иĐģи ĐģŅŽĐąŅ‹Đŧ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁĐŋĐžŅĐžĐąĐžĐŧ), а ĐˇĐ°Ņ‚ĐĩĐŧ **҇҂ĐĩĐŊĐ¸Ņ Đ¸Ņ… в Python**. @@ -63,11 +63,12 @@ name = os.getenv("MY_NAME", "World") print(f"Hello {name} from Python") ``` -/// tip +/// tip | ХОвĐĩŅ‚ -Đ’Ņ‚ĐžŅ€ĐžĐš Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ `os.getenv()` - ŅŅ‚Đž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ. +Đ’Ņ‚ĐžŅ€ĐžĐš Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ `os.getenv()` - ŅŅ‚Đž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧĐžĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ. Đ•ŅĐģи СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŊĐĩ ҃ĐēаСаĐŊĐž, Ņ‚Đž ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐžĐŊĐž Ņ€Đ°Đ˛ĐŊĐž `None`. В даĐŊĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐŧŅ‹ ҃ĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩĐŧ `ÂĢWorldÂģ` в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. + /// Đ—Đ°Ņ‚ĐĩĐŧ ĐŧĐžĐļĐŊĐž СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ŅŅ‚Ņƒ ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ҃ ĐŊа Python: @@ -150,13 +151,13 @@ Hello World from Python
-/// tip +/// tip | ХОвĐĩŅ‚ ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Ой ŅŅ‚ĐžĐŧ ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ ĐŊа ŅĐ°ĐšŅ‚Đĩ The Twelve-Factor App: Config. /// -## ĐĸиĐŋĐ¸ĐˇĐ°Ņ†Đ¸Ņ и ВаĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ +## ĐĸиĐŋĐ¸ĐˇĐ°Ņ†Đ¸Ņ и ВаĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ { #types-and-validation } Đ­Ņ‚Đ¸ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ ĐŧĐžĐŗŅƒŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ Ņ‚ĐžĐģҌĐēĐž ҁ **Ņ‚ĐĩĐēŅŅ‚ĐžĐ˛Ņ‹Đŧи ŅŅ‚Ņ€ĐžĐēаĐŧи**, ĐŋĐžŅĐēĐžĐģҌĐē҃ ĐžĐŊи ŅĐ˛ĐģŅŅŽŅ‚ŅŅ вĐŊĐĩ҈ĐŊиĐŧи ĐŋĐž ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸ŅŽ Đē Python и Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Ņ‚ŅŒ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹ ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧаĐŧи и ĐžŅŅ‚Đ°ĐģҌĐŊОК ŅĐ¸ŅŅ‚ĐĩĐŧОК (и даĐļĐĩ ҁ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊŅ‹Đŧи ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊŅ‹Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи, Ņ‚Đ°ĐēиĐŧи ĐēаĐē Linux, Windows, macOS). @@ -164,7 +165,7 @@ Hello World from Python ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Ой Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ Đ´ĐģŅ Ņ€Đ°ĐąĐžŅ‚Ņ‹ ҁ **ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ** Đ˛Ņ‹ ŅƒĐˇĐŊаĐĩŅ‚Đĩ в [Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊĐŊĐžĐĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ - ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи и ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ҁҀĐĩĐ´Ņ‹](./advanced/settings.md){.internal-link target=_blank}. -## ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ `PATH` +## ПĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ `PATH` { #path-environment-variable } ĐĄŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ **ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊĐ°Ņ** ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊĐ°Ņ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ **`PATH`**, ĐēĐžŅ‚ĐžŅ€Đ°Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ĐžĐŊĐŊŅ‹Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи (Linux, macOS, Windows) Đ´ĐģŅ ĐŋĐžĐ¸ŅĐēа ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧ Đ´ĐģŅ СаĐŋ҃ҁĐēа. @@ -208,7 +209,7 @@ C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System3 Đ•ŅĐģи ĐžĐŊа ĐĩĐĩ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚, Ņ‚Đž **Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ĐĩĐĩ**. В ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ ĐžĐŊа ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐĩŅ‚ Đ¸ŅĐēĐ°Ņ‚ŅŒ в **Đ´Ņ€ŅƒĐŗĐ¸Ņ… ĐēĐ°Ņ‚Đ°ĐģĐžĐŗĐ°Ņ…**. -### ĐŖŅŅ‚Đ°ĐŊОвĐēа Python и ОйĐŊОвĐģĐĩĐŊиĐĩ `PATH` +### ĐŖŅŅ‚Đ°ĐŊОвĐēа Python и ОйĐŊОвĐģĐĩĐŊиĐĩ `PATH` { #installing-python-and-updating-the-path } ĐŸŅ€Đ¸ ŅƒŅŅ‚Đ°ĐŊОвĐēĐĩ Python Đ˛Đ°Ņ ĐŧĐžĐŗŅƒŅ‚ ҁĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ, ĐŊ҃ĐļĐŊĐž Đģи ОйĐŊĐžĐ˛Đ¸Ņ‚ŅŒ ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅƒŅŽ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ `PATH`. @@ -286,7 +287,7 @@ $ C:\opt\custompython\bin\python Đ­Ņ‚Đ° иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐģĐĩСĐŊа ĐŋŅ€Đ¸ Đ¸ĐˇŅƒŅ‡ĐĩĐŊии [Đ’Đ¸Ņ€Ņ‚ŅƒĐ°ĐģҌĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊиК](virtual-environments.md){.internal-link target=_blank}. -## Đ’Ņ‹Đ˛ĐžĐ´ +## Đ’Ņ‹Đ˛ĐžĐ´ { #conclusion } БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃ Đ˛Ņ‹ Đ´ĐžĐģĐļĐŊŅ‹ иĐŧĐĩŅ‚ŅŒ йаСОвОĐĩ ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģĐĩĐŊиĐĩ Đž Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž Ņ‚Đ°ĐēĐžĐĩ **ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ** и ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… в Python. diff --git a/docs/ru/docs/fastapi-cli.md b/docs/ru/docs/fastapi-cli.md index c0be4a5df..156e3d200 100644 --- a/docs/ru/docs/fastapi-cli.md +++ b/docs/ru/docs/fastapi-cli.md @@ -1,4 +1,4 @@ -# FastAPI CLI +# FastAPI CLI { #fastapi-cli } **FastAPI CLI** ŅŅ‚Đž ĐŋŅ€ĐžĐŗŅ€Đ°ĐŧĐŧа ĐēĐžĐŧаĐŊĐ´ĐŊОК ŅŅ‚Ņ€ĐžĐēи, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´ĐģŅ СаĐŋ҃ҁĐēа Đ˛Đ°ŅˆĐĩĐŗĐž FastAPI ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ, Đ´ĐģŅ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸Ņ FastAPI-ĐŋŅ€ĐžĐĩĐēŅ‚ĐžĐŧ, а Ņ‚Đ°ĐēĐļĐĩ Đ´ĐģŅ ĐŧĐŊĐžĐŗĐ¸Ņ… Đ´Ņ€ŅƒĐŗĐ¸Ņ… вĐĩ҉ĐĩĐš. @@ -50,26 +50,26 @@ $ fastapi dev Uvicorn, Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš, ĐŗĐžŅ‚ĐžĐ˛Ņ‹Đš Đē Ņ€Đ°ĐąĐžŅ‚Đĩ в production ҁĐĩŅ€Đ˛ĐĩŅ€ ASGI. 😎 +ВĐŊŅƒŅ‚Ņ€Đ¸ **FastAPI CLI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Uvicorn, Đ˛Ņ‹ŅĐžĐēĐžĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš, ĐŗĐžŅ‚ĐžĐ˛Ņ‹Đš Đē Ņ€Đ°ĐąĐžŅ‚Đĩ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊĐĩ ASGI-ҁĐĩŅ€Đ˛ĐĩŅ€. 😎 -## `fastapi dev` +## `fastapi dev` { #fastapi-dev } Đ’Ņ‹ĐˇĐžĐ˛ `fastapi dev` СаĐŋ҃ҁĐēаĐĩŅ‚ Ņ€ĐĩĐļиĐŧ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи. -По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ вĐēĐģŅŽŅ‡ĐĩĐŊа Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа (**auto-reload**), ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃ ĐŋŅ€Đ¸ иСĐŧĐĩĐŊĐĩĐŊии ĐēОда ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. Đ­Ņ‚Đ° ŅƒŅŅ‚Đ°ĐŊОвĐēа ҂ҀĐĩĐąŅƒĐĩŅ‚ СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ и Đ´ĐĩĐģаĐĩŅ‚ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ ĐŧĐĩĐŊĐĩĐĩ ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊОК. Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐĩŅ‘ Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ. ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁĐģŅƒŅˆĐ°ĐĩŅ‚ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ĐŊа IP `127.0.0.1`. Đ­Ņ‚Đž IP Đ°Đ´Ņ€Đĩҁ Đ˛Đ°ŅˆĐĩĐš ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, ĐŋŅ€ĐĩĐ´ĐŊаСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ‹Đš Đ´ĐģŅ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐ¸Ņ… ĐēĐžĐŧĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Đš (`localhost`). +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ вĐēĐģŅŽŅ‡ĐĩĐŊа Đ°Đ˛Ņ‚Đž-ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа (**auto-reload**), ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃ ĐŋŅ€Đ¸ иСĐŧĐĩĐŊĐĩĐŊии ĐēОда ĐŋŅ€ĐžĐ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа ҁĐĩŅ€Đ˛ĐĩŅ€Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. Đ­Ņ‚Đ° ŅƒŅŅ‚Đ°ĐŊОвĐēа ҂ҀĐĩĐąŅƒĐĩŅ‚ СĐŊĐ°Ņ‡Đ¸Ņ‚ĐĩĐģҌĐŊҋ҅ Ņ€ĐĩŅŅƒŅ€ŅĐžĐ˛ и Đ´ĐĩĐģаĐĩŅ‚ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ ĐŧĐĩĐŊĐĩĐĩ ŅŅ‚Đ°ĐąĐ¸ĐģҌĐŊОК. Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐĩŅ‘ Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€Đ¸ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ. ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁĐģŅƒŅˆĐ°ĐĩŅ‚ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ĐŊа IP `127.0.0.1`. Đ­Ņ‚Đž IP Đ°Đ´Ņ€Đĩҁ Đ˛Đ°ŅˆĐĩĐš ĐŧĐ°ŅˆĐ¸ĐŊŅ‹, ĐŋŅ€ĐĩĐ´ĐŊаСĐŊĐ°Ņ‡ĐĩĐŊĐŊŅ‹Đš Đ´ĐģŅ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊĐ¸Ņ… ĐēĐžĐŧĐŧ҃ĐŊиĐēĐ°Ņ†Đ¸Đš (`localhost`). -## `fastapi run` +## `fastapi run` { #fastapi-run } -Đ’Ņ‹ĐˇĐžĐ˛ `fastapi run` ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ СаĐŋ҃ҁĐēаĐĩŅ‚ FastAPI в Ņ€ĐĩĐļиĐŧĐĩ production. +Đ’Ņ‹ĐˇĐžĐ˛ `fastapi run` ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ СаĐŋ҃ҁĐēаĐĩŅ‚ FastAPI в Ņ€ĐĩĐļиĐŧĐĩ ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ. -По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēи **auto-reload** ĐžŅ‚ĐēĐģŅŽŅ‡ĐĩĐŊа. ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁĐģŅƒŅˆĐ°ĐĩŅ‚ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ĐŊа IP `0.0.0.0`, Ņ‚.Đĩ. ĐŊа Đ˛ŅĐĩŅ… Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ Đ°Đ´Ņ€ĐĩŅĐ°Ņ… ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đ°. ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŒŅŅ в ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐĩ Đ´ĐģŅ ĐģŅŽĐąĐžĐŗĐž, ĐēŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐ´ŅĐžĐĩдиĐŊĐ¸Ņ‚ŅŒŅŅ Đē Đ˛Đ°ŅˆĐĩĐš ĐŧĐ°ŅˆĐ¸ĐŊĐĩ. ĐŸŅ€ĐžĐ´ŅƒĐēŅ‚ĐžĐ˛Ņ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ŅŅ иĐŧĐĩĐŊĐŊĐž Ņ‚Đ°Đē, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛. +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ Đ°Đ˛Ņ‚Đž-ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐēа (**auto-reload**) ĐžŅ‚ĐēĐģŅŽŅ‡ĐĩĐŊа. ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҁĐģŅƒŅˆĐ°ĐĩŅ‚ Đ˛Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ ĐŋОдĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ĐŊа IP `0.0.0.0`, Ņ‚.Đĩ. ĐŊа Đ˛ŅĐĩŅ… Đ´ĐžŅŅ‚ŅƒĐŋĐŊҋ҅ Đ°Đ´Ņ€ĐĩŅĐ°Ņ… ĐēĐžĐŧĐŋŅŒŅŽŅ‚ĐĩŅ€Đ°. ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŊĐ°Ņ…ĐžĐ´Đ¸Ņ‚ŅŒŅŅ в ĐŋŅƒĐąĐģĐ¸Ņ‡ĐŊĐžĐŧ Đ´ĐžŅŅ‚ŅƒĐŋĐĩ Đ´ĐģŅ ĐģŅŽĐąĐžĐŗĐž, ĐēŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐ´ŅĐžĐĩдиĐŊĐ¸Ņ‚ŅŒŅŅ Đē Đ˛Đ°ŅˆĐĩĐš ĐŧĐ°ŅˆĐ¸ĐŊĐĩ. ĐŸŅ€ĐžĐ´ŅƒĐēŅ‚ĐžĐ˛Ņ‹Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ СаĐŋ҃ҁĐēĐ°ŅŽŅ‚ŅŅ иĐŧĐĩĐŊĐŊĐž Ņ‚Đ°Đē, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐēĐžĐŊŅ‚ĐĩĐšĐŊĐĩŅ€ĐžĐ˛. В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв Đ˛Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ (и Đ´ĐžĐģĐļĐŊŅ‹) Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋŅ€ĐžĐēŅĐ¸-ҁĐĩŅ€Đ˛ĐĩŅ€ ("termination proxy"), ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ HTTPS ĐŋОвĐĩҀ҅ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ. Đ’ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ ĐˇĐ°Đ˛Đ¸ŅĐĩŅ‚ŅŒ ĐžŅ‚ Ņ‚ĐžĐŗĐž, ĐēаĐē Đ˛Ņ‹ Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ: Са Đ˛Đ°Ņ ŅŅ‚Đž ĐģийО ŅĐ´ĐĩĐģаĐĩŅ‚ Đ˛Đ°Ņˆ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€, ĐģийО ваĐŧ ĐŋŅ€Đ¸Đ´ĐĩŅ‚ŅŅ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž. /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ йОĐģҌ҈Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ Ой ŅŅ‚ĐžĐŧ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŋĐž Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸ŅŽ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиК [deployment documentation](deployment/index.md){.internal-link target=_blank}. +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ йОĐģҌ҈Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ Ой ŅŅ‚ĐžĐŧ в [Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŋĐž Ņ€Đ°ĐˇĐ˛ĐĩŅ€Ņ‚Ņ‹Đ˛Đ°ĐŊĐ¸ŅŽ](deployment/index.md){.internal-link target=_blank}. /// diff --git a/docs/ru/docs/features.md b/docs/ru/docs/features.md index 77d6b936a..91ffe331b 100644 --- a/docs/ru/docs/features.md +++ b/docs/ru/docs/features.md @@ -1,23 +1,21 @@ -# ĐžŅĐŊОвĐŊŅ‹Đĩ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đ° +# ВозĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ { #features } -## ĐžŅĐŊОвĐŊŅ‹Đĩ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đ° FastAPI +## ВозĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ FastAPI { #fastapi-features } **FastAPI** ĐŋŅ€ĐĩĐ´ĐģĐ°ĐŗĐ°ĐĩŅ‚ ваĐŧ ҁĐģĐĩĐ´ŅƒŅŽŅ‰ĐĩĐĩ: -### Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐžŅ‚ĐēҀҋ҂ҋ҅ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐ˛ +### ĐžŅĐŊОваĐŊĐž ĐŊа ĐžŅ‚ĐēҀҋ҂ҋ҅ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ°Ņ… { #based-on-open-standards } -* OpenAPI Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API, вĐēĐģŅŽŅ‡Đ°Ņ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸, ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛, Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ°, ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ и Ņ‚.Đ´. - - -* ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐŧОдĐĩĐģĐĩĐš даĐŊĐŊҋ҅ в ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛Đ¸Đ¸ ҁ JSON Schema (Ņ‚Đ°Đē ĐēаĐē ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ OpenAPI ŅĐ°Đŧа ĐžŅĐŊОваĐŊа ĐŊа JSON Schema). -* Đ Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊ, ĐŋŅ€Đ¸Đ´ĐĩŅ€ĐļĐ¸Đ˛Đ°ŅŅŅŒ ŅŅ‚Đ¸Ņ… ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐ˛, ĐŋĐžŅĐģĐĩ Ņ‚Ņ‰Đ°Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž Đ¸Ņ… Đ¸ĐˇŅƒŅ‡ĐĩĐŊĐ¸Ņ. Đ­Ņ‚Đ¸ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Ņ‹ иСĐŊĐ°Ņ‡Đ°ĐģҌĐŊĐž вĐēĐģŅŽŅ‡ĐĩĐŊŅ‹ вО ҄ҀĐĩĐšĐŧŅ„ĐžŅ€Đē, а ĐŊĐĩ ŅĐ˛ĐģŅŅŽŅ‚ŅŅ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊОК ĐŊĐ°Đ´ŅŅ‚Ņ€ĐžĐšĐēОК. +* OpenAPI Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ API, вĐēĐģŅŽŅ‡Đ°Ņ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸, ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛, Ņ‚ĐĩĐģ СаĐŋŅ€ĐžŅĐžĐ˛, ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ и Ņ‚. Đ´. +* ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ ĐŧОдĐĩĐģĐĩĐš даĐŊĐŊҋ҅ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ JSON Schema (Ņ‚Đ°Đē ĐēаĐē ŅĐ°Đŧа ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ OpenAPI ĐžŅĐŊОваĐŊа ĐŊа JSON Schema). +* Đ Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊ вОĐēŅ€ŅƒĐŗ ŅŅ‚Đ¸Ņ… ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐ˛, ĐŋĐžŅĐģĐĩ Ņ‚Ņ‰Đ°Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž Đ¸Ņ… Đ¸ĐˇŅƒŅ‡ĐĩĐŊĐ¸Ņ. Đ­Ņ‚Đž ĐŊĐĩ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊĐ°Ņ ĐŊĐ°Đ´ŅŅ‚Ņ€ĐžĐšĐēа ĐŋОвĐĩҀ҅. * Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ĐŋОСвОĐģŅĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ **ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐēĐģиĐĩĐŊ҂ҁĐēĐžĐŗĐž ĐēОда** ĐŊа ĐŧĐŊĐžĐŗĐ¸Ņ… ŅĐˇŅ‹ĐēĐ°Ņ…. -### ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩĐŧĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ +### ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ { #automatic-docs } -ИĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ Đ´ĐģŅ API и Đ¸ŅŅĐģĐĩдОваĐŊĐ¸Ņ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐ˛. ĐŸĐžŅĐēĐžĐģҌĐē҃ ŅŅ‚ĐžŅ‚ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē ĐžŅĐŊОваĐŊ ĐŊа OpenAPI, ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐ˛ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, 2 иС ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… вĐēĐģŅŽŅ‡ĐĩĐŊŅ‹ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. +ИĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊĐ°Ņ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ Đ´ĐģŅ API и Đ¸ŅŅĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ вĐĩĐą-иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅ‹. ĐŸĐžŅĐēĐžĐģҌĐē҃ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē ĐžŅĐŊОваĐŊ ĐŊа OpenAPI, ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒĐĩŅ‚ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐ˛ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ, 2 иС ĐŊĐ¸Ņ… вĐēĐģŅŽŅ‡ĐĩĐŊŅ‹ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. -* Swagger UI, ҁ иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊŅ‹Đŧ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛Đ¸ĐĩĐŧ, Đ˛Ņ‹ĐˇŅ‹Đ˛Đ°ĐĩŅ‚ и Ņ‚ĐĩŅŅ‚Đ¸Ņ€ŅƒĐĩŅ‚ Đ˛Đ°Ņˆ API ĐŋŅ€ŅĐŧĐž иС ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°. +* Swagger UI, ҁ иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊŅ‹Đŧ Đ¸ŅŅĐģĐĩдОваĐŊиĐĩĐŧ, Đ˛Ņ‹ĐˇĐžĐ˛ĐžĐŧ и Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩĐŧ Đ˛Đ°ŅˆĐĩĐŗĐž API ĐŋŅ€ŅĐŧĐž иС ĐąŅ€Đ°ŅƒĐˇĐĩŅ€Đ°. ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) @@ -25,22 +23,21 @@ ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### ĐĸĐžĐģҌĐēĐž ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš Python +### ĐĸĐžĐģҌĐēĐž ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš Python { #just-modern-python } -Đ’ŅĐĩ ŅŅ‚Đ¸ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ĐžŅĐŊОваĐŊŅ‹ ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊҋ҅ **аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŅ… Ņ‚Đ¸ĐŋОв Python 3.8** (ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ Pydantic). НĐĩ ĐŊ҃ĐļĐŊĐž Đ¸ĐˇŅƒŅ‡Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đš ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ. ĐĸĐžĐģҌĐēĐž ĐģĐ¸ŅˆŅŒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đš ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš Python. +Đ’ŅĐĩ ĐžŅĐŊОваĐŊĐž ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊҋ҅ **аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŅ… Ņ‚Đ¸ĐŋОв Python** (ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ Pydantic). НĐĩ ĐŊ҃ĐļĐŊĐž Đ¸ĐˇŅƒŅ‡Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đš ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ. ĐĸĐžĐģҌĐēĐž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đš ŅĐžĐ˛Ņ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đš Python. -Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž ĐžŅĐ˛ĐĩĐļĐ¸Ņ‚ŅŒ СĐŊаĐŊĐ¸Ņ, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв в Python (даĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI), Đ˛Ņ‹Đ´ĐĩĐģĐ¸Ņ‚Đĩ 2 ĐŧиĐŊŅƒŅ‚Ņ‹ и ĐŋŅ€ĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ĐēŅ€Đ°Ņ‚ĐēĐžĐĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž: [ВвĐĩĐ´ĐĩĐŊиĐĩ в аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв PythonÂļ -](python-types.md){.internal-link target=_blank}. +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž ĐžŅĐ˛ĐĩĐļĐ¸Ņ‚ŅŒ СĐŊаĐŊĐ¸Ņ Đž Ņ‚Đ¸ĐŋĐ°Ņ… в Python (даĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ ĐŊĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI), Đ˛Ņ‹Đ´ĐĩĐģĐ¸Ņ‚Đĩ 2 ĐŧиĐŊŅƒŅ‚Ņ‹ и ĐŋŅ€ĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ĐēŅ€Đ°Ņ‚ĐēĐžĐĩ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž: [ĐĸиĐŋŅ‹ Python](python-types.md){.internal-link target=_blank}. -Đ’Ņ‹ ĐŋĐ¸ŅˆĐĩŅ‚Đĩ ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊĐžĐŧ Python ҁ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅĐŧи Ņ‚Đ¸ĐŋОв: +Đ’Ņ‹ ĐŋĐ¸ŅˆĐĩŅ‚Đĩ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đš Python ҁ Ņ‚Đ¸ĐŋаĐŧи: ```Python from datetime import date from pydantic import BaseModel -# ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ user_id ҁ Ņ‚Đ¸ĐŋĐžĐŧ `str` -# и ĐŋĐžĐģŅƒŅ‡Đ°ĐĩĐŧ ĐŋОддĐĩŅ€ĐļĐē҃ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ +# ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ ĐēаĐē `str` +# и ĐŋĐžĐģŅƒŅ‡Đ°ĐĩĐŧ ĐŋОддĐĩŅ€ĐļĐē҃ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ° ĐēОда вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ def main(user_id: str): return user_id @@ -70,17 +67,17 @@ my_second_user: User = User(**second_user_data) `**second_user_data` ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚: -ПĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐēĐģŅŽŅ‡Đ¸ и СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ҁĐģĐžĐ˛Đ°Ņ€Ņ `second_user_data`, в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ Ņ‚Đ¸Đŋа "ĐēĐģŅŽŅ‡-СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ", ŅŅ‚Đž ŅĐēвиваĐģĐĩĐŊŅ‚ĐŊĐž: `User(id=4, name="Mary", joined="2018-11-30")` . +ПĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐēĐģŅŽŅ‡Đ¸ и СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ ҁĐģĐžĐ˛Đ°Ņ€Ņ `second_user_data` в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ "ĐēĐģŅŽŅ‡-СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ", ŅĐēвиваĐģĐĩĐŊŅ‚ĐŊĐž: `User(id=4, name="Mary", joined="2018-11-30")` /// -### ПоддĐĩŅ€ĐļĐēа Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛ (IDE) +### ПоддĐĩŅ€ĐļĐēа Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛ (IDE) { #editor-support } ВĐĩҁҌ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đē ĐąŅ‹Đģ ĐŋŅ€ĐžĐ´ŅƒĐŧаĐŊ Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ ĐąŅ‹Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Ņ‹Đŧ и иĐŊŅ‚ŅƒĐ¸Ņ‚Đ¸Đ˛ĐŊĐž ĐŋĐžĐŊŅŅ‚ĐŊŅ‹Đŧ в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии, Đ˛ŅĐĩ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ ĐąŅ‹Đģи ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊŅ‹ ĐŊа ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đĩ Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛ Đĩ҉Đĩ Đ´Đž ĐŊĐ°Ņ‡Đ°Đģа Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи, Ņ‡Ņ‚ĐžĐąŅ‹ ОйĐĩҁĐŋĐĩŅ‡Đ¸Ņ‚ŅŒ ĐŊаиĐģŅƒŅ‡ŅˆĐ¸Đĩ ҃ҁĐģĐžĐ˛Đ¸Ņ ĐŋŅ€Đ¸ ĐŊаĐŋĐ¸ŅĐ°ĐŊии ĐēОда. -В ĐžĐŋŅ€ĐžŅĐĩ Python-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв ĐąŅ‹ĐģĐž Đ˛Ņ‹ŅŅĐŊĐĩĐŊĐž, Ņ‡Ņ‚Đž ĐŊаийОĐģĐĩĐĩ Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧОК Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛, ŅĐ˛ĐģŅĐĩŅ‚ŅŅ "Đ°Đ˛Ņ‚ĐžĐ´ĐžĐŋĐžĐģĐŊĐĩĐŊиĐĩ". +В ĐžĐŋŅ€ĐžŅĐ°Ņ… Pythonâ€‘Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв видĐŊĐž, Ņ‡Ņ‚Đž ОдĐŊОК иС ŅĐ°Đŧҋ҅ Ņ‡Đ°ŅŅ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ Ņ„ŅƒĐŊĐēŅ†Đ¸Đš ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ÂĢĐ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩÂģ. -Đ’ŅŅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° **FastAPI** ĐžŅĐŊОваĐŊа ĐŊа ŅƒĐ´ĐžĐ˛ĐģĐĩŅ‚Đ˛ĐžŅ€ĐĩĐŊии ŅŅ‚ĐžĐš вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸. ĐĐ˛Ņ‚ĐžĐ´ĐžĐŋĐžĐģĐŊĐĩĐŊиĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ вĐĩСдĐĩ. +Đ’ŅŅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° **FastAPI** ĐžŅĐŊОваĐŊа ĐŊа ŅƒĐ´ĐžĐ˛ĐģĐĩŅ‚Đ˛ĐžŅ€ĐĩĐŊии ŅŅ‚ĐžĐš вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸. ĐĐ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚ вĐĩСдĐĩ. ВаĐŧ Ņ€ĐĩĐ´ĐēĐž ĐŊ҃ĐļĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒŅŅ Đē Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. @@ -94,23 +91,23 @@ my_second_user: User = User(**second_user_data) ![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png) -Đ’Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐ´ĐžĐŋĐžĐģĐŊĐĩĐŊиĐĩ ĐēОда даĐļĐĩ Ņ‚Đ°Đŧ, ĐŗĐ´Đĩ Đ˛Ņ‹ ŅŅ‡Đ¸Ņ‚Đ°Đģи ŅŅ‚Đž ĐŊĐĩвОСĐŧĐžĐļĐŊŅ‹Đŧ Ņ€Đ°ĐŊҌ҈Đĩ. -КаĐē ĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐģŅŽŅ‡ `price` вĐŊŅƒŅ‚Ņ€Đ¸ Ņ‚ĐĩĐģа JSON (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧ), ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‰ĐĩĐŗĐž в СаĐŋŅ€ĐžŅĐĩ. +Đ’Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ ĐēОда даĐļĐĩ Ņ‚Đ°Đŧ, ĐŗĐ´Đĩ Đ˛Ņ‹ ŅŅ‡Đ¸Ņ‚Đ°Đģи ŅŅ‚Đž ĐŊĐĩвОСĐŧĐžĐļĐŊŅ‹Đŧ Ņ€Đ°ĐŊҌ҈Đĩ. КаĐē ĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐģŅŽŅ‡ `price` вĐŊŅƒŅ‚Ņ€Đ¸ Ņ‚ĐĩĐģа JSON (ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ вĐģĐžĐļĐĩĐŊĐŊŅ‹Đŧ), ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‰ĐĩĐŗĐž в СаĐŋŅ€ĐžŅĐĩ. -БоĐģҌ҈Đĩ ĐŊиĐēаĐēĐ¸Ņ… ĐŊĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊҋ҅ иĐŧŅ‘ĐŊ ĐēĐģŅŽŅ‡ĐĩĐš, ĐŧĐĩŅ‚Đ°ĐŊĐ¸Ņ ĐŋĐž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ иĐģи ĐŋŅ€ĐžĐēŅ€ŅƒŅ‡Đ¸Đ˛Đ°ĐŊĐ¸Ņ ĐēОда ввĐĩҀ҅ и вĐŊиС, в ĐŋĐžĐŋҋ҂ĐēĐ°Ņ… ŅƒĐˇĐŊĐ°Ņ‚ŅŒ - Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи Đ˛Ņ‹ Ņ€Đ°ĐŊĐĩĐĩ `username` иĐģи `user_name`. +БоĐģҌ҈Đĩ ĐŊиĐēаĐēĐ¸Ņ… ĐŊĐĩĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊҋ҅ иĐŧŅ‘ĐŊ ĐēĐģŅŽŅ‡ĐĩĐš, ĐŧĐĩŅ‚Đ°ĐŊĐ¸Ņ ĐŋĐž Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ иĐģи ĐŋŅ€ĐžĐēŅ€ŅƒŅ‡Đ¸Đ˛Đ°ĐŊĐ¸Ņ ĐēОда ввĐĩҀ҅ и вĐŊиС в ĐŋĐžĐŋҋ҂ĐēĐ°Ņ… ŅƒĐˇĐŊĐ°Ņ‚ŅŒ — Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģи Đ˛Ņ‹ Ņ€Đ°ĐŊĐĩĐĩ `username` иĐģи `user_name`. -### ĐšŅ€Đ°Ņ‚ĐēĐžŅŅ‚ŅŒ -FastAPI иĐŧĐĩĐĩŅ‚ ĐŋŅ€ĐžĐ´ŅƒĐŧаĐŊĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ **ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ** Đ´ĐģŅ Đ˛ŅĐĩĐŗĐž, ҁ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐģҌĐŊŅ‹Đŧи ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи вĐĩСдĐĩ. Đ’ŅĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ‚ĐžĐŊĐēĐž ĐŋĐžĐ´ŅŅ‚Ņ€ĐžĐĩĐŊŅ‹ Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ Đ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‚Đž, Ņ‡Ņ‚Đž ваĐŧ ĐŊ҃ĐļĐŊĐž и ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đš ваĐŧ API. +### ĐšŅ€Đ°Ņ‚ĐēĐžŅŅ‚ŅŒ { #short } -Но, ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, Đ˛ŅŅ‘ ŅŅ‚Đž **"и Ņ‚Đ°Đē Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚"**. +FastAPI иĐŧĐĩĐĩŅ‚ ĐŋŅ€ĐžĐ´ŅƒĐŧаĐŊĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ **ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ** Đ´ĐģŅ Đ˛ŅĐĩĐŗĐž, ҁ ĐžĐŋŅ†Đ¸ĐžĐŊаĐģҌĐŊŅ‹Đŧи ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи вĐĩСдĐĩ. Đ’ŅĐĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ‚ĐžĐŊĐēĐž ĐŋĐžĐ´ŅŅ‚Ņ€ĐžĐĩĐŊŅ‹ Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ Đ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‚Đž, Ņ‡Ņ‚Đž ваĐŧ ĐŊ҃ĐļĐŊĐž, и ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đš ваĐŧ API. -### ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа СĐŊĐ°Ņ‡ĐĩĐŊиК +Но ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ Đ˛ŅŅ‘ **ÂĢĐŋŅ€ĐžŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚Âģ**. -* ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа СĐŊĐ°Ņ‡ĐĩĐŊиК Đ´ĐģŅ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đ° (иĐģи Đ˛ŅĐĩŅ…?) **Ņ‚Đ¸ĐŋОв даĐŊĐŊҋ҅** Python, вĐēĐģŅŽŅ‡Đ°Ņ: +### ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа СĐŊĐ°Ņ‡ĐĩĐŊиК { #validation } + +* ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа СĐŊĐ°Ņ‡ĐĩĐŊиК Đ´ĐģŅ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đ° (иĐģи Đ˛ŅĐĩŅ…?) **Ņ‚Đ¸ĐŋОв даĐŊĐŊҋ҅** Python, вĐēĐģŅŽŅ‡Đ°Ņ: * ĐžĐąŅŠĐĩĐē҂ҋ JSON (`dict`). - * ĐœĐ°ŅŅĐ¸Đ˛Ņ‹ JSON (`list`) ҁ ŅƒŅŅ‚Đ°ĐŊОвĐģĐĩĐŊĐŊŅ‹Đŧи Ņ‚Đ¸ĐŋаĐŧи ŅĐģĐĩĐŧĐĩĐŊŅ‚ĐžĐ˛. + * ĐœĐ°ŅŅĐ¸Đ˛ JSON (`list`) ҁ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đŧи Ņ‚Đ¸ĐŋаĐŧи ŅĐģĐĩĐŧĐĩĐŊŅ‚ĐžĐ˛. * ĐĄŅ‚Ņ€ĐžĐēĐžĐ˛Ņ‹Đĩ (`str`) ĐŋĐžĐģŅ ҁ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиĐĩĐŧ ĐŧиĐŊиĐŧаĐģҌĐŊОК и ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊОК Đ´ĐģиĐŊŅ‹. - * Đ§Đ¸ŅĐģа (`int`, `float`) ҁ ĐŧиĐŊиĐŧаĐģҌĐŊŅ‹Đŧи и ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊŅ‹Đŧи СĐŊĐ°Ņ‡ĐĩĐŊĐ¸ŅĐŧи и Ņ‚.Đŋ. + * Đ§Đ¸ŅĐģа (`int`, `float`) ҁ ĐŧиĐŊиĐŧаĐģҌĐŊŅ‹Đŧи и ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊŅ‹Đŧи СĐŊĐ°Ņ‡ĐĩĐŊĐ¸ŅĐŧи и Ņ‚. Đŋ. * ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа Đ´ĐģŅ йОĐģĐĩĐĩ ŅĐēĐˇĐžŅ‚Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… Ņ‚Đ¸ĐŋОв, Ņ‚Đ°ĐēĐ¸Ņ… ĐēаĐē: * URL. @@ -118,11 +115,11 @@ FastAPI иĐŧĐĩĐĩŅ‚ ĐŋŅ€ĐžĐ´ŅƒĐŧаĐŊĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ **ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊ * UUID. * ...и Đ´Ņ€ŅƒĐŗĐ¸Đĩ. -Đ’ŅĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ Ņ…ĐžŅ€ĐžŅˆĐž ĐˇĐ°Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ĐžĐ˛Đ°Đ˛ŅˆĐ¸Đŧ ҁĐĩĐąŅ и ĐŊадĐĩĐļĐŊŅ‹Đŧ **Pydantic**. +Đ’ŅĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ Ņ…ĐžŅ€ĐžŅˆĐž ĐˇĐ°Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ĐžĐ˛Đ°Đ˛ŅˆĐ¸Đŧ ҁĐĩĐąŅ и ĐŊĐ°Đ´Ņ‘ĐļĐŊŅ‹Đŧ **Pydantic**. -### БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ и Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ +### БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ и Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Ņ { #security-and-authentication } -Đ’ŅŅ‚Ņ€ĐžĐĩĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ и Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸. БĐĩС ĐēаĐēĐ¸Ņ…-ĐģийО ĐēĐžĐŧĐŋŅ€ĐžĐŧĐ¸ŅŅĐžĐ˛ ҁ йаСаĐŧи даĐŊĐŊҋ҅ иĐģи ĐŧОдĐĩĐģŅĐŧи даĐŊĐŊҋ҅. +Đ’ŅŅ‚Ņ€ĐžĐĩĐŊĐŊŅ‹Đĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ и Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸. БĐĩС ĐēаĐēĐ¸Ņ…â€‘ĐģийО ĐēĐžĐŧĐŋŅ€ĐžĐŧĐ¸ŅŅĐžĐ˛ ҁ йаСаĐŧи даĐŊĐŊҋ҅ иĐģи ĐŧОдĐĩĐģŅĐŧи даĐŊĐŊҋ҅. Đ’ŅĐĩ ҁ҅ĐĩĐŧŅ‹ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đĩ в OpenAPI, вĐēĐģŅŽŅ‡Đ°Ņ: @@ -137,68 +134,68 @@ FastAPI иĐŧĐĩĐĩŅ‚ ĐŋŅ€ĐžĐ´ŅƒĐŧаĐŊĐŊŅ‹Đĩ СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ **ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊ Đ’ŅĐĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ и ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊ҂ҋ ҁĐŋŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹ Đ´ĐģŅ ĐŧĐŊĐžĐŗĐžĐēŅ€Đ°Ņ‚ĐŊĐžĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ и ĐģĐĩĐŗĐēĐž иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ŅƒŅŽŅ‚ŅŅ ҁ Đ˛Đ°ŅˆĐ¸Đŧи ŅĐ¸ŅŅ‚ĐĩĐŧаĐŧи, Ņ…Ņ€Đ°ĐŊиĐģĐ¸Ņ‰Đ°Đŧи даĐŊĐŊҋ҅, Ņ€ĐĩĐģŅŅ†Đ¸ĐžĐŊĐŊŅ‹Đŧи и NoSQL йаСаĐŧи даĐŊĐŊҋ҅ и Ņ‚. Đ´. -### ВĐŊĐĩĐ´Ņ€ĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš +### ВĐŊĐĩĐ´Ņ€ĐĩĐŊиĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš { #dependency-injection } FastAPI вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ в ҁĐĩĐąŅ ҇ҀĐĩĐˇĐ˛Ņ‹Ņ‡Đ°ĐšĐŊĐž ĐŋŅ€ĐžŅŅ‚ŅƒŅŽ в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии, ĐŊĐž ҇ҀĐĩĐˇĐ˛Ņ‹Ņ‡Đ°ĐšĐŊĐž ĐŧĐžŅ‰ĐŊŅƒŅŽ ŅĐ¸ŅŅ‚ĐĩĐŧ҃ ВĐŊĐĩĐ´Ņ€ĐĩĐŊĐ¸Ņ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. -* ДаĐļĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŧĐžĐŗŅƒŅ‚ иĐŧĐĩŅ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ иĐĩŅ€Đ°Ņ€Ņ…Đ¸ŅŽ иĐģи **"ĐŗŅ€Đ°Ņ„Ņ‹" ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš**. +* ДаĐļĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŧĐžĐŗŅƒŅ‚ иĐŧĐĩŅ‚ŅŒ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸, ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ иĐĩŅ€Đ°Ņ€Ņ…Đ¸ŅŽ иĐģи **ÂĢĐŗŅ€Đ°Ņ„Âģ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš**. * Đ’ŅŅ‘ **Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ŅŅ** ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ. * Đ’ŅĐĩ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐŧĐžĐŗŅƒŅ‚ СаĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°Ņ‚ŅŒ даĐŊĐŊŅ‹Đĩ иС СаĐŋŅ€ĐžŅĐžĐ˛ и **Đ´ĐžĐŋĐžĐģĐŊŅŅ‚ŅŒ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸** ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊĐ¸ŅĐŧи и Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš. -* **ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа** даĐļĐĩ Đ´ĐģŅ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐŊҋ҅ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ…. -* ПоддĐĩŅ€ĐļĐēа ҁĐģĐžĐļĐŊҋ҅ ŅĐ¸ŅŅ‚ĐĩĐŧ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš, **ŅĐžĐĩдиĐŊĐĩĐŊиК ҁ йаСаĐŧи даĐŊĐŊҋ҅** и Ņ‚.Đ´. -* **НиĐēаĐēĐ¸Ņ… ĐēĐžĐŧĐŋŅ€ĐžĐŧĐ¸ŅŅĐžĐ˛** ҁ йаСаĐŧи даĐŊĐŊҋ҅, иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°Đŧи и Ņ‚.Đ´. Но ĐģĐĩĐŗĐēĐ°Ņ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Ņ ŅĐž Đ˛ŅĐĩĐŧи ĐŊиĐŧи. +* **ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ°Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа** даĐļĐĩ Đ´ĐģŅ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€ĐžĐ˛ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅŅ…. +* ПоддĐĩŅ€ĐļĐēа ҁĐģĐžĐļĐŊҋ҅ ŅĐ¸ŅŅ‚ĐĩĐŧ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš, **ŅĐžĐĩдиĐŊĐĩĐŊиК ҁ йаСаĐŧи даĐŊĐŊҋ҅** и Ņ‚. Đ´. +* **НиĐēаĐēĐ¸Ņ… ĐēĐžĐŧĐŋŅ€ĐžĐŧĐ¸ŅŅĐžĐ˛** ҁ йаСаĐŧи даĐŊĐŊҋ҅, иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐ°Đŧи и Ņ‚. Đ´. Но ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ — ĐģŅ‘ĐŗĐēĐ°Ņ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Ņ ŅĐž Đ˛ŅĐĩĐŧи ĐŊиĐŧи. -### НĐĩŅ‚ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиК ĐŊа "ПĐģĐ°ĐŗĐ¸ĐŊŅ‹" +### НĐĩŅ‚ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиК ĐŊа "ПĐģĐ°ĐŗĐ¸ĐŊŅ‹" { #unlimited-plug-ins } -ИĐģи, Đ´Ņ€ŅƒĐŗĐ¸Đŧи ҁĐģОваĐŧи, ĐŊĐĩŅ‚ ҁĐģĐžĐļĐŊĐžŅŅ‚ĐĩĐš ҁ ĐŊиĐŧи, иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐŊ҃ĐļĐŊŅ‹Đš ваĐŧ ĐēОд. +ИĐģи, Đ´Ņ€ŅƒĐŗĐ¸Đŧи ҁĐģОваĐŧи, ĐŊĐĩŅ‚ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ в ĐŊĐ¸Ņ… — ĐŋŅ€ĐžŅŅ‚Đž иĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ĐŊ҃ĐļĐŊŅ‹Đš ваĐŧ ĐēОд. -Đ›ŅŽĐąĐ°Ņ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Ņ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊа ĐŊĐ°ŅŅ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžŅŅ‚ĐžĐš в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии (ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи), Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ "ĐŋĐģĐ°ĐŗĐ¸ĐŊ" Đ´ĐģŅ ŅĐ˛ĐžĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ в ĐŋĐ°Ņ€Ņƒ ŅŅ‚Ņ€ĐžĐē ĐēОда, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ‚Ņƒ ĐļĐĩ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņƒ и ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ, Ņ‡Ņ‚Đž и Đ´ĐģŅ Đ˛Đ°ŅˆĐ¸Ņ… *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*. +Đ›ŅŽĐąĐ°Ņ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Ņ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đ°ĐŊа ĐŊĐ°ŅŅ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžŅŅ‚ĐžĐš в Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии (ҁ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ŅĐŧи), Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ÂĢĐŋĐģĐ°ĐŗĐ¸ĐŊÂģ Đ´ĐģŅ ŅĐ˛ĐžĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ в ĐŋĐ°Ņ€Ņƒ ŅŅ‚Ņ€ĐžĐē ĐēОда, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ‚Ņƒ ĐļĐĩ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņƒ и ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸Ņ, Ņ‡Ņ‚Đž и Đ´ĐģŅ Đ˛Đ°ŅˆĐ¸Ņ… *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸*. -### ĐŸŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊ +### ĐŸŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊ { #tested } -* 100% ĐŋĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи. -* 100% аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Ņ‚Đ¸ĐŋОв в ĐēОдОвОК йаСĐĩ. -* Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в Ņ€ĐĩаĐģҌĐŊĐž Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‰Đ¸Ņ… ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ…. +* 100% ĐŋĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи. +* 100% аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Ņ‚Đ¸ĐŋОв в ĐēОдОвОК йаСĐĩ. +* Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ‑ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŅ…. -## ĐžŅĐŊОвĐŊŅ‹Đĩ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đ° Starlette +## ВозĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Starlette { #starlette-features } -**FastAPI** ĐžŅĐŊОваĐŊ ĐŊа Starlette и ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đŧ ҁ ĐŊиĐŧ. ĐĸаĐē Ņ‡Ņ‚Đž, ĐģŅŽĐąĐžĐš Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐēОд Starlette, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ, ĐąŅƒĐ´ĐĩŅ‚ Ņ‚Đ°ĐēĐļĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ. +**FastAPI** ĐžŅĐŊОваĐŊ ĐŊа Starlette и ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đŧ ҁ ĐŊиĐŧ. ĐĸаĐē Ņ‡Ņ‚Đž ĐģŅŽĐąĐžĐš Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐēОд Starlette, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ, Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ. -На ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ, `FastAPI` - ŅŅ‚Đž ĐēĐģĐ°ŅŅ, ҃ĐŊĐ°ŅĐģĐĩдОваĐŊĐŊŅ‹Đš ĐžŅ‚ `Starlette`. ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐĩҁĐģи Đ˛Ņ‹ ҃ĐļĐĩ СĐŊаĐĩŅ‚Đĩ иĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Starlette, йОĐģŅŒŅˆĐ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģа ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ Ņ‚Đ°Đē ĐļĐĩ. +На ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ, `FastAPI` — ŅŅ‚Đž ĐŋОдĐēĐģĐ°ŅŅ `Starlette`. ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐĩҁĐģи Đ˛Ņ‹ ҃ĐļĐĩ СĐŊаĐĩŅ‚Đĩ иĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ Starlette, йОĐģŅŒŅˆĐ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģа ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ Ņ‚Đ°Đē ĐļĐĩ. -ĐĄ **FastAPI** Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ˛ŅĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ **Starlette** (Ņ‚Đ°Đē ĐēаĐē FastAPI ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ Starlette ĐŊа ҁ҂ĐĩŅ€ĐžĐ¸Đ´Đ°Ņ…): +ĐĄ **FastAPI** Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ˛ŅĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ **Starlette** (Ņ‚Đ°Đē ĐēаĐē FastAPI — ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ Starlette ĐŊа ҁ҂ĐĩŅ€ĐžĐ¸Đ´Đ°Ņ…): -* ĐĄĐĩŅ€ŅŒŅ‘ĐˇĐŊĐž вĐŋĐĩŅ‡Đ°Ņ‚ĐģŅŅŽŅ‰Đ°Ņ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. Đ­Ņ‚Đž ОдиĐŊ иС ŅĐ°Đŧҋ҅ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв ĐŊа Python, ĐŊĐ°Ņ€Đ°Đ˛ĐŊĐĩ ҁ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧи Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰Đ¸Đŧи **NodeJS** иĐģи **Go**. +* ĐĄĐĩŅ€ŅŒŅ‘ĐˇĐŊĐž вĐŋĐĩŅ‡Đ°Ņ‚ĐģŅŅŽŅ‰Đ°Ņ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸Ņ‚ĐĩĐģҌĐŊĐžŅŅ‚ŅŒ. Đ­Ņ‚Đž ОдиĐŊ иС ŅĐ°Đŧҋ҅ ĐąŅ‹ŅŅ‚Ņ€Ņ‹Ņ… ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв ĐŊа Python, ĐŊĐ°Ņ€Đ°Đ˛ĐŊĐĩ ҁ **NodeJS** и **Go**. * ПоддĐĩŅ€ĐļĐēа **WebSocket**. -* ФОĐŊĐžĐ˛Ņ‹Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ Đ´ĐģŅ ĐŋŅ€ĐžŅ†ĐĩŅŅĐžĐ˛. +* ФОĐŊĐžĐ˛Ņ‹Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ в Ņ‚ĐžĐŧ ĐļĐĩ ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ. * ĐĄĐžĐąŅ‹Ņ‚Đ¸Ņ СаĐŋ҃ҁĐēа и Đ˛Ņ‹ĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ. -* ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đš ĐēĐģиĐĩĐŊŅ‚ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊ ĐŊа йийĐģĐ¸ĐžŅ‚ĐĩĐēĐĩ HTTPX. +* ĐĸĐĩŅŅ‚ĐžĐ˛Ņ‹Đš ĐēĐģиĐĩĐŊŅ‚ ĐŋĐžŅŅ‚Ņ€ĐžĐĩĐŊ ĐŊа HTTPX. * **CORS**, GZip, ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹, ĐŋĐžŅ‚ĐžĐēĐžĐ˛Ņ‹Đĩ ĐžŅ‚Đ˛Đĩ҂ҋ. * ПоддĐĩŅ€ĐļĐēа **ҁĐĩŅŅĐ¸Đš и cookie**. * 100% ĐŋĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи. * 100% аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Ņ‚Đ¸ĐŋОв в ĐēОдОвОК йаСĐĩ. -## ĐžŅĐžĐąĐĩĐŊĐŊĐžŅŅ‚Đ¸ и вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Pydantic +## ВозĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ Pydantic { #pydantic-features } -**FastAPI** ĐžŅĐŊОваĐŊ ĐŊа Pydantic и ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đŧ ҁ ĐŊиĐŧ. ĐĸаĐē Ņ‡Ņ‚Đž, ĐģŅŽĐąĐžĐš Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐēОд Pydantic, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ, ĐąŅƒĐ´ĐĩŅ‚ Ņ‚Đ°ĐēĐļĐĩ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ. +**FastAPI** ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸Đŧ ҁ (и ĐžŅĐŊОваĐŊ ĐŊа) Pydantic. ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐģŅŽĐąĐžĐš Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš ĐēОд Pydantic, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ, Ņ‚Đ°ĐēĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ. -ВĐēĐģŅŽŅ‡Đ°Ņ вĐŊĐĩ҈ĐŊиĐĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи, Ņ‚Đ°ĐēĐļĐĩ ĐžŅĐŊОваĐŊĐŊŅ‹Đĩ ĐŊа Pydantic, Ņ‚Đ°ĐēиĐĩ ĐēаĐē: ORM'Ņ‹, ODM'Ņ‹ Đ´ĐģŅ йаС даĐŊĐŊҋ҅. +ВĐēĐģŅŽŅ‡Đ°Ņ вĐŊĐĩ҈ĐŊиĐĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи, Ņ‚Đ°ĐēĐļĐĩ ĐžŅĐŊОваĐŊĐŊŅ‹Đĩ ĐŊа Pydantic, Ņ‚Đ°ĐēиĐĩ ĐēаĐē ORMâ€™Ņ‹, ODMâ€™Ņ‹ Đ´ĐģŅ йаС даĐŊĐŊҋ҅. Đ­Ņ‚Đž Ņ‚Đ°ĐēĐļĐĩ ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ´Đ°Đ˛Đ°Ņ‚ŅŒ Ņ‚ĐžŅ‚ ĐļĐĩ ĐžĐąŅŠĐĩĐēŅ‚, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋĐžĐģŅƒŅ‡Đ¸Đģи иС СаĐŋŅ€ĐžŅĐ°, **ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž в ĐąĐ°ĐˇŅƒ даĐŊĐŊҋ҅**, Ņ‚Đ°Đē ĐēаĐē Đ˛ŅŅ‘ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚ŅŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи. И ĐŊĐ°ĐžĐąĐžŅ€ĐžŅ‚, вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžŅŅ‚Đž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ ĐžĐąŅŠĐĩĐēŅ‚, ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đš иС ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅, **ĐŊĐĩĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐĩĐŊĐŊĐž ĐēĐģиĐĩĐŊŅ‚Ņƒ**. -ĐĄ **FastAPI** Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ˛ŅĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ **Pydantic** (Ņ‚Đ°Đē ĐēаĐē, FastAPI ĐžŅĐŊОваĐŊ ĐŊа Pydantic, Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи даĐŊĐŊҋ҅): +ĐĄ **FastAPI** Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚Đĩ Đ˛ŅĐĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ **Pydantic** (Ņ‚Đ°Đē ĐēаĐē FastAPI ĐžŅĐŊОваĐŊ ĐŊа Pydantic Đ´ĐģŅ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи даĐŊĐŊҋ҅): -* **НиĐēаĐēОК ĐŊĐĩŅ€Đ˛ĐžŅ‚Ņ€Ņ‘ĐŋĐēи** : - * НĐĩ ĐŊ҃ĐļĐŊĐž Đ¸ĐˇŅƒŅ‡Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Ņ… ҁ҅ĐĩĐŧ в ĐŧиĐēŅ€ĐžŅĐˇŅ‹ĐēĐ°Ņ…. - * Đ•ŅĐģи Đ˛Ņ‹ СĐŊаĐĩŅ‚Đĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв в Python, Đ˛Ņ‹ СĐŊаĐĩŅ‚Đĩ, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Pydantic. -* ĐŸŅ€ĐĩĐēŅ€Đ°ŅĐŊĐž ŅĐžŅ‡ĐĩŅ‚Đ°ĐĩŅ‚ŅŅ ҁ Đ˛Đ°ŅˆĐ¸Đŧи **IDE/linter/ĐŧĐžĐˇĐŗĐžĐŧ**: - * ĐŸĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņ‹ даĐŊĐŊҋ҅ pydantic - ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ŅĐēСĐĩĐŧĐŋĐģŅŅ€Ņ‹ ĐēĐģĐ°ŅŅĐžĐ˛, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ваĐŧи. ĐĐ˛Ņ‚ĐžĐ´ĐžĐŋĐžĐģĐŊĐĩĐŊиĐĩ, ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ĐēОда, mypy и Đ˛Đ°ŅˆĐ° иĐŊŅ‚ŅƒĐ¸Ņ†Đ¸Ņ - Đ˛ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ Đ˛Đ°ŅˆĐ¸Đŧи ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊĐŊŅ‹Đŧи даĐŊĐŊŅ‹Đŧи. -* ĐŸŅ€ĐžĐ˛ĐĩŅ€Đēа **ҁĐģĐžĐļĐŊҋ҅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€**: - * Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ иĐĩŅ€Đ°Ņ€Ņ…Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… ĐŧОдĐĩĐģĐĩĐš Pydantic; `List`, `Dict` и Ņ‚.Đŋ. иС ĐŧĐžĐ´ŅƒĐģŅ `typing` (Đ˛Ņ…ĐžĐ´Đ¸Ņ‚ в ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅƒŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃ Python). - * ВаĐģĐ¸Đ´Đ°Ņ‚ĐžŅ€Ņ‹ ĐŋОСвОĐģŅŅŽŅ‚ ҇ĐĩŅ‚ĐēĐž и ĐģĐĩĐŗĐēĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ, ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁĐģĐžĐļĐŊŅ‹Đĩ ҁ҅ĐĩĐŧŅ‹ даĐŊĐŊҋ҅ в видĐĩ JSON Schema. - * ĐŖ Đ˛Đ°Ņ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŗĐģŅƒĐąĐžĐēĐž **вĐģĐžĐļĐĩĐŊĐŊŅ‹Đĩ ĐžĐąŅŠĐĩĐē҂ҋ JSON** и Đ˛ŅĐĩ ĐžĐŊи ĐąŅƒĐ´ŅƒŅ‚ ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊŅ‹ и аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹. +* **НиĐēаĐēОК ĐŊĐĩŅ€Đ˛ĐžŅ‚Ņ€Ņ‘ĐŋĐēи**: + * НĐĩ ĐŊ҃ĐļĐŊĐž Đ¸ĐˇŅƒŅ‡Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đĩ ҁ҅ĐĩĐŧŅ‹ в ĐŧиĐēŅ€ĐžŅĐˇŅ‹ĐēĐ°Ņ…. + * Đ•ŅĐģи Đ˛Ņ‹ СĐŊаĐĩŅ‚Đĩ Ņ‚Đ¸ĐŋŅ‹ в Python, Đ˛Ņ‹ СĐŊаĐĩŅ‚Đĩ, ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Pydantic. +* ĐŸŅ€ĐĩĐēŅ€Đ°ŅĐŊĐž ŅĐžŅ‡ĐĩŅ‚Đ°ĐĩŅ‚ŅŅ ҁ Đ˛Đ°ŅˆĐ¸Đŧ **IDE/linter/ĐŧĐžĐˇĐŗĐžĐŧ**: + * ĐŸĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Ņ‹ даĐŊĐŊҋ҅ pydantic — ŅŅ‚Đž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ŅĐēСĐĩĐŧĐŋĐģŅŅ€Ņ‹ ĐēĐģĐ°ŅŅĐžĐ˛, ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ваĐŧи; Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ, ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēа ĐēОда, mypy и Đ˛Đ°ŅˆĐ° иĐŊŅ‚ŅƒĐ¸Ņ†Đ¸Ņ — Đ˛ŅŅ‘ ĐąŅƒĐ´ĐĩŅ‚ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ Đ˛Đ°ŅˆĐ¸Đŧи ваĐģĐ¸Đ´Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đŧи даĐŊĐŊŅ‹Đŧи. +* ВаĐģĐ¸Đ´Đ°Ņ†Đ¸Ņ **ҁĐģĐžĐļĐŊҋ҅ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€**: + * Đ˜ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ иĐĩŅ€Đ°Ņ€Ņ…Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… ĐŧОдĐĩĐģĐĩĐš Pydantic; `List`, `Dict` и Ņ‚. Đŋ. иС ĐŧĐžĐ´ŅƒĐģŅ `typing` (Đ˛Ņ…ĐžĐ´Đ¸Ņ‚ в ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅƒŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃ Python). + * ВаĐģĐ¸Đ´Đ°Ņ‚ĐžŅ€Ņ‹ ĐŋОСвОĐģŅŅŽŅ‚ ҇ґ҂ĐēĐž и ĐģĐĩĐŗĐēĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ, ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁĐģĐžĐļĐŊŅ‹Đĩ ҁ҅ĐĩĐŧŅ‹ даĐŊĐŊҋ҅ в видĐĩ JSON Schema. + * ĐŖ Đ˛Đ°Ņ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŗĐģŅƒĐąĐžĐēĐž **вĐģĐžĐļĐĩĐŊĐŊŅ‹Đĩ ĐžĐąŅŠĐĩĐē҂ҋ JSON**, и Đ˛ŅĐĩ ĐžĐŊи ĐąŅƒĐ´ŅƒŅ‚ ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊŅ‹ и аĐŊĐŊĐžŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊŅ‹. * **Đ Đ°ŅŅˆĐ¸Ņ€ŅĐĩĐŧĐžŅŅ‚ŅŒ**: - * Pydantic ĐŋОСвОĐģŅĐĩŅ‚ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ Ņ‚Đ¸ĐŋŅ‹ даĐŊĐŊҋ҅ иĐģи Ņ€Đ°ŅŅˆĐ¸Ņ€ŅŅ‚ŅŒ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ ĐŧĐĩŅ‚ĐžĐ´Đ°Đŧи ĐŧОдĐĩĐģи, ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐžŅ‡ĐŊҋ҅ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛. + * Pydantic ĐŋОСвОĐģŅĐĩŅ‚ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅŅ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ Ņ‚Đ¸ĐŋŅ‹ даĐŊĐŊҋ҅ иĐģи Ņ€Đ°ŅŅˆĐ¸Ņ€ŅŅ‚ŅŒ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ ĐŧĐĩŅ‚ĐžĐ´Đ°Đŧи ĐŧОдĐĩĐģи ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Đ´ĐĩĐēĐžŅ€Đ°Ņ‚ĐžŅ€ĐžĐ˛ ваĐģĐ¸Đ´Đ°Ņ‚ĐžŅ€ĐžĐ˛. * 100% ĐŋĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Ņ‚ĐĩŅŅ‚Đ°Đŧи. diff --git a/docs/ru/docs/help-fastapi.md b/docs/ru/docs/help-fastapi.md index 474b3d689..6bfabb96c 100644 --- a/docs/ru/docs/help-fastapi.md +++ b/docs/ru/docs/help-fastapi.md @@ -1,261 +1,255 @@ -# ПоĐŧĐžŅ‡ŅŒ FastAPI - ПоĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰ŅŒ +# ПоĐŧĐžŅ‡ŅŒ FastAPI - ПоĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰ŅŒ { #help-fastapi-get-help } ĐŅ€Đ°Đ˛Đ¸Ņ‚ŅŅ Đģи ВаĐŧ **FastAPI**? -ĐĨĐžŅ‚ĐĩĐģи ĐąŅ‹ Đ’Ņ‹ ĐŋĐžĐŧĐžŅ‡ŅŒ FastAPI, ĐĩĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ и Đ°Đ˛Ņ‚ĐžŅ€Ņƒ? +ĐĨĐžŅ‚ĐĩĐģи ĐąŅ‹ Đ’Ņ‹ ĐŋĐžĐŧĐžŅ‡ŅŒ FastAPI, Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ и Đ°Đ˛Ņ‚ĐžŅ€Ņƒ? -МоĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ҃ Đ’Đ°Ņ вОСĐŊиĐēĐģи Ņ‚Ņ€ŅƒĐ´ĐŊĐžŅŅ‚Đ¸ ҁ **FastAPI** и ВаĐŧ ĐŊ҃ĐļĐŊа ĐŋĐžĐŧĐžŅ‰ŅŒ? +ИĐģи Đ’Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰ŅŒ ĐŋĐž **FastAPI**? -Đ•ŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Ņ‹Ņ… ҁĐŋĐžŅĐžĐąĐžĐ˛ ĐžĐēаСаĐŊĐ¸Ņ ĐŋĐžĐŧĐžŅ‰Đ¸ (иĐŊĐžĐŗĐ´Đ° Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ОдĐŊĐžĐŗĐž иĐģи Đ´Đ˛ŅƒŅ… ĐēĐģиĐēОв). +Đ•ŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐžŅ‡ĐĩĐŊҌ ĐŋŅ€ĐžŅŅ‚Ņ‹Ņ… ҁĐŋĐžŅĐžĐąĐžĐ˛ ĐŋĐžĐŧĐžŅ‡ŅŒ (иĐŊĐžĐŗĐ´Đ° Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Đ˛ŅĐĩĐŗĐž ĐģĐ¸ŅˆŅŒ ОдĐŊĐžĐŗĐž-Đ´Đ˛ŅƒŅ… ĐēĐģиĐēОв). И Ņ‚Đ°ĐēĐļĐĩ ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҁĐŋĐžŅĐžĐąĐžĐ˛ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰ŅŒ. -## ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŊĐžĐ˛ĐžŅŅ‚ĐŊŅƒŅŽ Ņ€Đ°ŅŅŅ‹ĐģĐē҃ +## ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŊĐžĐ˛ĐžŅŅ‚ĐŊŅƒŅŽ Ņ€Đ°ŅŅŅ‹ĐģĐē҃ { #subscribe-to-the-newsletter } Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋОдĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа Ņ€ĐĩĐ´ĐēŅƒŅŽ [ĐŊĐžĐ˛ĐžŅŅ‚ĐŊŅƒŅŽ Ņ€Đ°ŅŅŅ‹ĐģĐē҃ **FastAPI и ĐĩĐŗĐž Đ´Ņ€ŅƒĐˇŅŒŅ**](newsletter.md){.internal-link target=_blank} и ĐąŅ‹Ņ‚ŅŒ в ĐēŅƒŅ€ŅĐĩ Đž: * ĐĐžĐ˛ĐžŅŅ‚ŅŅ… Đž FastAPI и ĐĩĐŗĐž Đ´Ņ€ŅƒĐˇŅŒŅŅ… 🚀 * Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đ°Ņ… 📝 * ВозĐŧĐžĐļĐŊĐžŅŅ‚ŅŅ… ✨ -* Đ˜ŅĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸ŅŅ… 🚨 +* ЛоĐŧĐ°ŅŽŅ‰Đ¸Ņ… иСĐŧĐĩĐŊĐĩĐŊĐ¸ŅŅ… 🚨 * ĐŸĐžĐ´ŅĐēаСĐēĐ°Ņ… и Ņ…Đ¸Ņ‚Ņ€ĐžŅŅ‚ŅŅ… ✅ -## ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа FastAPI в Twitter +## ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа FastAPI в X (Twitter) { #follow-fastapi-on-x-twitter } -ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа @fastapi в **Twitter** Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ĐŊĐ°Đ¸ŅĐ˛ĐĩĐļĐ°ĐšŅˆĐ¸Ņ… ĐŊĐžĐ˛ĐžŅŅ‚ĐĩĐš Đž **FastAPI**. đŸĻ +ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа @fastapi в **X (Twitter)** Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ ĐŊĐ°Đ¸ŅĐ˛ĐĩĐļĐ°ĐšŅˆĐ¸Ņ… ĐŊĐžĐ˛ĐžŅŅ‚ĐĩĐš Đž **FastAPI**. đŸĻ -## Đ”ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ **FastAPI** СвĐĩĐˇĐ´Ņƒ ĐŊа GitHub +## Đ”ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ **FastAPI** СвĐĩĐˇĐ´Ņƒ ĐŊа GitHub { #star-fastapi-in-github } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ FastAPI "СвĐĩĐˇĐ´Ņƒ" ĐŊа GitHub (ĐēĐģиĐēĐŊŅƒŅ‚ŅŒ ĐŊа ĐēĐŊĐžĐŋĐē҃ СвĐĩĐˇĐ´Ņ‹ в вĐĩҀ҅ĐŊĐĩĐŧ ĐŋŅ€Đ°Đ˛ĐžĐŧ ŅƒĐŗĐģ҃ ŅĐēŅ€Đ°ĐŊа): https://github.com/fastapi/fastapi. â­ī¸ +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ FastAPI "СвĐĩĐˇĐ´Ņƒ" ĐŊа GitHub (ĐēĐģиĐēĐŊŅƒĐ˛ ĐŊа ĐēĐŊĐžĐŋĐē҃ СвĐĩĐˇĐ´Ņ‹ в ĐŋŅ€Đ°Đ˛ĐžĐŧ вĐĩҀ҅ĐŊĐĩĐŧ ŅƒĐŗĐģ҃): https://github.com/fastapi/fastapi. â­ī¸ -ЧĐĩĐŧ йОĐģҌ҈Đĩ ĐˇĐ˛Ņ‘ĐˇĐ´, Ņ‚ĐĩĐŧ ĐģĐĩĐŗŅ‡Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ ĐŊĐ°ĐšŅ‚Đ¸ ĐŊĐ°Ņ и ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž ĐŋŅ€ĐžĐĩĐēŅ‚ ҃ĐļĐĩ ŅŅ‚Đ°Đģ ĐŋĐžĐģĐĩСĐŊŅ‹Đŧ Đ´ĐģŅ ĐŧĐŊĐžĐŗĐ¸Ņ…. +ЧĐĩĐŧ йОĐģҌ҈Đĩ ĐˇĐ˛Ņ‘ĐˇĐ´, Ņ‚ĐĩĐŧ ĐģĐĩĐŗŅ‡Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅĐŧ ĐŊĐ°ĐšŅ‚Đ¸ ĐŋŅ€ĐžĐĩĐēŅ‚ и ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ, Ņ‡Ņ‚Đž ĐžĐŊ ҃ĐļĐĩ ĐžĐēаСаĐģŅŅ ĐŋĐžĐģĐĩСĐŊŅ‹Đŧ Đ´ĐģŅ ĐŧĐŊĐžĐŗĐ¸Ņ…. -## ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ŅĐ˛ĐĩĐļиĐĩ Đ˛Ņ‹Đŋ҃ҁĐēи в Ņ€ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Đ¸Đ¸ ĐŊа GitHub +## ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ ŅĐ˛ĐĩĐļиĐĩ Đ˛Ņ‹Đŋ҃ҁĐēи в Ņ€ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Đ¸Đ¸ ĐŊа GitHub { #watch-the-github-repository-for-releases } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ "ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ" FastAPI ĐŊа GitHub (ĐēĐģиĐēĐŊĐ¸Ņ‚Đĩ ĐŋĐž ĐēĐŊĐžĐŋĐēĐĩ "watch" ĐŊавĐĩŅ€Ņ…Ņƒ ҁĐŋŅ€Đ°Đ˛Đ°): https://github.com/fastapi/fastapi. 👀 +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ "ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ" FastAPI ĐŊа GitHub (ĐēĐģиĐēĐŊŅƒĐ˛ ĐŋĐž ĐēĐŊĐžĐŋĐēĐĩ "watch" ĐŊавĐĩŅ€Ņ…Ņƒ ҁĐŋŅ€Đ°Đ˛Đ°): https://github.com/fastapi/fastapi. 👀 -ĐĸаĐŧ ĐļĐĩ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ в ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēĐ°Ņ… - "Releases only". +ĐĸаĐŧ ĐļĐĩ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ "Releases only". ĐĄ Ņ‚Đ°ĐēОК ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēОК Đ’Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ ĐŊа Đ˛Đ°ŅˆŅƒ ŅĐģĐĩĐēŅ‚Ņ€ĐžĐŊĐŊŅƒŅŽ ĐŋĐžŅ‡Ņ‚Ņƒ ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ, ĐēĐžĐŗĐ´Đ° ĐŋĐžŅĐ˛Đ¸Ņ‚ŅŅ ĐŊĐžĐ˛Ņ‹Đš Ņ€ĐĩĐģиС (ĐŊĐžĐ˛Đ°Ņ вĐĩŅ€ŅĐ¸Ņ) **FastAPI** ҁ Đ¸ŅĐŋŅ€Đ°Đ˛ĐģĐĩĐŊĐ¸ŅĐŧи ĐžŅˆĐ¸ĐąĐžĐē и ĐŊĐžĐ˛Ņ‹Đŧи вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅĐŧи. -## ĐĄĐ˛ŅĐˇĐ°Ņ‚ŅŒŅŅ ҁ Đ°Đ˛Ņ‚ĐžŅ€ĐžĐŧ +## ĐĄĐ˛ŅĐˇĐ°Ņ‚ŅŒŅŅ ҁ Đ°Đ˛Ņ‚ĐžŅ€ĐžĐŧ { #connect-with-the-author } -МоĐļĐŊĐž ŅĐ˛ŅĐˇĐ°Ņ‚ŅŒŅŅ ŅĐž ĐŧĐŊОК (ĐĄĐĩĐąŅŅŅ‚ŅŒŅĐŊ РаĐŧĐ¸Ņ€ĐĩС / `tiangolo`), Đ°Đ˛Ņ‚ĐžŅ€ĐžĐŧ FastAPI. +МоĐļĐŊĐž ŅĐ˛ŅĐˇĐ°Ņ‚ŅŒŅŅ ŅĐž ĐŧĐŊОК (SebastiÃĄn Ramírez / `tiangolo`), Đ°Đ˛Ņ‚ĐžŅ€ĐžĐŧ. Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ: * ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ ĐŊа **GitHub**. * ĐŸĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŧОи ĐŋŅ€ĐžĐĩĐē҂ҋ ҁ ĐžŅ‚ĐēҀҋ҂ҋĐŧ ĐēОдОĐŧ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐŗŅƒŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊŅ‹ ВаĐŧ. - * ПодĐŋĐ¸ŅĐ°Đ˛ŅˆĐ¸ŅŅŒ ĐŊа ĐŧĐĩĐŊŅ Đ’Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ, Ņ‡Ņ‚Đž Ņ ŅĐžĐˇĐ´Đ°Đģ ĐŊĐžĐ˛Ņ‹Đš ĐŋŅ€ĐžĐĩĐēŅ‚ ҁ ĐžŅ‚ĐēҀҋ҂ҋĐŧ ĐēОдОĐŧ,. -* ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ в **Twitter** иĐģи в Mastodon. - * ПодĐĩĐģĐ¸Ņ‚ŅŒŅŅ ŅĐž ĐŧĐŊОК, ĐēаĐē Đ’Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI (Ņ ОйОĐļĐ°ŅŽ Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ ĐŋŅ€Đž ŅŅ‚Đž). - * ПоĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ, ĐēĐžĐŗĐ´Đ° Ņ Đ´ĐĩĐģĐ°ŅŽ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ и ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅŅŽ ĐŊĐžĐ˛Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ. - * Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋОдĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа @fastapi в Twitter (ŅŅ‚Đž ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš аĐēĐēĐ°ŅƒĐŊŅ‚). -* ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ в **Linkedin**. - * ПоĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ, ĐēĐžĐŗĐ´Đ° Ņ Đ´ĐĩĐģĐ°ŅŽ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ и ĐŋŅ€ĐĩĐ´ŅŅ‚Đ°Đ˛ĐģŅŅŽ ĐŊĐžĐ˛Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ (ĐŋŅ€Đ°Đ˛Đ´Đ° Ņ‡Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽ Twitter 🤷‍♂). -* Đ§Đ¸Ņ‚Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Ņ ĐŋĐ¸ŅˆŅƒ (иĐģи ĐŋОдĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ) в **Dev.to** иĐģи в **Medium**. - * Đ§Đ¸Ņ‚Đ°Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ идĐĩи, ŅŅ‚Đ°Ņ‚ŅŒĐ¸ и Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ Ой иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Ņ… ŅĐžĐˇĐ´Đ°ĐŊĐŊҋ҅ ĐŧĐŊОК. - * ПодĐŋĐ¸ŅˆĐ¸Ņ‚ĐĩҁҌ ĐŊа ĐŧĐĩĐŊŅ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ, ĐēĐžĐŗĐ´Đ° Ņ ĐžĐŋŅƒĐąĐģиĐēŅƒŅŽ Ņ‡Ņ‚Đž-ĐŊĐ¸ĐąŅƒĐ´ŅŒ ĐŊОвОĐĩ. + * ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ, Ņ‡Ņ‚ĐžĐąŅ‹ видĐĩŅ‚ŅŒ, ĐēĐžĐŗĐ´Đ° Ņ ŅĐžĐˇĐ´Đ°ŅŽ ĐŊĐžĐ˛Ņ‹Đš ĐŋŅ€ĐžĐĩĐēŅ‚ ҁ ĐžŅ‚ĐēҀҋ҂ҋĐŧ ĐēОдОĐŧ. +* ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ в **X (Twitter)** иĐģи в Mastodon. + * ПодĐĩĐģĐ¸Ņ‚ŅŒŅŅ ŅĐž ĐŧĐŊОК, ĐēаĐē Đ’Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ FastAPI (Ņ ОйОĐļĐ°ŅŽ ŅŅ‚Đž Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ). + * ĐŖĐˇĐŊĐ°Đ˛Đ°Ņ‚ŅŒ, ĐēĐžĐŗĐ´Đ° Ņ Đ´ĐĩĐģĐ°ŅŽ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ иĐģи Đ˛Ņ‹Đŋ҃ҁĐēĐ°ŅŽ ĐŊĐžĐ˛Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ. + * Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋОдĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа @fastapi в X (Twitter) (ŅŅ‚Đž ĐžŅ‚Đ´ĐĩĐģҌĐŊŅ‹Đš аĐēĐēĐ°ŅƒĐŊŅ‚). +* ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ в **LinkedIn**. + * ĐŖĐˇĐŊĐ°Đ˛Đ°Ņ‚ŅŒ, ĐēĐžĐŗĐ´Đ° Ņ Đ´ĐĩĐģĐ°ŅŽ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐ¸Ņ иĐģи Đ˛Ņ‹Đŋ҃ҁĐēĐ°ŅŽ ĐŊĐžĐ˛Ņ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ (Ņ…ĐžŅ‚Ņ Ņ‡Đ°Ņ‰Đĩ Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽ X (Twitter) 🤷‍♂). +* Đ§Đ¸Ņ‚Đ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Ņ ĐŋĐ¸ŅˆŅƒ (иĐģи ĐŋОдĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ ĐŊа ĐŧĐĩĐŊŅ) ĐŊа **Dev.to** иĐģи **Medium**. + * Đ§Đ¸Ņ‚Đ°Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đĩ идĐĩи, ŅŅ‚Đ°Ņ‚ŅŒĐ¸ и Đž ŅĐžĐˇĐ´Đ°ĐŊĐŊҋ҅ ĐŧĐŊОК иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚Đ°Ņ…. + * ПодĐŋĐ¸ŅĐ°Ņ‚ŅŒŅŅ, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ, ĐēĐžĐŗĐ´Đ° Ņ ĐŋŅƒĐąĐģиĐēŅƒŅŽ Ņ‡Ņ‚Đž-Ņ‚Đž ĐŊОвОĐĩ. -## ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ŅĐžĐžĐąŅ‰ĐĩĐŊиĐĩ в Twitter Đž **FastAPI** +## ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ŅĐžĐžĐąŅ‰ĐĩĐŊиĐĩ в X (Twitter) Đž **FastAPI** { #tweet-about-fastapi } -ĐžŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ ŅĐžĐžĐąŅ‰ĐĩĐŊиĐĩ в Twitter Đž **FastAPI** и ĐŋОСвОĐģŅŒŅ‚Đĩ ĐŧĐŊĐĩ и Đ´Ņ€ŅƒĐŗĐ¸Đŧ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ - ĐŋĐžŅ‡ĐĩĐŧ҃ ĐžĐŊ ВаĐŧ ĐŊŅ€Đ°Đ˛Đ¸Ņ‚ŅŅ. 🎉 +ĐžŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ ŅĐžĐžĐąŅ‰ĐĩĐŊиĐĩ в X (Twitter) Đž **FastAPI** и ĐŋОСвОĐģŅŒŅ‚Đĩ ĐŧĐŊĐĩ и Đ´Ņ€ŅƒĐŗĐ¸Đŧ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ, ĐŋĐžŅ‡ĐĩĐŧ҃ ĐžĐŊ ВаĐŧ ĐŊŅ€Đ°Đ˛Đ¸Ņ‚ŅŅ. 🎉 -Đ¯ ĐģŅŽĐąĐģŅŽ ŅƒĐˇĐŊĐ°Đ˛Đ°Ņ‚ŅŒ Đž Ņ‚ĐžĐŧ, ĐēаĐē **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ, Ņ‡Ņ‚Đž ВаĐŧ ĐŋĐžĐŊŅ€Đ°Đ˛Đ¸ĐģĐžŅŅŒ в ĐŊŅ‘Đŧ, в ĐēаĐēĐ¸Ņ… ĐŋŅ€ĐžĐĩĐēŅ‚Đ°Ņ…/ĐēĐžĐŧĐŋаĐŊĐ¸ŅŅ… Đ’Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ ĐĩĐŗĐž и Ņ‚.Đŋ. +Đ¯ ĐģŅŽĐąĐģŅŽ ŅƒĐˇĐŊĐ°Đ˛Đ°Ņ‚ŅŒ Đž Ņ‚ĐžĐŧ, ĐēаĐē **FastAPI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ, Ņ‡Ņ‚Đž ВаĐŧ ĐŋĐžĐŊŅ€Đ°Đ˛Đ¸ĐģĐžŅŅŒ в ĐŊŅ‘Đŧ, в ĐēаĐēĐ¸Ņ… ĐŋŅ€ĐžĐĩĐēŅ‚Đ°Ņ…/ĐēĐžĐŧĐŋаĐŊĐ¸ŅŅ… Đ’Ņ‹ ĐĩĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ и Ņ‚.Đ´. -## ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŗĐžĐģĐžŅ Са FastAPI +## ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŗĐžĐģĐžŅ Са FastAPI { #vote-for-fastapi } * ГоĐģĐžŅŅƒĐšŅ‚Đĩ Са **FastAPI** в Slant. -* ГоĐģĐžŅŅƒĐšŅ‚Đĩ Са **FastAPI** в AlternativeTo. -* Đ Đ°ŅŅĐēаĐļĐ¸Ņ‚Đĩ, ĐēаĐē Đ’Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **FastAPI** ĐŊа StackShare. +* ГоĐģĐžŅŅƒĐšŅ‚Đĩ Са **FastAPI** в AlternativeTo. +* Đ Đ°ŅŅĐēаĐļĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ’Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ **FastAPI** ĐŊа StackShare. -## ПоĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ Đ¸Ņ… ĐŋŅ€ĐžĐąĐģĐĩĐŧаĐŧи ĐŊа GitHub +## ПоĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ вОĐŋŅ€ĐžŅĐ°Đŧи ĐŊа GitHub { #help-others-with-questions-in-github } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ, ĐēаĐēиĐĩ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ Đ¸ŅĐŋŅ‹Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐģŅŽĐ´Đ¸ и ĐŋĐžĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ ĐŋĐžĐŧĐžŅ‡ŅŒ иĐŧ. Đ§Đ°Ņ‰Đĩ Đ˛ŅĐĩĐŗĐž ŅŅ‚Đž вОĐŋŅ€ĐžŅŅ‹, ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ, вĐĩҁҌĐŧа вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Đ’Ņ‹ ҃ĐļĐĩ СĐŊаĐĩŅ‚Đĩ ĐžŅ‚Đ˛ĐĩŅ‚. 🤓 +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ Đ¸Ņ… вОĐŋŅ€ĐžŅĐ°Đŧи в: -Đ•ŅĐģи Đ’Ņ‹ ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŧĐŊĐžĐŗĐž ĐŋĐžĐŧĐžĐŗĐ°Ņ‚ŅŒ ĐģŅŽĐ´ŅĐŧ ҁ Ņ€Đĩ҈ĐĩĐŊиĐĩĐŧ Đ¸Ņ… ĐŋŅ€ĐžĐąĐģĐĩĐŧ, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅŅ‚Đ°Ņ‚ŅŒ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đŧ [Đ­ĐēҁĐŋĐĩŅ€Ņ‚ĐžĐŧ FastAPI](fastapi-people.md#_3){.internal-link target=_blank}. 🎉 +* GitHub Discussions +* GitHub Issues -ĐĸĐžĐģҌĐēĐž ĐŋĐžĐŧĐŊĐ¸Ņ‚Đĩ, ŅĐ°ĐŧĐžĐĩ ваĐļĐŊĐžĐĩ ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ - Đ´ĐžĐąŅ€ĐžŅ‚Đ°. ĐĄŅ‚ĐžĐģĐēĐŊŅƒĐ˛ŅˆĐ¸ŅŅŒ ҁ ĐŋŅ€ĐžĐąĐģĐĩĐŧОК, ĐģŅŽĐ´Đ¸ Ņ€Đ°ŅŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°ŅŽŅ‚ŅŅ и Ņ‡Đ°ŅŅ‚Đž ĐˇĐ°Đ´Đ°ŅŽŅ‚ вОĐŋŅ€ĐžŅŅ‹ ĐŊĐĩ ĐģŅƒŅ‡ŅˆĐ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŊĐž ĐŋĐžŅŅ‚Đ°Ņ€Đ°ĐšŅ‚ĐĩҁҌ ĐąŅ‹Ņ‚ŅŒ ĐŧаĐēŅĐ¸ĐŧаĐģҌĐŊĐž Đ´ĐžĐąŅ€ĐžĐļĐĩĐģĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ. 🤗 +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… Đ’Ņ‹ ҃ĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ СĐŊĐ°Ņ‚ŅŒ ĐžŅ‚Đ˛Đĩ҂ҋ ĐŊа ŅŅ‚Đ¸ вОĐŋŅ€ĐžŅŅ‹. 🤓 -ИдĐĩŅ ŅĐžĐžĐąŅ‰ĐĩŅŅ‚Đ˛Đ° **FastAPI** в Ņ‚ĐžĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐąŅ€ĐžĐ´ŅƒŅˆĐŊŅ‹Đŧ и ĐŗĐžŅŅ‚ĐĩĐŋŅ€Đ¸Đ¸ĐŧĐŊŅ‹Đŧи. НĐĩ Đ´ĐžĐŋ҃ҁĐēĐ°ĐšŅ‚Đĩ иСдĐĩĐ˛Đ°Ņ‚ĐĩĐģŅŒŅŅ‚Đ˛ иĐģи ĐŊĐĩŅƒĐ˛Đ°ĐļĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐŋОвĐĩĐ´ĐĩĐŊĐ¸Ņ ĐŋĐž ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸ŅŽ Đē Đ´Ņ€ŅƒĐŗĐ¸Đŧ. ĐœŅ‹ Đ´ĐžĐģĐļĐŊŅ‹ ĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ŅŒŅŅ Đ´Ņ€ŅƒĐŗ Đž Đ´Ņ€ŅƒĐŗĐĩ. +Đ•ŅĐģи Đ’Ņ‹ ĐŧĐŊĐžĐŗĐž ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚Đĩ ĐģŅŽĐ´ŅĐŧ ҁ Đ¸Ņ… вОĐŋŅ€ĐžŅĐ°Đŧи, Đ’Ņ‹ ŅŅ‚Đ°ĐŊĐĩŅ‚Đĩ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅ‹Đŧ [Đ­ĐēҁĐŋĐĩŅ€Ņ‚ĐžĐŧ FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. 🎉 + +ĐĸĐžĐģҌĐēĐž ĐŋĐžĐŧĐŊĐ¸Ņ‚Đĩ, ŅĐ°ĐŧĐžĐĩ ваĐļĐŊĐžĐĩ — ĐŋĐžŅŅ‚Đ°Ņ€Đ°ĐšŅ‚ĐĩҁҌ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐąŅ€Ņ‹Đŧи. Đ›ŅŽĐ´Đ¸ ĐŋŅ€Đ¸Ņ…ĐžĐ´ŅŅ‚ ŅĐž ŅĐ˛ĐžĐ¸Đŧи Ņ€Đ°ĐˇĐžŅ‡Đ°Ņ€ĐžĐ˛Đ°ĐŊĐ¸ŅĐŧи и Ņ‡Đ°ŅŅ‚Đž ĐˇĐ°Đ´Đ°ŅŽŅ‚ вОĐŋŅ€ĐžŅŅ‹ ĐŊĐĩ ĐģŅƒŅ‡ŅˆĐ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ĐŊĐž ĐŋĐžŅŅ‚Đ°Ņ€Đ°ĐšŅ‚ĐĩҁҌ, ĐŊĐ°ŅĐēĐžĐģҌĐēĐž ĐŧĐžĐļĐĩŅ‚Đĩ, ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐąŅ€ĐžĐļĐĩĐģĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи. 🤗 + +ИдĐĩŅ ŅĐžĐžĐąŅ‰ĐĩŅŅ‚Đ˛Đ° **FastAPI** — ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐąŅ€ĐžĐļĐĩĐģĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ и ĐŗĐžŅŅ‚ĐĩĐŋŅ€Đ¸Đ¸ĐŧĐŊŅ‹Đŧ. В Ņ‚Đž ĐļĐĩ Đ˛Ņ€ĐĩĐŧŅ ĐŊĐĩ Đ´ĐžĐŋ҃ҁĐēĐ°ĐšŅ‚Đĩ Ņ‚Ņ€Đ°Đ˛ĐģŅŽ иĐģи ĐŊĐĩŅƒĐ˛Đ°ĐļĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐĩ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ ĐŋĐž ĐžŅ‚ĐŊĐžŅˆĐĩĐŊĐ¸ŅŽ Đē Đ´Ņ€ŅƒĐŗĐ¸Đŧ. ĐœŅ‹ Đ´ĐžĐģĐļĐŊŅ‹ ĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ŅŒŅŅ Đ´Ņ€ŅƒĐŗ Đž Đ´Ņ€ŅƒĐŗĐĩ. --- -КаĐē ĐŋĐžĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ Đ¸Ņ… ĐŋŅ€ĐžĐąĐģĐĩĐŧаĐŧи: +КаĐē ĐŋĐžĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ вОĐŋŅ€ĐžŅĐ°Đŧи (в ĐžĐąŅŅƒĐļĐ´ĐĩĐŊĐ¸ŅŅ… иĐģи Issues): -### ПоĐŊŅŅ‚ŅŒ вОĐŋŅ€ĐžŅ +### ПоĐŊŅŅ‚ŅŒ вОĐŋŅ€ĐžŅ { #understand-the-question } -* ĐŖĐ´ĐžŅŅ‚ĐžĐ˛ĐĩŅ€ŅŒŅ‚ĐĩҁҌ, Ņ‡Ņ‚Đž ĐŋĐžĐŊŅĐģи **҆ĐĩĐģҌ** и ĐžĐąŅŅ‚ĐžŅŅ‚ĐĩĐģŅŒŅŅ‚Đ˛Đ° ҁĐģŅƒŅ‡Đ°Ņ вОĐŋŅ€ĐžŅˆĐ°ŅŽŅ‰ĐĩĐŗĐž. +* ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž ĐŋĐžĐŊŅĐģи **҆ĐĩĐģҌ** и ĐēĐĩĐšŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐˇĐ°Đ´Đ°ŅŽŅ‰ĐĩĐŗĐž вОĐŋŅ€ĐžŅ. -* Đ—Đ°Ņ‚ĐĩĐŧ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž вОĐŋŅ€ĐžŅ (в ĐŋОдавĐģŅŅŽŅ‰ĐĩĐŧ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ - ŅŅ‚Đž вОĐŋŅ€ĐžŅŅ‹) ВаĐŧ **ŅŅĐĩĐŊ**. +* Đ—Đ°Ņ‚ĐĩĐŧ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž вОĐŋŅ€ĐžŅ (в ĐŋОдавĐģŅŅŽŅ‰ĐĩĐŧ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ŅŅ‚Đž вОĐŋŅ€ĐžŅŅ‹) ŅŅ„ĐžŅ€Đŧ҃ĐģĐ¸Ņ€ĐžĐ˛Đ°ĐŊ **ŅŅĐŊĐž**. -* Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… вОĐŋŅ€ĐžŅ ĐēĐ°ŅĐ°ĐĩŅ‚ŅŅ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ ĐŋŅ€Đ¸Đ´ŅƒĐŧаĐģ ŅĐ°Đŧ, ĐŊĐž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ и Ņ€Đĩ҈ĐĩĐŊиĐĩ **ĐŋĐžĐģŅƒŅ‡ŅˆĐĩ**. Đ•ŅĐģи Đ’Ņ‹ ĐŋОКĐŧґ҂Đĩ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ и ĐžĐąŅŅ‚ĐžŅŅ‚ĐĩĐģŅŒŅŅ‚Đ˛Đ° ҁĐģŅƒŅ‡Đ°Ņ, Ņ‚Đž ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ **аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐžĐĩ Ņ€Đĩ҈ĐĩĐŊиĐĩ**. +* Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ҁĐŋŅ€Đ°ŅˆĐ¸Đ˛Đ°ŅŽŅ‚ Đž Đ˛ĐžĐžĐąŅ€Đ°ĐļаĐĩĐŧĐžĐŧ Ņ€Đĩ҈ĐĩĐŊии ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ, ĐŊĐž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ€Đĩ҈ĐĩĐŊиĐĩ **ĐŋĐžĐģŅƒŅ‡ŅˆĐĩ**. Đ•ŅĐģи Đ’Ņ‹ ĐģŅƒŅ‡ŅˆĐĩ ĐŋОКĐŧґ҂Đĩ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ и ĐēĐĩĐšŅ, ҁĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ **аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐŊĐžĐĩ Ņ€Đĩ҈ĐĩĐŊиĐĩ**. -* ЕĐļĐĩĐģи вОĐŋŅ€ĐžŅ ВаĐŧ ĐŊĐĩĐŋĐžĐŊŅŅ‚ĐĩĐŊ, СаĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ йОĐģҌ҈Đĩ **Đ´ĐĩŅ‚Đ°ĐģĐĩĐš**. +* Đ•ŅĐģи вОĐŋŅ€ĐžŅ ĐŊĐĩĐŋĐžĐŊŅŅ‚ĐĩĐŊ, СаĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ йОĐģҌ҈Đĩ **Đ´ĐĩŅ‚Đ°ĐģĐĩĐš**. -### Đ’ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ +### Đ’ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ { #reproduce-the-problem } -В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ĐĩŅŅ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž ŅĐ˛ŅĐˇĐ°ĐŊĐŊĐžĐĩ ҁ **Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đŧ ĐēОдОĐŧ** вОĐŋŅ€ĐžŅˆĐ°ŅŽŅ‰ĐĩĐŗĐž. +В йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв и вОĐŋŅ€ĐžŅĐžĐ˛ ĐĩŅŅ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž ŅĐ˛ŅĐˇĐ°ĐŊĐŊĐžĐĩ ҁ **Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đŧ ĐēОдОĐŧ** Đ°Đ˛Ņ‚ĐžŅ€Đ°. -И вО ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊ Ņ‚ĐžĐģҌĐēĐž Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ ŅŅ‚ĐžĐŗĐž ĐēОда, ĐēĐžŅ‚ĐžŅ€ĐžĐŗĐž ĐŊĐĩĐ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž Đ´ĐģŅ **Đ˛ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩĐ´ĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹**. +Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅŅŽŅ‚ Ņ‚ĐžĐģҌĐēĐž Ņ„Ņ€Đ°ĐŗĐŧĐĩĐŊŅ‚ ĐēОда, ĐŊĐž ŅŅ‚ĐžĐŗĐž ĐŊĐĩĐ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ **Đ˛ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩŅŅ‚Đ¸ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃**. -* ПоĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŧиĐŊиĐŧаĐģҌĐŊŅ‹Đš Đ˛ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸ĐŧŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŧĐžĐļĐŊĐž **ҁĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ** и СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐģĐžĐēаĐģҌĐŊĐž Đ´Đ°ĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Ņ‚Đ°ĐēŅƒŅŽ ĐļĐĩ ĐžŅˆĐ¸ĐąĐē҃, иĐģи ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ, иĐģи ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐžĐŊŅŅ‚ŅŒ ĐžĐąŅŅ‚ĐžŅŅ‚ĐĩĐģŅŒŅŅ‚Đ˛Đ° ҁĐģŅƒŅ‡Đ°Ņ. +* ПоĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ ĐŧиĐŊиĐŧаĐģҌĐŊŅ‹Đš Đ˛ĐžŅĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐžĐ´Đ¸ĐŧŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ’Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ **ҁĐēĐžĐŋĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ-Đ˛ŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ** и СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐģĐžĐēаĐģҌĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Ņ‚Ņƒ ĐļĐĩ ĐžŅˆĐ¸ĐąĐē҃ иĐģи ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ, иĐģи ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐžĐŊŅŅ‚ŅŒ Đ¸Ņ… ĐēĐĩĐšŅ. -* Đ•ŅĐģи ĐŊа Đ’Đ°Ņ ĐŊĐ°Ņ…ĐģŅ‹ĐŊ҃ĐģĐž вĐĩĐģиĐēĐžĐ´ŅƒŅˆĐ¸Đĩ, Ņ‚Đž ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ **ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŋĐžŅ…ĐžĐļиК ĐŋŅ€Đ¸ĐŧĐĩŅ€** ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž, ĐžŅĐŊĐžĐ˛Ņ‹Đ˛Đ°ŅŅŅŒ Ņ‚ĐžĐģҌĐēĐž ĐŊа ĐžĐŋĐ¸ŅĐ°ĐŊии ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. Но иĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ СаĐŊŅŅ‚ŅŒ ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи и, вОСĐŧĐžĐļĐŊĐž, ŅŅ‚ĐžĐ¸Ņ‚ ҁĐŊĐ°Ņ‡Đ°Đģа ĐŋĐžĐˇĐ°Đ´Đ°Đ˛Đ°Ņ‚ŅŒ вОĐŋŅ€ĐžŅŅ‹ Đ´ĐģŅ ĐŋŅ€ĐžŅŅĐŊĐĩĐŊĐ¸Ņ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. +* Đ•ŅĐģи Ņ‡ŅƒĐ˛ŅŅ‚Đ˛ŅƒĐĩŅ‚Đĩ ҁĐĩĐąŅ ĐžŅĐžĐąĐĩĐŊĐŊĐž вĐĩĐģиĐēĐžĐ´ŅƒŅˆĐŊŅ‹Đŧи, ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ **ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ‚Đ°ĐēОК ĐŋŅ€Đ¸ĐŧĐĩŅ€** ŅĐ°Đŧи, ĐžŅĐŊĐžĐ˛Ņ‹Đ˛Đ°ŅŅŅŒ Ņ‚ĐžĐģҌĐēĐž ĐŊа ĐžĐŋĐ¸ŅĐ°ĐŊии ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. ĐŸŅ€ĐžŅŅ‚Đž ĐŋĐžĐŧĐŊĐ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ СаĐŊŅŅ‚ŅŒ ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи, и, вОСĐŧĐžĐļĐŊĐž, ҁĐŊĐ°Ņ‡Đ°Đģа ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ ŅƒŅ‚ĐžŅ‡ĐŊĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃. -### ĐŸŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ Ņ€Đĩ҈ĐĩĐŊиĐĩ +### ĐŸŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ Ņ€Đĩ҈ĐĩĐŊиĐĩ { #suggest-solutions } -* ĐŸĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž ĐēаĐē Đ’Ņ‹ ĐŋĐžĐŊŅĐģи вОĐŋŅ€ĐžŅ, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´Đ°Ņ‚ŅŒ **ĐžŅ‚Đ˛ĐĩŅ‚**. +* ĐŸĐžŅĐģĐĩ Ņ‚ĐžĐŗĐž ĐēаĐē Đ’Ņ‹ ĐŋĐžĐŊŅĐģи вОĐŋŅ€ĐžŅ, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ´Đ°Ņ‚ŅŒ вОСĐŧĐžĐļĐŊŅ‹Đš **ĐžŅ‚Đ˛ĐĩŅ‚**. -* ĐĄĐģĐĩĐ´ŅƒĐĩŅ‚ ĐŋĐžĐŊŅŅ‚ŅŒ **ĐžŅĐŊОвĐŊŅƒŅŽ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ и ĐžĐąŅŅ‚ĐžŅŅ‚ĐĩĐģŅŒŅŅ‚Đ˛Đ° ҁĐģŅƒŅ‡Đ°Ņ**, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ€Đĩ҈ĐĩĐŊиĐĩ ĐģŅƒŅ‡ŅˆĐĩ, ҇ĐĩĐŧ Ņ‚Đž, ĐēĐžŅ‚ĐžŅ€ĐžĐĩ ĐŋŅ‹Ņ‚Đ°ĐģĐ¸ŅŅŒ Ņ€ĐĩаĐģĐ¸ĐˇĐžĐ˛Đ°Ņ‚ŅŒ. +* Во ĐŧĐŊĐžĐŗĐ¸Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐģŅƒŅ‡ŅˆĐĩ ĐŋĐžĐŊŅŅ‚ŅŒ **Đ¸ŅŅ…ĐžĐ´ĐŊŅƒŅŽ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ иĐģи ĐēĐĩĐšŅ**, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁĐŋĐžŅĐžĐą Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ ĐĩŅ‘ ĐģŅƒŅ‡ŅˆĐĩ, ҇ĐĩĐŧ Ņ‚Đž, Ņ‡Ņ‚Đž ĐŋŅ‹Ņ‚Đ°ŅŽŅ‚ŅŅ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ. -### ПоĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ СаĐēŅ€Ņ‹Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ +### ПоĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ СаĐēŅ€Ņ‹Ņ‚ŅŒ { #ask-to-close } -Đ•ŅĐģи ВаĐŧ ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Đģи, Đ˛Ņ‹ŅĐžĐēи ŅˆĐ°ĐŊҁҋ, Ņ‡Ņ‚Đž ВаĐŧ ŅƒĐ´Đ°ĐģĐžŅŅŒ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃, ĐŋĐžĐˇĐ´Ņ€Đ°Đ˛ĐģŅŅŽ, **Đ’Ņ‹ - ĐŗĐĩŅ€ĐžĐš**! đŸĻ¸ +Đ•ŅĐģи ВаĐŧ ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Đģи, вĐĩĐģиĐēа вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒ, Ņ‡Ņ‚Đž Đ’Ņ‹ Ņ€ĐĩŅˆĐ¸Đģи Đ¸Ņ… ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃, ĐŋĐžĐˇĐ´Ņ€Đ°Đ˛ĐģŅŅŽ, **Đ’Ņ‹ — ĐŗĐĩŅ€ĐžĐš**! đŸĻ¸ -* В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ, ĐĩҁĐģи вОĐŋŅ€ĐžŅ Ņ€ĐĩŅˆŅ‘ĐŊ, ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ **СаĐēŅ€Ņ‹Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃**. +* ĐĸĐĩĐŋĐĩŅ€ŅŒ, ĐĩҁĐģи ĐŋŅ€ĐžĐąĐģĐĩĐŧа Ņ€Đĩ҈ĐĩĐŊа, ĐŧĐžĐļĐŊĐž ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ Đ¸Ņ…: + * В GitHub Discussions: ĐŋĐžĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đš ĐēаĐē **answer** (ĐžŅ‚Đ˛ĐĩŅ‚). + * В GitHub Issues: **СаĐēŅ€Ņ‹Ņ‚ŅŒ** Issue. -## ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ Ņ€ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Đ¸Đš ĐŊа GitHub +## ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ Ņ€ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Đ¸Đš ĐŊа GitHub { #watch-the-github-repository } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ "ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ" FastAPI ĐŊа GitHub (ĐēĐģиĐēĐŊĐ¸Ņ‚Đĩ ĐŋĐž ĐēĐŊĐžĐŋĐēĐĩ "watch" ĐŊавĐĩŅ€Ņ…Ņƒ ҁĐŋŅ€Đ°Đ˛Đ°): https://github.com/fastapi/fastapi. 👀 +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ "ĐžŅ‚ŅĐģĐĩĐļĐ¸Đ˛Đ°Ņ‚ŅŒ" FastAPI ĐŊа GitHub (ĐēĐģиĐēĐŊŅƒĐ˛ ĐŋĐž ĐēĐŊĐžĐŋĐēĐĩ "watch" ĐŊавĐĩŅ€Ņ…Ņƒ ҁĐŋŅ€Đ°Đ˛Đ°): https://github.com/fastapi/fastapi. 👀 -Đ•ŅĐģи Đ’Ņ‹ Đ˛Ņ‹ĐąĐĩŅ€ĐĩŅ‚Đĩ "Watching" вĐŧĐĩŅŅ‚Đž "Releases only", Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ ĐēĐžĐŗĐ´Đ° ĐēŅ‚Đž-ĐģийО ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ Đž ĐŋĐžĐŧĐžŅ‰Đ¸ ҁ Ņ€Đĩ҈ĐĩĐŊиĐĩĐŧ ĐĩĐŗĐž ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹. +Đ•ŅĐģи Đ’Ņ‹ Đ˛Ņ‹ĐąĐĩŅ€ĐĩŅ‚Đĩ "Watching" вĐŧĐĩŅŅ‚Đž "Releases only", Ņ‚Đž ĐąŅƒĐ´ĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ, ĐēĐžĐŗĐ´Đ° ĐēŅ‚Đž-ĐģийО ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚ ĐŊĐžĐ˛Ņ‹Đš вОĐŋŅ€ĐžŅ иĐģи Issue. Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģĐĩĐŊĐ¸Ņ Ņ‚ĐžĐģҌĐēĐž Đž ĐŊĐžĐ˛Ņ‹Ņ… Issues, иĐģи ĐžĐąŅŅƒĐļĐ´ĐĩĐŊĐ¸ŅŅ…, иĐģи Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ°Ņ… и Ņ‚.Đ´. -ĐĸĐžĐŗĐ´Đ° Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ ŅŅ‚Ņƒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃. +ĐĸĐžĐŗĐ´Đ° Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‡ŅŒ иĐŧ ҁ Ņ€Đĩ҈ĐĩĐŊиĐĩĐŧ ŅŅ‚Đ¸Ņ… вОĐŋŅ€ĐžŅĐžĐ˛. -## ЗаĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰ŅŒ ҁ Ņ€Đĩ҈ĐĩĐŊиĐĩĐŧ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ +## Đ—Đ°Đ´Đ°Ņ‚ŅŒ вОĐŋŅ€ĐžŅŅ‹ { #ask-questions } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đš СаĐŋŅ€ĐžŅ ҁ ĐŋŅ€ĐžŅŅŒĐąĐžĐš Đž ĐŋĐžĐŧĐžŅ‰Đ¸ в Ņ€ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Đ¸Đ¸ ĐŊа GitHub, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đš вОĐŋŅ€ĐžŅ в Ņ€ĐĩĐŋĐžĐˇĐ¸Ņ‚ĐžŅ€Đ¸Đ¸ GitHub, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: -* Đ—Đ°Đ´Đ°Ņ‚ŅŒ **вОĐŋŅ€ĐžŅ** иĐģи ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰Đ¸ в Ņ€Đĩ҈ĐĩĐŊии **ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹**. -* ĐŸŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ ĐŊОвОĐĩ **҃ĐģŅƒŅ‡ŅˆĐĩĐŊиĐĩ**. +* Đ—Đ°Đ´Đ°Ņ‚ŅŒ **вОĐŋŅ€ĐžŅ** иĐģи ҁĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ Đž **ĐŋŅ€ĐžĐąĐģĐĩĐŧĐĩ**. +* ĐŸŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ ĐŊĐžĐ˛ŅƒŅŽ **вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ**. -**ЗаĐŧĐĩŅ‚Đēа**: Đ•ŅĐģи Đ’Ņ‹ ŅĐžĐˇĐ´Đ°Ņ‘Ņ‚Đĩ ĐŋОдОйĐŊŅ‹Đĩ СаĐŋŅ€ĐžŅŅ‹, Ņ‚Đž Ņ ĐŋĐžĐŋŅ€ĐžŅˆŅƒ Đ’Đ°Ņ Ņ‚Đ°ĐēĐļĐĩ ĐžĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅƒŅŽ ĐŋĐžĐŧĐžŅ‰ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ. 😉 +**ЗаĐŧĐĩŅ‚Đēа**: ĐĩҁĐģи Đ’Ņ‹ ŅŅ‚Đž ŅĐ´ĐĩĐģаĐĩŅ‚Đĩ, Ņ‚Đž Ņ ĐŋĐžĐŋŅ€ĐžŅˆŅƒ Đ’Đ°Ņ Ņ‚Đ°ĐēĐļĐĩ ĐŋĐžĐŧĐžĐŗĐ°Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ. 😉 -## ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ +## ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ { #review-pull-requests } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŧĐžŅ‡ŅŒ ĐŧĐŊĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ŅƒŅ‡Đ°ŅŅ‚ĐŊиĐēОв. +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŧĐžŅ‡ŅŒ ĐŧĐŊĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ Đ´Ņ€ŅƒĐŗĐ¸Ņ… ŅƒŅ‡Đ°ŅŅ‚ĐŊиĐēОв. -И ĐŋĐžĐ˛Ņ‚ĐžŅ€ŅŽŅŅŒ, ĐŋĐžŅŅ‚Đ°Ņ€Đ°ĐšŅ‚ĐĩҁҌ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐąŅ€ĐžĐļĐĩĐģĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ. 🤗 +И, ҁĐŊОва, ĐŋĐžŅŅ‚Đ°Ņ€Đ°ĐšŅ‚ĐĩҁҌ ĐąŅ‹Ņ‚ŅŒ Đ´ĐžĐąŅ€ĐžĐļĐĩĐģĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧи. 🤗 --- -О Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž иĐŧĐĩŅ‚ŅŒ в Đ˛Đ¸Đ´Ņƒ ĐŋŅ€Đ¸ ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐēĐĩ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚ĐžĐ˛: +О Ņ‚ĐžĐŧ, Ņ‡Ņ‚Đž ĐŊ҃ĐļĐŊĐž иĐŧĐĩŅ‚ŅŒ в Đ˛Đ¸Đ´Ņƒ и ĐēаĐē ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂: -### ПоĐŊŅŅ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ +### ПоĐŊŅŅ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ { #understand-the-problem } -* Во-ĐŋĐĩŅ€Đ˛Ņ‹Ņ…, ŅƒĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž **ĐŋĐžĐŊŅĐģи ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃**, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ ĐŋŅ‹Ņ‚Đ°ĐĩŅ‚ŅŅ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ. ДĐģŅ ŅŅ‚ĐžĐŗĐž ĐŧĐžĐļĐĩŅ‚ ĐŋĐžŅ‚Ņ€ĐĩĐąĐžĐ˛Đ°Ņ‚ŅŒŅŅ ĐŋŅ€ĐžĐ´ĐžĐģĐļĐ¸Ņ‚ĐĩĐģҌĐŊĐžĐĩ ĐžĐąŅŅƒĐļĐ´ĐĩĐŊиĐĩ. +* Во-ĐŋĐĩŅ€Đ˛Ņ‹Ņ…, ŅƒĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž **ĐŋĐžĐŊŅĐģи ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃**, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ ĐŋŅ‹Ņ‚Đ°ĐĩŅ‚ŅŅ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ. ВозĐŧĐžĐļĐŊĐž, ŅŅ‚Đž ĐžĐąŅŅƒĐļдаĐģĐžŅŅŒ йОĐģĐĩĐĩ ĐŋĐžĐ´Ņ€ĐžĐąĐŊĐž в GitHub Discussion иĐģи Issue. -* ĐĸаĐēĐļĐĩ ĐĩŅŅ‚ŅŒ вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒ, Ņ‡Ņ‚Đž Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ ĐŊĐĩ аĐēŅ‚ŅƒĐ°ĐģĐĩĐŊ, Ņ‚Đ°Đē ĐēаĐē ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ ĐŧĐžĐļĐŊĐž Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ **Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋŅƒŅ‚Ņ‘Đŧ**. В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐŊа ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐēŅ‚. +* ĐĸаĐēĐļĐĩ ĐĩŅŅ‚ŅŒ вĐĩŅ€ĐžŅŅ‚ĐŊĐžŅŅ‚ŅŒ, Ņ‡Ņ‚Đž Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ ĐŊĐĩ ĐŊ҃ĐļĐĩĐŊ, Ņ‚Đ°Đē ĐēаĐē ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ ĐŧĐžĐļĐŊĐž Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ **Đ´Ņ€ŅƒĐŗĐ¸Đŧ ĐŋŅƒŅ‚Ņ‘Đŧ**. ĐĸĐžĐŗĐ´Đ° Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ иĐģи ҁĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ Ой ŅŅ‚ĐžĐŧ. -### НĐĩ ĐŋĐĩŅ€ĐĩĐļĐ¸Đ˛Đ°ĐšŅ‚Đĩ Đž ŅŅ‚Đ¸ĐģĐĩ +### НĐĩ ĐŋĐĩŅ€ĐĩĐļĐ¸Đ˛Đ°ĐšŅ‚Đĩ Đž ŅŅ‚Đ¸ĐģĐĩ { #dont-worry-about-style } -* НĐĩ ŅŅ‚ĐžĐ¸Ņ‚ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐąĐĩҁĐŋĐžĐēĐžĐ¸Ņ‚ŅŒŅŅ Đž Ņ‚Đ°ĐēĐ¸Ņ… вĐĩŅ‰Đ°Ņ…, ĐēаĐē ŅŅ‚Đ¸ĐģҌ ŅĐžĐžĐąŅ‰ĐĩĐŊиК в ĐēĐžĐŧĐŧĐ¸Ņ‚Đ°Ņ… иĐģи ĐēĐžĐģĐ¸Ņ‡ĐĩŅŅ‚Đ˛Đž ĐēĐžĐŧĐŧĐ¸Ņ‚ĐžĐ˛. ĐŸŅ€Đ¸ ҁĐģĐ¸ŅĐŊии Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ° ҁ ĐžŅĐŊОвĐŊОК вĐĩŅ‚ĐēОК, Ņ ĐąŅƒĐ´Ņƒ ҁĐļиĐŧĐ°Ņ‚ŅŒ и ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°Ņ‚ŅŒ Đ˛ŅŅ‘ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ. +* НĐĩ ŅŅ‚ĐžĐ¸Ņ‚ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐąĐĩҁĐŋĐžĐēĐžĐ¸Ņ‚ŅŒŅŅ Đž Ņ‚Đ°ĐēĐ¸Ņ… вĐĩŅ‰Đ°Ņ…, ĐēаĐē ŅŅ‚Đ¸ĐģҌ ŅĐžĐžĐąŅ‰ĐĩĐŊиК в ĐēĐžĐŧĐŧĐ¸Ņ‚Đ°Ņ… — ĐŋŅ€Đ¸ ҁĐģĐ¸ŅĐŊии Ņ Đ˛Ņ‹ĐŋĐžĐģĐŊŅŽ squash и ĐŊĐ°ŅŅ‚Ņ€ĐžŅŽ ĐēĐžĐŧĐŧĐ¸Ņ‚ Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ. -* ĐĸаĐēĐļĐĩ ĐŊĐĩ ĐąĐĩҁĐŋĐžĐēĐžĐšŅ‚ĐĩҁҌ Đž ĐŋŅ€Đ°Đ˛Đ¸ĐģĐ°Ņ… ŅŅ‚Đ¸ĐģŅ, Đ´ĐģŅ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи ҁĐĩĐŗĐž ĐĩŅŅ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ. +* ĐĸаĐēĐļĐĩ ĐŊĐĩ ĐąĐĩҁĐŋĐžĐēĐžĐšŅ‚ĐĩҁҌ Đž ĐŋŅ€Đ°Đ˛Đ¸ĐģĐ°Ņ… ŅŅ‚Đ¸ĐģŅ, ŅŅ‚Đž ҃ĐļĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅŽŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸ĐˇĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ. -И ĐĩҁĐģи Đ˛ŅŅ‘ ĐļĐĩ ĐŋĐžŅ‚Ņ€ĐĩĐąŅƒĐĩŅ‚ŅŅ ĐēаĐēОК-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚Đ¸ĐģҌ, Ņ ĐŋĐžĐŋŅ€ĐžŅˆŅƒ Đ’Đ°Ņ Ой ŅŅ‚ĐžĐŧ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иĐģи дОйавĐģŅŽ ŅĐ°Đŧ ĐēĐžĐŧĐŧĐ¸Ņ‚Ņ‹ ҁ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đŧи иСĐŧĐĩĐŊĐĩĐŊĐ¸ŅĐŧи. +Đ•ŅĐģи ĐąŅƒĐ´ĐĩŅ‚ ĐŊ҃ĐļĐŊа ĐēаĐēĐ°Ņ-Ņ‚Đž Đ´Ņ€ŅƒĐŗĐ°Ņ ŅŅ‚Đ¸ĐģĐ¸ŅŅ‚Đ¸Đēа иĐģи ĐĩдиĐŊĐžĐžĐąŅ€Đ°ĐˇĐ¸Đĩ, Ņ ĐŋĐžĐŋŅ€ĐžŅˆŅƒ Ой ŅŅ‚ĐžĐŧ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ иĐģи дОйавĐģŅŽ ĐŋОвĐĩҀ҅ ŅĐ˛ĐžĐ¸ ĐēĐžĐŧĐŧĐ¸Ņ‚Ņ‹ ҁ ĐŊ҃ĐļĐŊŅ‹Đŧи иСĐŧĐĩĐŊĐĩĐŊĐ¸ŅĐŧи. -### ĐŸŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ ĐēОд +### ĐŸŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ ĐēОд { #check-the-code } -* ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ и ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ ĐēОд, ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ, ĐēаĐēОК ĐžĐŊ иĐŧĐĩĐĩŅ‚ ҁĐŧҋҁĐģ, **СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐĩĐŗĐž ĐģĐžĐēаĐģҌĐŊĐž** и ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ, Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž Đģи ĐžĐŊ Ņ€ĐĩŅˆĐ°ĐĩŅ‚ ĐŋĐžŅŅ‚Đ°Đ˛ĐģĐĩĐŊĐŊŅƒŅŽ ĐˇĐ°Đ´Đ°Ņ‡Ņƒ. +* ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ и ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ ĐēОд, ĐŋĐžŅĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ, ĐģĐžĐŗĐ¸Ņ‡ĐĩĐŊ Đģи ĐžĐŊ, **СаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ĐĩĐŗĐž ĐģĐžĐēаĐģҌĐŊĐž** и ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž Đģи ĐžĐŊ Ņ€ĐĩŅˆĐ°ĐĩŅ‚ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃. -* Đ—Đ°Ņ‚ĐĩĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ **ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đš**, ŅĐžĐžĐąŅ‰Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ’Ņ‹ ŅĐ´ĐĩĐģаĐģи ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃, Ņ‚ĐžĐŗĐ´Đ° Ņ ĐąŅƒĐ´Ņƒ СĐŊĐ°Ņ‚ŅŒ, Ņ‡Ņ‚Đž Đ’Ņ‹ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Đģи ĐēОд. +* Đ—Đ°Ņ‚ĐĩĐŧ ĐžŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ **ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đš**, Ņ‡Ņ‚Đž Đ’Ņ‹ ŅŅ‚Đž ŅĐ´ĐĩĐģаĐģи, Ņ‚Đ°Đē Ņ ĐŋОКĐŧ҃, Ņ‡Ņ‚Đž Đ’Ņ‹ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Đģи ĐēОд. /// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ -К ŅĐžĐļаĐģĐĩĐŊĐ¸ŅŽ, Ņ ĐŊĐĩ ĐŧĐžĐŗŅƒ Ņ‚Đ°Đē ĐŋŅ€ĐžŅŅ‚Đž дОвĐĩŅ€ŅŅ‚ŅŒ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ°Đŧ, ҃ ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҃ĐļĐĩ ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐžĐ´ĐžĐąŅ€ĐĩĐŊиК. +К ŅĐžĐļаĐģĐĩĐŊĐ¸ŅŽ, Ņ ĐŊĐĩ ĐŧĐžĐŗŅƒ ĐŋŅ€ĐžŅŅ‚Đž дОвĐĩŅ€ŅŅ‚ŅŒ PR-аĐŧ Ņ‚ĐžĐģҌĐēĐž ĐŋĐžŅ‚ĐžĐŧ҃, Ņ‡Ņ‚Đž ҃ ĐŊĐ¸Ņ… ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐžĐ´ĐžĐąŅ€ĐĩĐŊиК. -Đ‘Ņ‹Đ˛Đ°Đģи ҁĐģŅƒŅ‡Đ°Đ¸, Ņ‡Ņ‚Đž Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ иĐŧĐĩĐģи 3, 5 иĐģи йОĐģҌ҈Đĩ ĐžĐ´ĐžĐąŅ€ĐĩĐŊиК, вĐĩŅ€ĐžŅŅ‚ĐŊĐž иС-Са ĐŋŅ€Đ¸Đ˛ĐģĐĩĐēĐ°Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐžĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ, ĐŊĐž ĐēĐžĐŗĐ´Đ° Ņ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐģ ŅŅ‚Đ¸ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ, ĐžĐŊи ĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐģĐ¸ŅŅŒ ҁĐģĐžĐŧаĐŊŅ‹, ŅĐžĐ´ĐĩŅ€ĐļаĐģи ĐžŅˆĐ¸ĐąĐēи иĐģи Đ˛ĐžĐ˛ŅĐĩ ĐŊĐĩ Ņ€ĐĩŅˆĐ°Đģи ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ, ĐēаĐē ĐžĐŊи ŅƒŅ‚Đ˛ĐĩŅ€ĐļдаĐģи, Đ´ĐžĐģĐļĐŊŅ‹ ĐąŅ‹Đģи Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ. 😅 +НĐĩҁĐēĐžĐģҌĐēĐž Ņ€Đ°Đˇ ĐąŅ‹ĐģĐž Ņ‚Đ°Đē, Ņ‡Ņ‚Đž ҃ PR-Ов ĐąŅ‹ĐģĐž 3, 5 иĐģи йОĐģҌ҈Đĩ ĐžĐ´ĐžĐąŅ€ĐĩĐŊиК, вĐĩŅ€ĐžŅŅ‚ĐŊĐž иС-Са ĐŋŅ€Đ¸Đ˛ĐģĐĩĐēĐ°Ņ‚ĐĩĐģҌĐŊĐžĐŗĐž ĐžĐŋĐ¸ŅĐ°ĐŊĐ¸Ņ, ĐŊĐž ĐēĐžĐŗĐ´Đ° Ņ Đ¸Ņ… ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐģ, ĐžĐŊи ĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐģĐ¸ŅŅŒ ҁĐģĐžĐŧаĐŊĐŊŅ‹Đŧи, ŅĐžĐ´ĐĩŅ€ĐļаĐģи ĐąĐ°ĐŗĐ¸ иĐģи Đ˛ĐžĐ˛ŅĐĩ ĐŊĐĩ Ņ€ĐĩŅˆĐ°Đģи ĐˇĐ°ŅĐ˛ĐģĐĩĐŊĐŊŅƒŅŽ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃. 😅 -ĐŸĐžŅ‚ĐžĐŧ҃ ŅŅ‚Đž Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ваĐļĐŊĐž - ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ и СаĐŋ҃ҁĐēĐ°Ņ‚ŅŒ ĐēОд, и ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸ĐĩĐŧ ŅƒĐ˛ĐĩĐ´ĐžĐŧĐģŅŅ‚ŅŒ ĐŧĐĩĐŊŅ, Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŋŅ€ĐžĐ´ĐĩĐģаĐģи ŅŅ‚Đ¸ Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ. 🤓 +ĐŸĐžŅŅ‚ĐžĐŧ҃ ĐžŅ‡ĐĩĐŊҌ ваĐļĐŊĐž Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ и СаĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ĐēОд и ŅĐžĐžĐąŅ‰Đ¸Ņ‚ŅŒ ĐŧĐŊĐĩ Ой ŅŅ‚ĐžĐŧ в ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đ¸. 🤓 /// -* Đ•ŅĐģи Đ’Ņ‹ ŅŅ‡Đ¸Ņ‚Đ°ĐĩŅ‚Đĩ, Ņ‡Ņ‚Đž Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ ĐŧĐžĐļĐŊĐž ҃ĐŋŅ€ĐžŅŅ‚Đ¸Ņ‚ŅŒ, Ņ‚Đž ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ Ой ŅŅ‚ĐžĐŧ, ĐŊĐž ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐŋŅ€Đ¸Đ´Đ¸Ņ€Ņ‡Đ¸Đ˛Ņ‹Đŧ, ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŧĐŊĐžĐŗĐž ŅŅƒĐąŅŠĐĩĐēŅ‚Đ¸Đ˛ĐŊҋ҅ Ņ‚ĐžŅ‡ĐĩĐē ĐˇŅ€ĐĩĐŊĐ¸Ņ (и ҃ ĐŧĐĩĐŊŅ Ņ‚ĐžĐļĐĩ ĐąŅƒĐ´ĐĩŅ‚ ŅĐ˛ĐžŅ 🙈), ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐąŅƒĐ´ĐĩŅ‚ ĐģŅƒŅ‡ŅˆĐĩ, ĐĩҁĐģи Đ’Ņ‹ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸Ņ‚ĐĩҁҌ ĐŊа Ņ„ŅƒĐŊдаĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊҋ҅ вĐĩŅ‰Đ°Ņ…. +* Đ•ŅĐģи PR ĐŧĐžĐļĐŊĐž ҃ĐŋŅ€ĐžŅŅ‚Đ¸Ņ‚ŅŒ, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŋŅ€ĐžŅĐ¸Ņ‚ŅŒ Ой ŅŅ‚ĐžĐŧ, ĐŊĐž ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐŋŅ€Đ¸Đ´Đ¸Ņ€Ņ‡Đ¸Đ˛Ņ‹Đŧ — ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŧĐŊĐžĐŗĐž ŅŅƒĐąŅŠĐĩĐēŅ‚Đ¸Đ˛ĐŊҋ҅ ĐŧĐŊĐĩĐŊиК (и ҃ ĐŧĐĩĐŊŅ Ņ‚ĐžĐļĐĩ 🙈), ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐģŅƒŅ‡ŅˆĐĩ ŅĐžŅŅ€ĐĩĐ´ĐžŅ‚ĐžŅ‡Đ¸Ņ‚ŅŒŅŅ ĐŊа Ņ„ŅƒĐŊдаĐŧĐĩĐŊŅ‚Đ°ĐģҌĐŊҋ҅ вĐĩŅ‰Đ°Ņ…. -### ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ +### ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ { #tests } -* ПоĐŧĐžĐŗĐ¸Ņ‚Đĩ ĐŧĐŊĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž ҃ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ° ĐĩŅŅ‚ŅŒ **Ņ‚Đĩҁ҂ҋ**. +* ПоĐŧĐžĐŗĐ¸Ņ‚Đĩ ĐŧĐŊĐĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ, Ņ‡Ņ‚Đž ҃ PR ĐĩŅŅ‚ŅŒ **Ņ‚Đĩҁ҂ҋ**. -* ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đĩҁ҂ҋ **ĐŋадаĐģи** Đ´Đž Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ°. 🚨 +* ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đĩҁ҂ҋ **ĐŋĐ°Đ´Đ°ŅŽŅ‚** Đ´Đž PR. 🚨 -* Đ—Đ°Ņ‚ĐĩĐŧ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đĩҁ҂ҋ **ĐŊĐĩ ваĐģŅŅ‚ŅŅ** ĐŋĐžŅĐģĐĩ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ°. ✅ +* Đ—Đ°Ņ‚ĐĩĐŧ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ, Ņ‡Ņ‚Đž Ņ‚Đĩҁ҂ҋ **ĐŋŅ€ĐžŅ…ĐžĐ´ŅŅ‚** ĐŋĐžŅĐģĐĩ PR. ✅ -* МĐŊĐžĐŗĐ¸Đĩ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ ĐŊĐĩ иĐŧĐĩŅŽŅ‚ Ņ‚ĐĩŅŅ‚ĐžĐ˛, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ **ĐŊаĐŋĐžĐŧĐŊĐ¸Ņ‚ŅŒ** Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ дОйавĐģĐĩĐŊĐ¸Ņ Ņ‚ĐĩŅŅ‚ĐžĐ˛ иĐģи даĐļĐĩ **ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ** ĐēаĐēиĐĩ-ĐģийО ŅĐ˛ĐžĐ¸ Ņ‚Đĩҁ҂ҋ. Đ­Ņ‚Đž ОдĐŊа иС Ņ‚ĐĩŅ… вĐĩ҉ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžŅ‚ĐŊиĐŧĐ°ŅŽŅ‚ ĐŧĐŊĐžĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи и Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŧĐžŅ‡ŅŒ ҁ ŅŅ‚Đ¸Đŧ. +* МĐŊĐžĐŗĐ¸Đĩ PR ĐŊĐĩ иĐŧĐĩŅŽŅ‚ Ņ‚ĐĩŅŅ‚ĐžĐ˛ — Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ **ĐŊаĐŋĐžĐŧĐŊĐ¸Ņ‚ŅŒ** Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ‚Đĩҁ҂ҋ иĐģи даĐļĐĩ **ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ** ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ‚Đĩҁ҂ҋ ŅĐ°Đŧи. Đ­Ņ‚Đž ОдĐŊа иС ŅĐ°Đŧҋ҅ Ņ‚Ņ€ŅƒĐ´ĐžĐˇĐ°Ņ‚Ņ€Đ°Ņ‚ĐŊҋ҅ Ņ‡Đ°ŅŅ‚ĐĩĐš, и СдĐĩҁҌ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‡ĐĩĐŊҌ ĐŋĐžĐŧĐžŅ‡ŅŒ. -* Đ—Đ°Ņ‚ĐĩĐŧ Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đš, Ņ‡Ņ‚Đž Đ’Ņ‹ Đ¸ŅĐŋŅ€ĐžĐąĐžĐ˛Đ°Đģи в Ņ…ĐžĐ´Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи. ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ Ņ ĐąŅƒĐ´Ņƒ СĐŊĐ°Ņ‚ŅŒ, ĐēаĐē Đ’Ņ‹ ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩĐģи ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃. 🤓 +* Đ—Đ°Ņ‚ĐĩĐŧ Đ´ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ ĐēĐžĐŧĐŧĐĩĐŊŅ‚Đ°Ņ€Đ¸Đš, Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Đģи, Ņ‡Ņ‚ĐžĐąŅ‹ Ņ СĐŊаĐģ, Ņ‡Ņ‚Đž Đ’Ņ‹ ŅŅ‚Đž ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Đģи. 🤓 -## ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ +## ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ { #create-a-pull-request } -Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ [ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ вĐēĐģад](contributing.md){.internal-link target=_blank} в ĐēОд ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ [ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ вĐēĐģад](contributing.md){.internal-link target=_blank} в Đ¸ŅŅ…ĐžĐ´ĐŊŅ‹Đš ĐēОд Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩŅŅ‚Đ°Đŧи, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: -* Đ˜ŅĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒ ĐžĐŋĐĩŅ‡Đ°Ņ‚Đē҃, ĐēĐžŅ‚ĐžŅ€ŅƒŅŽ Đ’Ņ‹ ĐŊĐ°ŅˆĐģи в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. -* ПодĐĩĐģĐ¸Ņ‚ŅŒŅŅ ŅŅ‚Đ°Ņ‚ŅŒŅ‘Đš, видĐĩĐž иĐģи ĐŋОдĐēĐ°ŅŅ‚ĐžĐŧ Đž FastAPI, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ’Ņ‹ ŅĐžĐˇĐ´Đ°Đģи иĐģи ĐŊĐ°ŅˆĐģи иСĐŧĐĩĐŊив ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ. - * ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž Đ’Ņ‹ дОйавиĐģи ŅĐ˛ĐžŅŽ ҁҁҋĐģĐē҃ в ĐŊĐ°Ņ‡Đ°ĐģĐž ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ĐĩĐŗĐž Ņ€Đ°ĐˇĐ´ĐĩĐģа. -* ПоĐŧĐžŅ‡ŅŒ ҁ [ĐŋĐĩŅ€ĐĩвОдОĐŧ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸](contributing.md#_8){.internal-link target=_blank} ĐŊа Đ’Đ°Ņˆ ŅĐˇŅ‹Đē. - * Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´Ņ‹ ŅĐ´ĐĩĐģаĐŊĐŊŅ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đŧи. +* Đ˜ŅĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒ ĐžĐŋĐĩŅ‡Đ°Ņ‚Đē҃, ĐŊаКдĐĩĐŊĐŊŅƒŅŽ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. +* ПодĐĩĐģĐ¸Ņ‚ŅŒŅŅ ŅŅ‚Đ°Ņ‚ŅŒŅ‘Đš, видĐĩĐž иĐģи ĐŋОдĐēĐ°ŅŅ‚ĐžĐŧ Đž FastAPI, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ’Ņ‹ ŅĐžĐˇĐ´Đ°Đģи иĐģи ĐŊĐ°ŅˆĐģи, иСĐŧĐĩĐŊив ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ. + * ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž дОйавиĐģи ŅĐ˛ĐžŅŽ ҁҁҋĐģĐē҃ в ĐŊĐ°Ņ‡Đ°ĐģĐž ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ĐĩĐŗĐž Ņ€Đ°ĐˇĐ´ĐĩĐģа. +* ПоĐŧĐžŅ‡ŅŒ ҁ [ĐŋĐĩŅ€ĐĩвОдОĐŧ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸](contributing.md#translations){.internal-link target=_blank} ĐŊа Đ’Đ°Ņˆ ŅĐˇŅ‹Đē. + * Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ ĐŋĐĩŅ€ĐĩĐ˛ĐžĐ´Ņ‹, ŅĐ´ĐĩĐģаĐŊĐŊŅ‹Đĩ Đ´Ņ€ŅƒĐŗĐ¸Đŧи. * ĐŸŅ€ĐĩĐ´ĐģĐžĐļĐ¸Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đĩ Ņ€Đ°ĐˇĐ´ĐĩĐģŅ‹ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. -* Đ˜ŅĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰ŅƒĐĩ ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹/ĐąĐ°ĐŗĐ¸. +* Đ˜ŅĐŋŅ€Đ°Đ˛Đ¸Ņ‚ŅŒ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰ŅƒŅŽ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃/ĐąĐ°Đŗ. * ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž дОйавиĐģи Ņ‚Đĩҁ҂ҋ. * Đ”ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŊĐžĐ˛ŅƒŅŽ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ. * ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž дОйавиĐģи Ņ‚Đĩҁ҂ҋ. - * ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž дОйавиĐģи Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, ĐĩҁĐģи ĐžĐŊа ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧа. + * ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž дОйавиĐģи Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, ĐĩҁĐģи ŅŅ‚Đž ҃ĐŧĐĩҁ҂ĐŊĐž. -## ПоĐŧĐžŅ‡ŅŒ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ FastAPI +## ПоĐŧĐžŅ‡ŅŒ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ FastAPI { #help-maintain-fastapi } ПоĐŧĐžĐŗĐ¸Ņ‚Đĩ ĐŧĐŊĐĩ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ **FastAPI**! 🤓 -ĐŸŅ€ĐĩĐ´ŅŅ‚ĐžĐ¸Ņ‚ Đĩ҉ґ ĐŧĐŊĐžĐŗĐž Ņ€Đ°ĐąĐžŅ‚Ņ‹ и, ĐŋĐž йОĐģҌ҈ĐĩĐš Ņ‡Đ°ŅŅ‚Đ¸, **ВĐĢ** ĐŧĐžĐļĐĩŅ‚Đĩ ĐĩŅ‘ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ. +ĐŸŅ€ĐĩĐ´ŅŅ‚ĐžĐ¸Ņ‚ Đĩ҉ґ ĐŧĐŊĐžĐŗĐž Ņ€Đ°ĐąĐžŅ‚Ņ‹, и, ĐŋĐž йОĐģҌ҈ĐĩĐš Ņ‡Đ°ŅŅ‚Đ¸, **ВĐĢ** ĐŧĐžĐļĐĩŅ‚Đĩ ĐĩŅ‘ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ. ĐžŅĐŊОвĐŊŅ‹Đĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ˛Ņ‹ĐŋĐžĐģĐŊĐ¸Ņ‚ŅŒ ĐŋŅ€ŅĐŧĐž ҁĐĩĐšŅ‡Đ°Ņ: -* [ПоĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ Đ¸Ņ… ĐŋŅ€ĐžĐąĐģĐĩĐŧаĐŧи ĐŊа GitHub](#github_1){.internal-link target=_blank} (ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Đ˛Ņ‹ŅˆĐĩŅŅ‚ĐžŅŅ‰ŅƒŅŽ ҁĐĩĐēŅ†Đ¸ŅŽ). -* [ĐŸŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ Đŋ҃Đģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ](#-){.internal-link target=_blank} (ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ Đ˛Ņ‹ŅˆĐĩŅŅ‚ĐžŅŅ‰ŅƒŅŽ ҁĐĩĐēŅ†Đ¸ŅŽ). +* [ПоĐŧĐžŅ‡ŅŒ Đ´Ņ€ŅƒĐŗĐ¸Đŧ ҁ вОĐŋŅ€ĐžŅĐ°Đŧи ĐŊа GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ҁĐĩĐēŅ†Đ¸ŅŽ Đ˛Ņ‹ŅˆĐĩ). +* [ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ Đŋ҃ĐģĐģ-Ņ€ĐĩĐēвĐĩҁ҂ҋ](#review-pull-requests){.internal-link target=_blank} (ҁĐŧĐžŅ‚Ņ€Đ¸Ņ‚Đĩ ҁĐĩĐēŅ†Đ¸ŅŽ Đ˛Ņ‹ŅˆĐĩ). -Đ­Ņ‚Đ¸ двĐĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ **ĐžŅ‚ĐŊиĐŧĐ°ŅŽŅ‚ йОĐģҌ҈Đĩ Đ˛ŅĐĩĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи**. Đ­Ņ‚Đž ĐžŅĐŊОвĐŊĐ°Ņ Ņ€Đ°ĐąĐžŅ‚Đ° ĐŋĐž ĐŋОддĐĩŅ€ĐļĐēĐĩ FastAPI. +ИĐŧĐĩĐŊĐŊĐž ŅŅ‚Đ¸ двĐĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸ **ĐˇĐ°ĐąĐ¸Ņ€Đ°ŅŽŅ‚ йОĐģҌ҈Đĩ Đ˛ŅĐĩĐŗĐž Đ˛Ņ€ĐĩĐŧĐĩĐŊи**. Đ­Ņ‚Đž ĐžŅĐŊОвĐŊĐ°Ņ Ņ€Đ°ĐąĐžŅ‚Đ° ĐŋĐž ĐŋОддĐĩŅ€ĐļĐēĐĩ FastAPI. -Đ•ŅĐģи Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŧĐžŅ‡ŅŒ ĐŧĐŊĐĩ ҁ ŅŅ‚Đ¸Đŧ, **Đ’Ņ‹ ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚Đĩ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ FastAPI** и ҁĐģĐĩĐ´Đ¸Ņ‚ŅŒ Са Ņ‚ĐĩĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐģ **Ņ€Đ°ĐˇĐ˛Đ¸Đ˛Đ°Ņ‚ŅŒŅŅ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ и ĐģŅƒŅ‡ŅˆĐĩ**. 🚀 +Đ•ŅĐģи Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐŧĐžŅ‡ŅŒ ĐŧĐŊĐĩ ҁ ŅŅ‚Đ¸Đŧ, **Đ’Ņ‹ ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ‚Đĩ ĐŋОддĐĩŅ€ĐļĐ¸Đ˛Đ°Ņ‚ŅŒ FastAPI** и Đ´ĐĩĐģаĐĩŅ‚Đĩ Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊ ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐģ **Ņ€Đ°ĐˇĐ˛Đ¸Đ˛Đ°Ņ‚ŅŒŅŅ ĐąŅ‹ŅŅ‚Ņ€ĐĩĐĩ и ĐģŅƒŅ‡ŅˆĐĩ**. 🚀 -## ПодĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ Đē Ņ‡Đ°Ņ‚Ņƒ +## ПодĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒŅŅ Đē Ņ‡Đ°Ņ‚Ņƒ { #join-the-chat } -ПодĐēĐģŅŽŅ‡Đ°ĐšŅ‚ĐĩҁҌ Đē đŸ‘Ĩ Ņ‡Đ°Ņ‚Ņƒ в Discord đŸ‘Ĩ и ĐžĐąŅ‰Đ°ĐšŅ‚ĐĩҁҌ ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи ŅƒŅ‡Đ°ŅŅ‚ĐŊиĐēаĐŧи ŅĐžĐžĐąŅ‰ĐĩŅŅ‚Đ˛Đ° FastAPI. +ПодĐēĐģŅŽŅ‡Đ°ĐšŅ‚ĐĩҁҌ Đē đŸ‘Ĩ ҁĐĩŅ€Đ˛ĐĩŅ€Ņƒ Ņ‡Đ°Ņ‚Đ° в Discord đŸ‘Ĩ и ĐžĐąŅ‰Đ°ĐšŅ‚ĐĩҁҌ ҁ Đ´Ņ€ŅƒĐŗĐ¸Đŧи ŅƒŅ‡Đ°ŅŅ‚ĐŊиĐēаĐŧи ŅĐžĐžĐąŅ‰ĐĩŅŅ‚Đ˛Đ° FastAPI. /// tip | ĐŸĐžĐ´ŅĐēаСĐēа -ВоĐŋŅ€ĐžŅŅ‹ ĐŋĐž ĐŋŅ€ĐžĐąĐģĐĩĐŧаĐŧ ҁ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēĐžĐŧ ĐģŅƒŅ‡ŅˆĐĩ ĐˇĐ°Đ´Đ°Đ˛Đ°Ņ‚ŅŒ в GitHub issues, Ņ‚Đ°Đē йОĐģҌ҈Đĩ ŅˆĐ°ĐŊŅĐžĐ˛, Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐŋĐžĐŧĐžŅ‰ŅŒ ĐžŅ‚ [Đ­ĐēҁĐŋĐĩŅ€Ņ‚ĐžĐ˛ FastAPI](fastapi-people.md#_3){.internal-link target=_blank}. +По вОĐŋŅ€ĐžŅĐ°Đŧ — ĐˇĐ°Đ´Đ°Đ˛Đ°ĐšŅ‚Đĩ Đ¸Ņ… в GitHub Discussions, Ņ‚Đ°Đē ĐŗĐžŅ€Đ°ĐˇĐ´Đž Đ˛Ņ‹ŅˆĐĩ ŅˆĐ°ĐŊҁ, Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐŋĐžĐŧĐžŅ‰ŅŒ ĐžŅ‚ [Đ­ĐēҁĐŋĐĩŅ€Ņ‚ĐžĐ˛ FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. -Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ŅŅ‚ĐžŅ‚ Ņ‡Đ°Ņ‚ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ĐąĐĩҁĐĩĐ´ ĐŊа ĐžŅ‚Đ˛ĐģĐĩ҇ґĐŊĐŊŅ‹Đĩ Ņ‚ĐĩĐŧŅ‹. +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ Ņ‡Đ°Ņ‚ Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ ĐŋŅ€ĐžŅ‡Đ¸Ņ… ĐžĐąŅ‰Đ¸Ņ… ĐąĐĩҁĐĩĐ´. /// -### НĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‡Đ°Ņ‚Ņ‹ Đ´ĐģŅ вОĐŋŅ€ĐžŅĐžĐ˛ +### НĐĩ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ Ņ‡Đ°Ņ‚ Đ´ĐģŅ вОĐŋŅ€ĐžŅĐžĐ˛ { #dont-use-the-chat-for-questions } -ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž Ņ‡Đ°Ņ‚Ņ‹ ĐŋОСвОĐģŅŅŽŅ‚ йОĐģҌ҈Đĩ "ŅĐ˛ĐžĐąĐžĐ´ĐŊĐžĐŗĐž ĐžĐąŅ‰ĐĩĐŊĐ¸Ņ", ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‚Đ°Đŧ ĐģĐĩĐŗĐēĐž ĐˇĐ°Đ´Đ°Đ˛Đ°Ņ‚ŅŒ вОĐŋŅ€ĐžŅŅ‹, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐžĐąŅ‰Đ¸Đĩ и ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ‚Ņ€ŅƒĐ´ĐŊĐĩĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Ņ‚ŅŒ, Ņ‚Đ°Đē Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊĐĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐŊ҃ĐļĐŊŅ‹Đĩ ВаĐŧ ĐžŅ‚Đ˛Đĩ҂ҋ. +ИĐŧĐĩĐšŅ‚Đĩ в Đ˛Đ¸Đ´Ņƒ, Ņ‡Ņ‚Đž в Ņ‡Đ°Ņ‚Đ°Ņ…, ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ "ŅĐ˛ĐžĐąĐžĐ´ĐŊĐžĐŧ҃ ĐžĐąŅ‰ĐĩĐŊĐ¸ŅŽ", ĐģĐĩĐŗĐēĐž ĐˇĐ°Đ´Đ°Ņ‚ŅŒ вОĐŋŅ€ĐžŅŅ‹, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐģĐ¸ŅˆĐēĐžĐŧ ĐžĐąŅ‰Đ¸Đĩ и ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁĐģĐžĐļĐŊĐĩĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ¸Ņ‚ŅŒ, ĐŋĐžŅŅ‚ĐžĐŧ҃ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊĐĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ĐžŅ‚Đ˛Đĩ҂ҋ. -В Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ "ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹" ĐŊа GitHub, ĐĩŅŅ‚ŅŒ ŅˆĐ°ĐąĐģĐžĐŊ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋĐžĐŧĐžĐļĐĩŅ‚ ВаĐŧ ĐŊаĐŋĐ¸ŅĐ°Ņ‚ŅŒ вОĐŋŅ€ĐžŅ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ВаĐŧ ĐąŅ‹ĐģĐž ĐģĐĩĐŗŅ‡Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ…ĐžŅ€ĐžŅˆĐ¸Đš ĐžŅ‚Đ˛ĐĩŅ‚ иĐģи даĐļĐĩ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž, ĐŋŅ€ĐĩĐļĐ´Đĩ ҇ĐĩĐŧ Đ’Ņ‹ ĐˇĐ°Đ´Đ°Đ´Đ¸Ņ‚Đĩ вОĐŋŅ€ĐžŅ. В GitHub Ņ ĐŧĐžĐŗŅƒ ĐąŅ‹Ņ‚ŅŒ ŅƒĐ˛ĐĩŅ€ĐĩĐŊ, Ņ‡Ņ‚Đž Đ˛ŅĐĩĐŗĐ´Đ° ĐžŅ‚Đ˛ĐĩŅ‡Đ°ŅŽ ĐŊа Đ˛ŅŅ‘, даĐļĐĩ ĐĩҁĐģи ŅŅ‚Đž СаКĐŧĐĩŅ‚ ĐēаĐēĐžĐĩ-Ņ‚Đž Đ˛Ņ€ĐĩĐŧŅ. И Ņ ĐŊĐĩ ĐŧĐžĐŗŅƒ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ Ņ‚Đž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ в Ņ‡Đ°Ņ‚Đ°Ņ…. 😅 +На GitHub ŅˆĐ°ĐąĐģĐžĐŊ ĐŋĐžĐŧĐžĐļĐĩŅ‚ ВаĐŧ ĐŋŅ€Đ°Đ˛Đ¸ĐģҌĐŊĐž ŅŅ„ĐžŅ€Đŧ҃ĐģĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ вОĐŋŅ€ĐžŅ, Ņ‡Ņ‚ĐžĐąŅ‹ ВаĐŧ ĐąŅ‹ĐģĐž ĐģĐĩĐŗŅ‡Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ…ĐžŅ€ĐžŅˆĐ¸Đš ĐžŅ‚Đ˛ĐĩŅ‚ иĐģи даĐļĐĩ Ņ€ĐĩŅˆĐ¸Ņ‚ŅŒ ĐŋŅ€ĐžĐąĐģĐĩĐŧ҃ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž Đĩ҉ґ Đ´Đž Ņ‚ĐžĐŗĐž, ĐēаĐē ҁĐŋŅ€ĐžŅĐ¸Ņ‚Đĩ. И ĐŊа GitHub Ņ ĐŧĐžĐŗŅƒ ҁĐģĐĩĐ´Đ¸Ņ‚ŅŒ Са Ņ‚ĐĩĐŧ, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ŅĐĩĐŗĐ´Đ° ĐžŅ‚Đ˛ĐĩŅ‡Đ°Ņ‚ŅŒ ĐŊа Đ˛ŅŅ‘, даĐļĐĩ ĐĩҁĐģи ŅŅ‚Đž СаĐŊиĐŧаĐĩŅ‚ Đ˛Ņ€ĐĩĐŧŅ. А ҁ Ņ‡Đ°Ņ‚Đ°Đŧи Ņ ĐŊĐĩ ĐŧĐžĐŗŅƒ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ŅŅ‚ĐžĐŗĐž ĐģĐ¸Ņ‡ĐŊĐž. 😅 -ĐšŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž, ĐžĐąŅ‰ĐĩĐŊиĐĩ в Ņ‡Đ°Ņ‚Đ°Ņ… ĐŊĐĩ Ņ‚Đ°Đē ĐģĐĩĐŗĐēĐžĐ´ĐžŅŅ‚ŅƒĐŋĐŊĐž Đ´ĐģŅ ĐŋĐžĐ¸ŅĐēа, ĐēаĐē в GitHub, ĐŋĐžŅ‚ĐžĐŧ҃ вОĐŋŅ€ĐžŅŅ‹ и ĐžŅ‚Đ˛Đĩ҂ҋ ĐŧĐžĐŗŅƒŅ‚ ĐŋĐžŅ‚ĐĩŅ€ŅŅ‚ŅŒŅŅ ҁҀĐĩди Đ´Ņ€ŅƒĐŗĐžĐŗĐž ĐžĐąŅ‰ĐĩĐŊĐ¸Ņ. И Ņ‚ĐžĐģҌĐēĐž ĐŋŅ€ĐžĐąĐģĐĩĐŧŅ‹ Ņ€ĐĩŅˆĐ°ĐĩĐŧŅ‹Đĩ ĐŊа GitHub ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ в ĐŋĐžĐģŅƒŅ‡ĐĩĐŊии Đģҋ҇Đēи [Đ­ĐēҁĐŋĐĩҀ҂ FastAPI](fastapi-people.md#_3){.internal-link target=_blank}, Ņ‚Đ°Đē Ņ‡Ņ‚Đž вĐĩҁҌĐŧа вĐĩŅ€ĐžŅŅ‚ĐŊĐž, Ņ‡Ņ‚Đž Đ’Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ йОĐģҌ҈Đĩ вĐŊиĐŧаĐŊĐ¸Ņ ĐŊа GitHub. +ĐšŅ€ĐžĐŧĐĩ Ņ‚ĐžĐŗĐž, ĐŋĐĩŅ€ĐĩĐŋĐ¸ŅĐēа в Ņ‡Đ°Ņ‚Đ°Ņ… Ņ…ŅƒĐļĐĩ Đ¸Ņ‰ĐĩŅ‚ŅŅ, ҇ĐĩĐŧ ĐŊа GitHub, ĐŋĐžŅŅ‚ĐžĐŧ҃ вОĐŋŅ€ĐžŅŅ‹ и ĐžŅ‚Đ˛Đĩ҂ҋ ĐŧĐžĐŗŅƒŅ‚ Ņ‚ĐĩŅ€ŅŅ‚ŅŒŅŅ ҁҀĐĩди ĐžŅŅ‚Đ°ĐģҌĐŊҋ҅ ŅĐžĐžĐąŅ‰ĐĩĐŊиК. И Ņ‚ĐžĐģҌĐēĐž Ņ‚Đĩ, Ņ‡Ņ‚Đž ĐŊа GitHub, ŅƒŅ‡Đ¸Ņ‚Ņ‹Đ˛Đ°ŅŽŅ‚ŅŅ Đ´ĐģŅ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸Ņ Đģҋ҇Đēи [Đ­ĐēҁĐŋĐĩҀ҂ FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, Ņ‚Đ°Đē Ņ‡Ņ‚Đž вĐĩŅ€ĐžŅŅ‚ĐŊĐĩĐĩ Đ˛ŅĐĩĐŗĐž Đ’Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ йОĐģҌ҈Đĩ вĐŊиĐŧаĐŊĐ¸Ņ иĐŧĐĩĐŊĐŊĐž ĐŊа GitHub. -ĐĄ Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, в Ņ‡Đ°Ņ‚Đ°Ņ… Ņ‚Ņ‹ŅŅŅ‡Đ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš, а СĐŊĐ°Ņ‡Đ¸Ņ‚ ĐĩŅŅ‚ŅŒ йОĐģŅŒŅˆĐ¸Đĩ ŅˆĐ°ĐŊҁҋ в ĐģŅŽĐąĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ ĐŊĐ°ĐšŅ‚Đ¸ Ņ‚Đ°Đŧ ĐēĐžĐŗĐž-Ņ‚Đž, ҁ ĐēĐĩĐŧ ĐŧĐžĐļĐŊĐž ĐŋĐžĐŗĐžĐ˛ĐžŅ€Đ¸Ņ‚ŅŒ. 😄 +ĐĄ Đ´Ņ€ŅƒĐŗĐžĐš ŅŅ‚ĐžŅ€ĐžĐŊŅ‹, в Ņ‡Đ°Ņ‚Đ°Ņ… Ņ‚Ņ‹ŅŅŅ‡Đ¸ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš, Ņ‚Đ°Đē Ņ‡Ņ‚Đž ĐŋĐžŅ‡Ņ‚Đ¸ Đ˛ŅĐĩĐŗĐ´Đ° ĐĩŅŅ‚ŅŒ ŅˆĐ°ĐŊҁ ĐŊĐ°ĐšŅ‚Đ¸ Ņ‚Đ°Đŧ ĐēĐžĐŗĐž-Ņ‚Đž Đ´ĐģŅ Ņ€Đ°ĐˇĐŗĐžĐ˛ĐžŅ€Đ°. 😄 -## ĐĄĐŋĐžĐŊŅĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžŅ€Đ° +## ĐĄĐŋĐžĐŊŅĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžŅ€Đ° { #sponsor-the-author } -Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐŧĐŊĐĩ Ņ„Đ¸ĐŊаĐŊŅĐžĐ˛ŅƒŅŽ ĐŋОддĐĩŅ€ĐļĐē҃ ĐŋĐžŅŅ€ĐĩĐ´ŅŅ‚Đ˛ĐžĐŧ ҁĐŋĐžĐŊŅĐžŅ€ŅŅ‚Đ˛Đ° ҇ĐĩŅ€ĐĩС GitHub. - -ĐĸаĐŧ ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžŅŅ‚Đž Đē҃ĐŋĐ¸Ņ‚ŅŒ ĐŧĐŊĐĩ ĐēĐžŅ„Đĩ â˜•ī¸ в СĐŊаĐē ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€ĐŊĐžŅŅ‚Đ¸. 😄 - -А Đĩ҉ґ Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅŅ‚Đ°Ņ‚ŅŒ ĐĄĐĩŅ€ĐĩĐąŅ€ŅĐŊŅ‹Đŧ иĐģи ЗоĐģĐžŅ‚Ņ‹Đŧ ҁĐŋĐžĐŊŅĐžŅ€ĐžĐŧ Đ´ĐģŅ FastAPI. 🏅🎉 - -## ĐĄĐŋĐžĐŊŅĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, ĐŊа ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… СиĐļĐ´ĐĩŅ‚ŅŅ ĐŧĐžŅ‰ŅŒ FastAPI - -КаĐē Đ’Ņ‹ ĐŧĐžĐŗĐģи СаĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, FastAPI ĐžĐŋĐ¸Ņ€Đ°ĐĩŅ‚ŅŅ ĐŊа ĐŋĐģĐĩŅ‡Đ¸ Ņ‚Đ¸Ņ‚Đ°ĐŊОв: Starlette и Pydantic. - -ИĐŧ Ņ‚ĐžĐļĐĩ ĐŧĐžĐļĐŊĐž ĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒ ҁĐŋĐžĐŊŅĐžŅ€ŅĐēŅƒŅŽ ĐŋОддĐĩŅ€ĐļĐē҃: - -* Samuel Colvin (Pydantic) -* Encode (Starlette, Uvicorn) +Đ•ŅĐģи Đ’Đ°Ņˆ **ĐŋŅ€ĐžĐ´ŅƒĐēŅ‚/ĐēĐžĐŧĐŋаĐŊĐ¸Ņ** ĐˇĐ°Đ˛Đ¸ŅŅŅ‚ ĐžŅ‚ **FastAPI** иĐģи ŅĐ˛ŅĐˇĐ°ĐŊŅ‹ ҁ ĐŊиĐŧ и Đ’Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ´ĐžĐŊĐĩŅŅ‚Đ¸ Đ´Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Đž ҁĐĩĐąĐĩ, Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҁĐŋĐžĐŊŅĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžŅ€Đ° (ĐŧĐĩĐŊŅ) ҇ĐĩŅ€ĐĩС GitHub Sponsors. В ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ ŅƒŅ€ĐžĐ˛ĐŊŅ ĐŋОддĐĩŅ€ĐļĐēи Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ йОĐŊŅƒŅŅ‹, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐąĐĩКдĐļ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. 🎁 --- -БĐģĐ°ĐŗĐžĐ´Đ°Ņ€ŅŅ‚Đ˛ŅƒŅŽ! 🚀 +ĐĄĐŋĐ°ŅĐ¸ĐąĐž! 🚀 diff --git a/docs/ru/docs/history-design-future.md b/docs/ru/docs/history-design-future.md index 96604e3a4..d679af3e3 100644 --- a/docs/ru/docs/history-design-future.md +++ b/docs/ru/docs/history-design-future.md @@ -1,4 +1,4 @@ -# Đ˜ŅŅ‚ĐžŅ€Đ¸Ņ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ и даĐģҌĐŊĐĩĐšŅˆĐĩĐĩ Ņ€Đ°ĐˇĐ˛Đ¸Ņ‚Đ¸Đĩ +# Đ˜ŅŅ‚ĐžŅ€Đ¸Ņ, ĐŋŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ и ĐąŅƒĐ´ŅƒŅ‰ĐĩĐĩ { #history-design-and-future } ОдĐŊаĐļĐ´Ņ‹, ОдиĐŊ иС ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš **FastAPI** СадаĐģ вОĐŋŅ€ĐžŅ: @@ -6,7 +6,7 @@ Đ§Ņ‚Đž Đļ, Đ˛ĐžŅ‚ ĐŊĐĩйОĐģŅŒŅˆĐ°Ņ Ņ‡Đ°ŅŅ‚ŅŒ Đ¸ŅŅ‚ĐžŅ€Đ¸Đ¸ ĐŋŅ€ĐžĐĩĐēŅ‚Đ°. -## АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹ +## АĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛Ņ‹ { #alternatives } В Ņ‚Đĩ҇ĐĩĐŊиĐĩ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐģĐĩŅ‚ Ņ, Đ˛ĐžĐˇĐŗĐģавĐģŅŅ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊŅ‹Đĩ ĐēĐžĐŧаĐŊĐ´Ņ‹ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв, ŅĐžĐˇĐ´Đ°Đ˛Đ°Đģ дОвОĐģҌĐŊĐž ҁĐģĐžĐļĐŊŅ‹Đĩ API Đ´ĐģŅ ĐŧĐ°ŅˆĐ¸ĐŊĐŊĐžĐŗĐž ĐžĐąŅƒŅ‡ĐĩĐŊĐ¸Ņ, Ņ€Đ°ŅĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊҋ҅ ŅĐ¸ŅŅ‚ĐĩĐŧ, Đ°ŅĐ¸ĐŊŅ…Ņ€ĐžĐŊĐŊҋ҅ ĐˇĐ°Đ´Đ°Ņ‡, йаС даĐŊĐŊҋ҅ NoSQL и Ņ‚.Đ´. @@ -24,45 +24,47 @@ Đ¯ Đ˛ŅŅŅ‡ĐĩҁĐēи иСйĐĩĐŗĐ°Đģ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐŊĐžĐ˛ĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа в Ņ‚Đĩ҇ĐĩĐŊиĐĩ ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… ĐģĐĩŅ‚. ĐĄĐŊĐ°Ņ‡Đ°Đģа Ņ ĐŋŅ‹Ņ‚Đ°ĐģŅŅ ŅĐžĐąŅ€Đ°Ņ‚ŅŒ Đ˛ŅĐĩ ĐŊ҃ĐļĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŊŅ‹ĐŊĐĩ ĐĩŅŅ‚ŅŒ в **FastAPI**, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ĐŧĐŊĐžĐļĐĩŅŅ‚Đ˛Đž Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊҋ҅ ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€ĐēОв, ĐŋĐģĐ°ĐŗĐ¸ĐŊОв и иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛. -Но в ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ĐŊĐĩ ĐžŅŅ‚Đ°ĐģĐžŅŅŒ Đ´Ņ€ŅƒĐŗĐžĐŗĐž Đ˛Ņ‹ĐąĐžŅ€Đ°, ĐēŅ€ĐžĐŧĐĩ ĐēаĐē ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐģĐž ĐąŅ‹ Đ˛ŅĐĩ ŅŅ‚Đ¸ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ŅŅ€Đ°ĐˇŅƒ. Đ’ĐˇŅŅ‚ŅŒ ŅĐ°ĐŧŅ‹Đĩ ĐģŅƒŅ‡ŅˆĐ¸Đĩ идĐĩи иС ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ввĐĩĐ´Ņ‘ĐŊĐŊŅ‹Đĩ в Python ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв (ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŊĐĩ ĐąŅ‹ĐģĐž Đ´Đž вĐĩŅ€ŅĐ¸Đ¸ 3.6), ĐžĐąŅŠĐĩдиĐŊĐ¸Ņ‚ŅŒ Đ¸Ņ…. +Но в ĐēаĐēОК-Ņ‚Đž ĐŧĐžĐŧĐĩĐŊŅ‚ ĐŊĐĩ ĐžŅŅ‚Đ°ĐģĐžŅŅŒ Đ´Ņ€ŅƒĐŗĐžĐŗĐž Đ˛Ņ‹ĐąĐžŅ€Đ°, ĐēŅ€ĐžĐŧĐĩ ĐēаĐē ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž, Ņ‡Ņ‚Đž ĐŋŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ĐģŅĐģĐž ĐąŅ‹ Đ˛ŅĐĩ ŅŅ‚Đ¸ вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ ŅŅ€Đ°ĐˇŅƒ. Đ’ĐˇŅŅ‚ŅŒ ŅĐ°ĐŧŅ‹Đĩ ĐģŅƒŅ‡ŅˆĐ¸Đĩ идĐĩи иС ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊŅ‚ĐžĐ˛ и, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ ввĐĩĐ´Ņ‘ĐŊĐŊŅ‹Đĩ в Python аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв (ĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐŊĐĩ ĐąŅ‹ĐģĐž Đ´Đž вĐĩŅ€ŅĐ¸Đ¸ 3.6), ĐžĐąŅŠĐĩдиĐŊĐ¸Ņ‚ŅŒ Đ¸Ņ…. -## Đ˜ŅŅĐģĐĩдОваĐŊĐ¸Ņ +## Đ˜ŅŅĐģĐĩдОваĐŊĐ¸Ņ { #investigation } БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ĐžĐŋŅ‹Ņ‚Ņƒ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Ņ… аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛, ĐŧŅ‹ ҁ ĐēĐžĐģĐģĐĩĐŗĐ°Đŧи Đ¸ĐˇŅƒŅ‡Đ¸Đģи Đ¸Ņ… ĐžŅĐŊОвĐŊŅ‹Đĩ идĐĩи и ҁĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Đģи ŅĐžĐąŅ€Đ°ĐŊĐŊŅ‹Đĩ СĐŊаĐŊĐ¸Ņ ĐŊаиĐģŅƒŅ‡ŅˆĐ¸Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ. -НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅŅ‚Đ°ĐģĐž ŅŅĐŊĐž, Ņ‡Ņ‚Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž ĐąŅ€Đ°Ņ‚ŅŒ Са ĐžŅĐŊĐžĐ˛Ņƒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ ĐŋĐžĐ´ŅĐēаСĐēи Ņ‚Đ¸ĐŋОв Python, а ŅĐ°ĐŧŅ‹Đŧ ĐģŅƒŅ‡ŅˆĐ¸Đŧ ĐŋĐžĐ´Ņ…ĐžĐ´ĐžĐŧ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ҃ĐļĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Ņ… ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐ˛. +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ŅŅ‚Đ°ĐģĐž ŅŅĐŊĐž, Ņ‡Ņ‚Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž ĐąŅ€Đ°Ņ‚ŅŒ Са ĐžŅĐŊĐžĐ˛Ņƒ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đĩ аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸Đ¸ Ņ‚Đ¸ĐŋОв Python. + +ĐĸаĐēĐļĐĩ ĐŊаиĐģŅƒŅ‡ŅˆĐ¸Đŧ ĐŋĐžĐ´Ņ…ĐžĐ´ĐžĐŧ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ ҃ĐļĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ŅƒŅŽŅ‰Đ¸Ņ… ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐžĐ˛. Đ˜Ņ‚Đ°Đē, ĐŋŅ€ĐĩĐļĐ´Đĩ ҇ĐĩĐŧ ĐŋŅ€Đ¸ŅŅ‚ŅƒĐŋĐ¸Ņ‚ŅŒ Đē ĐŊаĐŋĐ¸ŅĐ°ĐŊĐ¸ŅŽ **FastAPI**, Ņ ĐŋĐžŅ‚Ņ€Đ°Ņ‚Đ¸Đģ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ĐŧĐĩŅŅŅ†Đĩв ĐŊа Đ¸ĐˇŅƒŅ‡ĐĩĐŊиĐĩ OpenAPI, JSON Schema, OAuth2, и Ņ‚.Đŋ. Đ´ĐģŅ ĐŋĐžĐŊиĐŧаĐŊĐ¸Ņ Đ¸Ņ… вСаиĐŧĐžŅĐ˛ŅĐˇĐĩĐš, ŅĐžĐ˛ĐŋадĐĩĐŊиК и Ņ€Đ°ĐˇĐģĐ¸Ņ‡Đ¸Đš. -## ДизайĐŊ +## ĐŸŅ€ĐžĐĩĐēŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ { #design } Đ—Đ°Ņ‚ĐĩĐŧ Ņ ĐŋĐžŅ‚Ņ€Đ°Ņ‚Đ¸Đģ ĐŊĐĩĐēĐžŅ‚ĐžŅ€ĐžĐĩ Đ˛Ņ€ĐĩĐŧŅ ĐŊа ĐŋŅ€Đ¸Đ´ŅƒĐŧŅ‹Đ˛Đ°ĐŊиĐĩ "API" Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēа, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ Ņ…ĐžŅ‚ĐĩĐģ иĐŧĐĩŅ‚ŅŒ ĐēаĐē ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ (ĐēаĐē Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰Đ¸Đš FastAPI). -Đ¯ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Đģ ĐŊĐĩҁĐēĐžĐģҌĐēĐž идĐĩĐš ĐŊа ŅĐ°Đŧҋ҅ ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊҋ҅ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Ņ… ĐēОда ҁҀĐĩди Python-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв: PyCharm, VS Code, Jedi. +Đ¯ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Đģ ĐŊĐĩҁĐēĐžĐģҌĐēĐž идĐĩĐš ĐŊа ŅĐ°Đŧҋ҅ ĐŋĐžĐŋ҃ĐģŅŅ€ĐŊҋ҅ Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Ņ… ĐēОда: PyCharm, VS Code, Ņ€ĐĩдаĐēŅ‚ĐžŅ€Ņ‹ ĐŊа йаСĐĩ Jedi. -ДаĐŊĐŊŅ‹Đĩ ĐŋĐž Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Đŧ Ņ Đ˛ĐˇŅĐģ иС ĐžĐŋŅ€ĐžŅĐ° Python-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžŅ…Đ˛Đ°Ņ‚Ņ‹Đ˛Đ°Đ°ĐĩŅ‚ ĐžĐēĐžĐģĐž 80% ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš. +ДаĐŊĐŊŅ‹Đĩ ĐŋĐž Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Đŧ Ņ Đ˛ĐˇŅĐģ иС ĐžĐŋŅ€ĐžŅĐ° Python-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐžŅ…Đ˛Đ°Ņ‚Ņ‹Đ˛Đ°ĐĩŅ‚ ĐžĐēĐžĐģĐž 80% ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģĐĩĐš. Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž **FastAPI** ĐąŅ‹Đģ ҁĐŋĐĩŅ†Đ¸Đ°ĐģҌĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€ĐĩĐŊ ĐŊа Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Ņ…, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧҋ҅ 80% Python-Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēаĐŧи. И ĐŋĐžŅĐēĐžĐģҌĐē҃ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž Đ´Ņ€ŅƒĐŗĐ¸Ņ… Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛, ĐēаĐē ĐŋŅ€Đ°Đ˛Đ¸ĐģĐž, Ņ€Đ°ĐąĐžŅ‚Đ°ŅŽŅ‚ аĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊŅ‹Đŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Đ˛ŅĐĩ ĐĩĐŗĐž ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ° Đ´ĐžĐģĐļĐŊŅ‹ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐŋŅ€Đ°ĐēŅ‚Đ¸Ņ‡ĐĩҁĐēи Đ´ĐģŅ Đ˛ŅĐĩŅ… Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛. -ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Ņ ҁĐŧĐžĐŗ ĐŊĐ°ĐšŅ‚Đ¸ ĐŊаиĐģŅƒŅ‡ŅˆĐ¸Đĩ ҁĐŋĐžŅĐžĐąŅ‹ ŅĐžĐēŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒ Đ´ŅƒĐąĐģĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐēОда, ОйĐĩҁĐŋĐĩŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐ˛ŅĐĩĐŧĐĩҁ҂ĐŊĐžĐĩ Đ°Đ˛Ņ‚ĐžĐ´ĐžĐŋĐžĐģĐŊĐĩĐŊиĐĩ, ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ Ņ‚Đ¸ĐŋОв и ĐžŅˆĐ¸ĐąĐžĐē и Ņ‚.Đ´. +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, Ņ ҁĐŧĐžĐŗ ĐŊĐ°ĐšŅ‚Đ¸ ĐŊаиĐģŅƒŅ‡ŅˆĐ¸Đĩ ҁĐŋĐžŅĐžĐąŅ‹ ŅĐžĐēŅ€Đ°Ņ‚Đ¸Ņ‚ŅŒ Đ´ŅƒĐąĐģĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐēОда, ОйĐĩҁĐŋĐĩŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐ˛ŅĐĩĐŧĐĩҁ҂ĐŊĐžĐĩ Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ, ĐŋŅ€ĐžĐ˛ĐĩŅ€Đē҃ Ņ‚Đ¸ĐŋОв и ĐžŅˆĐ¸ĐąĐžĐē и Ņ‚.Đ´. И Đ˛ŅĐĩ ŅŅ‚Đž, Ņ‡Ņ‚ĐžĐąŅ‹ Đ˛ŅĐĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģи ĐŧĐžĐŗĐģи ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ŅŒ ĐŊаиĐģŅƒŅ‡ŅˆĐ¸Đš ĐžĐŋҋ҂ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēи. -## Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ +## Đ—Đ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ { #requirements } ĐŸŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°Đ˛ ĐŊĐĩҁĐēĐžĐģҌĐēĐž Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ĐžĐ˛, Ņ Ņ€ĐĩŅˆĐ¸Đģ, Ņ‡Ņ‚Đž в ĐēĐ°Ņ‡ĐĩŅŅ‚Đ˛Đĩ ĐžŅĐŊĐžĐ˛Ņ‹ ĐąŅƒĐ´Ņƒ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ **Pydantic** и ĐĩĐŗĐž ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ°. -По ĐŧОиĐŧ ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧ ĐąŅ‹Đģ иСĐŧĐĩĐŊŅ‘ĐŊ ĐēОд ŅŅ‚ĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ĐĩĐŗĐž ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧ ҁ JSON Schema, ĐŋОддĐĩŅ€ĐļĐ°Ņ‚ŅŒ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊŅ‹Đĩ ҁĐŋĐžŅĐžĐąŅ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиК и ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚ŅŒ ĐŋĐžĐŧĐžŅ‰ŅŒ Ņ€ĐĩдаĐēŅ‚ĐžŅ€ĐžĐ˛ (ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Ņ‚Đ¸ĐŋОв, Đ°Đ˛Ņ‚ĐžĐˇĐ°ĐŋĐžĐģĐŊĐĩĐŊиĐĩ). +По ĐŧОиĐŧ ĐŋŅ€ĐĩĐ´ĐģĐžĐļĐĩĐŊĐ¸ŅĐŧ ĐąŅ‹Đģ иСĐŧĐĩĐŊŅ‘ĐŊ ĐēОд ŅŅ‚ĐžĐŗĐž ҄ҀĐĩĐšĐŧĐ˛ĐžŅ€Đēа, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ ĐĩĐŗĐž ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đŧ ҁ JSON Schema, ĐŋОддĐĩŅ€ĐļĐ°Ņ‚ŅŒ Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊŅ‹Đĩ ҁĐŋĐžŅĐžĐąŅ‹ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊĐ¸Ņ ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊиК и ҃ĐģŅƒŅ‡ŅˆĐ¸Ņ‚ŅŒ ĐŋОддĐĩŅ€ĐļĐē҃ в Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Ņ… ĐēОда (ĐŋŅ€ĐžĐ˛ĐĩŅ€Đēи Ņ‚Đ¸ĐŋОв, Đ°Đ˛Ņ‚ĐžĐˇĐ°Đ˛ĐĩŅ€ŅˆĐĩĐŊиĐĩ) ĐŊа ĐžŅĐŊОвĐĩ Ņ‚ĐĩŅŅ‚ĐžĐ˛ в ĐŊĐĩҁĐēĐžĐģҌĐēĐ¸Ņ… Ņ€ĐĩдаĐēŅ‚ĐžŅ€Đ°Ņ…. В Ņ‚Đž ĐļĐĩ Đ˛Ņ€ĐĩĐŧŅ, Ņ ĐŋŅ€Đ¸ĐŊиĐŧаĐģ ŅƒŅ‡Đ°ŅŅ‚Đ¸Đĩ в Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚ĐēĐĩ **Starlette**, Đĩ҉ґ ОдиĐŊ иС ĐžŅĐŊОвĐŊҋ҅ ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛ FastAPI. -## Đ Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа +## Đ Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Đēа { #development } К Ņ‚ĐžĐŧ҃ Đ˛Ņ€ĐĩĐŧĐĩĐŊи, ĐēĐžĐŗĐ´Đ° Ņ ĐŊĐ°Ņ‡Đ°Đģ ŅĐžĐˇĐ´Đ°Đ˛Đ°Ņ‚ŅŒ **FastAPI**, йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸Đŧҋ҅ Đ´ĐĩŅ‚Đ°ĐģĐĩĐš ҃ĐļĐĩ ŅŅƒŅ‰ĐĩŅŅ‚Đ˛ĐžĐ˛Đ°ĐģĐž, диСаКĐŊ ĐąŅ‹Đģ ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊ, ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ и ĐŋŅ€ĐžŅ‡Đ¸Đĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ ĐąŅ‹Đģи ĐŗĐžŅ‚ĐžĐ˛Ņ‹, а СĐŊаĐŊĐ¸Ņ Đž ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đ°Ņ… и ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ŅŅ… ĐąŅ‹Đģи ҇ĐĩŅ‚ĐēиĐŧи и ŅĐ˛ĐĩĐļиĐŧи. -## Đ‘ŅƒĐ´ŅƒŅ‰ĐĩĐĩ +## Đ‘ŅƒĐ´ŅƒŅ‰ĐĩĐĩ { #future } ĐĄĐĩĐšŅ‡Đ°Ņ ҃ĐļĐĩ ŅŅĐŊĐž, Ņ‡Ņ‚Đž **FastAPI** ŅĐž ŅĐ˛ĐžĐ¸Đŧи идĐĩŅĐŧи ŅŅ‚Đ°Đģ ĐŋĐžĐģĐĩСĐĩĐŊ ĐŧĐŊĐžĐŗĐ¸Đŧ ĐģŅŽĐ´ŅĐŧ. diff --git a/docs/ru/docs/how-to/conditional-openapi.md b/docs/ru/docs/how-to/conditional-openapi.md new file mode 100644 index 000000000..dc987ae26 --- /dev/null +++ b/docs/ru/docs/how-to/conditional-openapi.md @@ -0,0 +1,56 @@ +# ĐŖŅĐģОвĐŊŅ‹Đš OpenAPI { #conditional-openapi } + +ĐŸŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи и ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅ‹Đĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ, Ņ‡Ņ‚ĐžĐąŅ‹ ҃ҁĐģОвĐŊĐž ĐŊĐ°ŅŅ‚Ņ€Đ°Đ¸Đ˛Đ°Ņ‚ŅŒ OpenAPI в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ и даĐļĐĩ ĐŋĐžĐģĐŊĐžŅŅ‚ŅŒŅŽ ĐĩĐŗĐž ĐžŅ‚ĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ. + +## О ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸, API и Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #about-security-apis-and-docs } + +ĐĄĐēŅ€Ņ‹Ņ‚Đ¸Đĩ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐ˛ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ *ĐŊĐĩ Đ´ĐžĐģĐļĐŊĐž* ĐąŅ‹Ņ‚ŅŒ ҁĐŋĐžŅĐžĐąĐžĐŧ ĐˇĐ°Ņ‰Đ¸Ņ‚Ņ‹ Đ˛Đ°ŅˆĐĩĐŗĐž API. + +Đ­Ņ‚Đž ĐŊĐĩ дОйавĐģŅĐĩŅ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊОК ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ Đ˛Đ°ŅˆĐĩĐŧ҃ API, *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* (ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đēи ĐŋŅƒŅ‚Đ¸) Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ŅƒŅ‚ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹ ĐŋĐž ŅĐ˛ĐžĐ¸Đŧ ĐŋŅƒŅ‚ŅĐŧ. + +Đ•ŅĐģи в Đ˛Đ°ŅˆĐĩĐŧ ĐēОдĐĩ ĐĩŅŅ‚ŅŒ ŅƒŅĐˇĐ˛Đ¸ĐŧĐžŅŅ‚ŅŒ, ĐžĐŊа Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐžŅŅ‚Đ°ĐŊĐĩŅ‚ŅŅ. + +ĐĄĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐģĐ¸ŅˆŅŒ ҃ҁĐģĐžĐļĐŊŅĐĩŅ‚ ĐŋĐžĐŊиĐŧаĐŊиĐĩ Ņ‚ĐžĐŗĐž, ĐēаĐē вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ Đ˛Đ°ŅˆĐ¸Đŧ API, и ĐŧĐžĐļĐĩŅ‚ ҃ҁĐģĐžĐļĐŊĐ¸Ņ‚ŅŒ ĐĩĐŗĐž ĐžŅ‚ĐģадĐē҃ в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ. Đ­Ņ‚Đž ĐŧĐžĐļĐŊĐž ŅŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ ĐŋŅ€ĐžŅŅ‚Đž Ņ€Đ°ĐˇĐŊОвидĐŊĐžŅŅ‚ŅŒŅŽ ĐąĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚Đ¸ ҇ĐĩŅ€ĐĩС ŅĐžĐēŅ€Ņ‹Ņ‚Đ¸Đĩ. + +Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ОйĐĩСОĐŋĐ°ŅĐ¸Ņ‚ŅŒ ŅĐ˛ĐžĐš API, ĐĩŅŅ‚ŅŒ ĐŊĐĩҁĐēĐžĐģҌĐēĐž йОĐģĐĩĐĩ ŅŅ„Ņ„ĐĩĐēŅ‚Đ¸Đ˛ĐŊҋ҅ вĐĩ҉ĐĩĐš, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŧĐžĐļĐŊĐž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +* ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž ҃ Đ˛Đ°Ņ ҇ґ҂ĐēĐž ĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊŅ‹ Pydantic-ĐŧОдĐĩĐģи Đ´ĐģŅ Ņ‚ĐĩĐģ СаĐŋŅ€ĐžŅĐžĐ˛ и ĐžŅ‚Đ˛ĐĩŅ‚ĐžĐ˛. +* ĐĐ°ŅŅ‚Ņ€ĐžĐšŅ‚Đĩ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Ņ€Đ°ĐˇŅ€Đĩ҈ĐĩĐŊĐ¸Ņ и Ņ€ĐžĐģи ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚ĐĩĐš. +* НиĐēĐžĐŗĐ´Đ° ĐŊĐĩ Ņ…Ņ€Đ°ĐŊĐ¸Ņ‚Đĩ ĐŋĐ°Ņ€ĐžĐģи в ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ĐžĐŧ видĐĩ, Ņ‚ĐžĐģҌĐēĐž Ņ…ŅŅˆĐ¸ ĐŋĐ°Ņ€ĐžĐģĐĩĐš. +* Đ ĐĩаĐģĐ¸ĐˇŅƒĐšŅ‚Đĩ и Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ иСвĐĩҁ҂ĐŊŅ‹Đĩ ĐēŅ€Đ¸ĐŋŅ‚ĐžĐŗŅ€Đ°Ņ„Đ¸Ņ‡ĐĩҁĐēиĐĩ иĐŊŅŅ‚Ņ€ŅƒĐŧĐĩĐŊ҂ҋ, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ pwdlib и JWT-Ņ‚ĐžĐēĐĩĐŊŅ‹, и Ņ‚.Đ´. +* Đ”ĐžĐąĐ°Đ˛ŅŒŅ‚Đĩ йОĐģĐĩĐĩ Ņ‚ĐžĐŊĐēĐžĐĩ ҃ĐŋŅ€Đ°Đ˛ĐģĐĩĐŊиĐĩ Đ´ĐžŅŅ‚ŅƒĐŋĐžĐŧ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ OAuth2 scopes (ОйĐģĐ°ŅŅ‚ĐĩĐš) Ņ‚Đ°Đŧ, ĐŗĐ´Đĩ ŅŅ‚Đž ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐž. +* ...и Ņ‚.Đŋ. + +ĐĸĐĩĐŧ ĐŊĐĩ ĐŧĐĩĐŊĐĩĐĩ, ҃ Đ˛Đ°Ņ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐžŅ‡ĐĩĐŊҌ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐŊŅ‹Đš ҁĐģŅƒŅ‡Đ°Đš Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ, ĐēĐžĐŗĐ´Đ° Đ´ĐĩĐšŅŅ‚Đ˛Đ¸Ņ‚ĐĩĐģҌĐŊĐž ĐŊ҃ĐļĐŊĐž ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API Đ´ĐģŅ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ĐžĐēŅ€ŅƒĐļĐĩĐŊиК (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, в ĐŋŅ€ĐžĐ´Đ°Đē҈ĐŊ) иĐģи в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē иС ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ. + +## ĐŖŅĐģОвĐŊŅ‹Đš OpenAPI иС ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē и ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊҋ҅ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ { #conditional-openapi-from-settings-and-env-vars } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐģĐĩĐŗĐēĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Đĩ ĐļĐĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи Pydantic, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš OpenAPI и иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅ‹ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *} + +ЗдĐĩҁҌ ĐŧŅ‹ ĐžĐąŅŠŅĐ˛ĐģŅĐĩĐŧ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐē҃ `openapi_url` ҁ Ņ‚ĐĩĐŧ ĐļĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩĐŧ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ — `"/openapi.json"`. + +Đ—Đ°Ņ‚ĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ĐĩŅ‘ ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ FastAPI. + +ДаĐģĐĩĐĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ OpenAPI (вĐēĐģŅŽŅ‡Đ°Ņ иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅŅ‹ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸), ŅƒŅŅ‚Đ°ĐŊОвив ĐŋĐĩŅ€ĐĩĐŧĐĩĐŊĐŊŅƒŅŽ ĐžĐēŅ€ŅƒĐļĐĩĐŊĐ¸Ņ `OPENAPI_URL` в ĐŋŅƒŅŅ‚ŅƒŅŽ ŅŅ‚Ņ€ĐžĐē҃, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +
+ +```console +$ OPENAPI_URL= uvicorn main:app + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž, ĐĩҁĐģи ĐŋĐĩŅ€ĐĩĐšŅ‚Đ¸ ĐŋĐž Đ°Đ´Ņ€ĐĩŅĐ°Đŧ `/openapi.json`, `/docs` иĐģи `/redoc`, Đ˛Ņ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚Đĩ ĐžŅˆĐ¸ĐąĐē҃ `404 Not Found`, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€: + +```JSON +{ + "detail": "Not Found" +} +``` diff --git a/docs/ru/docs/how-to/configure-swagger-ui.md b/docs/ru/docs/how-to/configure-swagger-ui.md new file mode 100644 index 000000000..4793cc9db --- /dev/null +++ b/docs/ru/docs/how-to/configure-swagger-ui.md @@ -0,0 +1,70 @@ +# ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēа Swagger UI { #configure-swagger-ui } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ Swagger UI. + +Đ§Ņ‚ĐžĐąŅ‹ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ Đ¸Ņ…, ĐŋĐĩŅ€ĐĩĐ´Đ°ĐšŅ‚Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚ `swagger_ui_parameters` ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии ĐžĐąŅŠĐĩĐēŅ‚Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `FastAPI()` иĐģи в Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ `get_swagger_ui_html()`. + +`swagger_ui_parameters` ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ҁĐģĐžĐ˛Đ°Ņ€ŅŒ ҁ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēаĐŧи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐĩŅ€ĐĩĐ´Đ°ŅŽŅ‚ŅŅ в Swagger UI ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ. + +FastAPI ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒĐĩŅ‚ ŅŅ‚Đ¸ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи в **JSON**, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžĐŊи ĐąŅ‹Đģи ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹ ҁ JavaScript, ĐŋĐžŅĐēĐžĐģҌĐē҃ иĐŧĐĩĐŊĐŊĐž ŅŅ‚Đž ҂ҀĐĩĐąŅƒĐĩŅ‚ŅŅ Swagger UI. + +## ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐ´ŅĐ˛ĐĩŅ‚Đē҃ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° { #disable-syntax-highlighting } + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐ´ŅĐ˛ĐĩŅ‚Đē҃ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° в Swagger UI. + +БĐĩС иСĐŧĐĩĐŊĐĩĐŊĐ¸Ņ ĐŊĐ°ŅŅ‚Ņ€ĐžĐĩĐē ĐŋĐžĐ´ŅĐ˛ĐĩŅ‚Đēа ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° вĐēĐģŅŽŅ‡ĐĩĐŊа ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ: + + + +Но Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐĩŅ‘, ŅƒŅŅ‚Đ°ĐŊОвив `syntaxHighlight` в `False`: + +{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *} + +â€Ļи ĐŋĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž Swagger UI йОĐģҌ҈Đĩ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°Ņ‚ŅŒ ĐŋĐžĐ´ŅĐ˛ĐĩŅ‚Đē҃ ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ°: + + + +## ИСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ Ņ‚ĐĩĐŧ҃ { #change-the-theme } + +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ Ņ‚ĐĩĐŧ҃ ĐŋĐžĐ´ŅĐ˛ĐĩŅ‚Đēи ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ° ҁ ĐēĐģŅŽŅ‡ĐžĐŧ "syntaxHighlight.theme" (ĐžĐąŅ€Đ°Ņ‚Đ¸Ņ‚Đĩ вĐŊиĐŧаĐŊиĐĩ, Ņ‡Ņ‚Đž ĐŋĐžŅĐĩŅ€ĐĩдиĐŊĐĩ ŅŅ‚ĐžĐ¸Ņ‚ Ņ‚ĐžŅ‡Đēа): + +{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *} + +Đ­Ņ‚Đ° ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēа иСĐŧĐĩĐŊĐ¸Ņ‚ Ņ†Đ˛ĐĩŅ‚ĐžĐ˛ŅƒŅŽ Ņ‚ĐĩĐŧ҃ ĐŋĐžĐ´ŅĐ˛ĐĩŅ‚Đēи ŅĐ¸ĐŊŅ‚Đ°ĐēŅĐ¸ŅĐ°: + + + +## ИСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ Swagger UI ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ { #change-default-swagger-ui-parameters } + +FastAPI вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ ĐēĐžĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐŋĐžĐ´Ņ…ĐžĐ´ŅŅ‰Đ¸Đĩ Đ´ĐģŅ йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đ° ҁĐģŅƒŅ‡Đ°Đĩв. + +Đ­Ņ‚Đž вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ: + +{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *} + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģŅŽĐąŅƒŅŽ иС ĐŊĐ¸Ņ…, ҃ĐēаСав Đ´Ņ€ŅƒĐŗĐžĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ в Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊŅ‚Đĩ `swagger_ui_parameters`. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ `deepLinking`, ĐŧĐžĐļĐŊĐž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ Ņ‚Đ°ĐēиĐĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи в `swagger_ui_parameters`: + +{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *} + +## Đ”Ņ€ŅƒĐŗĐ¸Đĩ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ Swagger UI { #other-swagger-ui-parameters } + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ Đ˛ŅĐĩ ĐžŅŅ‚Đ°ĐģҌĐŊŅ‹Đĩ вОСĐŧĐžĐļĐŊŅ‹Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŋĐž ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ°Đŧ Swagger UI. + +## ĐĐ°ŅŅ‚Ņ€ĐžĐšĐēи Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ JavaScript { #javascript-only-settings } + +Swagger UI Ņ‚Đ°ĐēĐļĐĩ Đ´ĐžĐŋ҃ҁĐēаĐĩŅ‚ Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи, ĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ŅĐ˛ĐģŅŅŽŅ‚ŅŅ **Ņ‡Đ¸ŅŅ‚Đž JavaScript-ĐžĐąŅŠĐĩĐēŅ‚Đ°Đŧи** (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, JavaScript-Ņ„ŅƒĐŊĐēŅ†Đ¸ŅĐŧи). + +FastAPI Ņ‚Đ°ĐēĐļĐĩ вĐēĐģŅŽŅ‡Đ°ĐĩŅ‚ ҁĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Đĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи `presets` (Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ JavaScript): + +```JavaScript +presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIBundle.SwaggerUIStandalonePreset +] +``` + +Đ­Ņ‚Đž ĐžĐąŅŠĐĩĐē҂ҋ **JavaScript**, а ĐŊĐĩ ŅŅ‚Ņ€ĐžĐēи, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ Đ¸Ņ… иС Python-ĐēОда ĐŊĐĩĐģŅŒĐˇŅ. + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊŅ‹ Ņ‚Đ°ĐēиĐĩ ĐŊĐ°ŅŅ‚Ņ€ĐžĐšĐēи Ņ‚ĐžĐģҌĐēĐž Đ´ĐģŅ JavaScript, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ ОдиĐŊ иС ĐŧĐĩŅ‚ĐžĐ´ĐžĐ˛ Đ˛Ņ‹ŅˆĐĩ. ПĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* Swagger UI и Đ˛Ņ€ŅƒŅ‡ĐŊŅƒŅŽ ĐŊаĐŋĐ¸ŅˆĐ¸Ņ‚Đĩ ĐģŅŽĐąĐžĐš ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đš JavaScript. diff --git a/docs/ru/docs/how-to/custom-docs-ui-assets.md b/docs/ru/docs/how-to/custom-docs-ui-assets.md new file mode 100644 index 000000000..c07a9695b --- /dev/null +++ b/docs/ru/docs/how-to/custom-docs-ui-assets.md @@ -0,0 +1,185 @@ +# ХвОи ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ€ĐĩŅŅƒŅ€ŅŅ‹ UI Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ (ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊŅ‹Đš Ņ…ĐžŅŅ‚Đ¸ĐŊĐŗ) { #custom-docs-ui-static-assets-self-hosting } + +ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ API Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ **Swagger UI** и **ReDoc**, и Đ´ĐģŅ ĐēаĐļĐ´ĐžĐŗĐž иС ĐŊĐ¸Ņ… ĐŊ҃ĐļĐŊŅ‹ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ Ņ„Đ°ĐšĐģŅ‹ JavaScript и CSS. + +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ŅŅ‚Đ¸ Ņ„Đ°ĐšĐģŅ‹ ĐžŅ‚Đ´Đ°ŅŽŅ‚ŅŅ ҁ CDN. + +Но ŅŅ‚Đž ĐŧĐžĐļĐŊĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ: Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ҃ĐēĐ°ĐˇĐ°Ņ‚ŅŒ ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊŅ‹Đš CDN иĐģи ĐžŅ‚Đ´Đ°Đ˛Đ°Ņ‚ŅŒ Ņ„Đ°ĐšĐģŅ‹ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž. + +## ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК CDN Đ´ĐģŅ JavaScript и CSS { #custom-cdn-for-javascript-and-css } + +ДоĐŋŅƒŅŅ‚Đ¸Đŧ, Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ´Ņ€ŅƒĐŗĐžĐš CDN, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `https://unpkg.com/`. + +Đ­Ņ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐŊĐž, ĐĩҁĐģи, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ˛Ņ‹ ĐļĐ¸Đ˛Ņ‘Ņ‚Đĩ в ŅŅ‚Ņ€Đ°ĐŊĐĩ, ĐŗĐ´Đĩ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ URL ĐžĐŗŅ€Đ°ĐŊĐ¸Ņ‡ĐĩĐŊŅ‹. + +### ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ { #disable-the-automatic-docs } + +ПĐĩŅ€Đ˛Ņ‹Đš ŅˆĐ°Đŗ — ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ, Ņ‚Đ°Đē ĐēаĐē ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐžĐŊа Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚ĐŊŅ‹Đš CDN. + +Đ§Ņ‚ĐžĐąŅ‹ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐĩŅ‘, ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ Đ¸Ņ… URL в СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ `None` ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `FastAPI`: + +{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *} + +### ПодĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ { #include-the-custom-docs } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ FastAPI Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ HTML-ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ† Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ иĐŧ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ: + +* `openapi_url`: URL, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ HTML-ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đ° Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž API. ЗдĐĩҁҌ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `app.openapi_url`. +* `title`: ĐˇĐ°ĐŗĐžĐģОвОĐē Đ˛Đ°ŅˆĐĩĐŗĐž API. +* `oauth2_redirect_url`: СдĐĩҁҌ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `app.swagger_ui_oauth2_redirect_url`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. +* `swagger_js_url`: URL, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ HTML Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Swagger UI ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ„Đ°ĐšĐģ **JavaScript**. Đ­Ņ‚Đž URL Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž CDN. +* `swagger_css_url`: URL, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ HTML Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Swagger UI ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ„Đ°ĐšĐģ **CSS**. Đ­Ņ‚Đž URL Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž CDN. + +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž и Đ´ĐģŅ ReDoc... + +{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *} + +/// tip | ХОвĐĩŅ‚ + +*ОĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ `swagger_ui_redirect` — ŅŅ‚Đž Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ŅĐŊĐ´ĐŋОиĐŊŅ‚ ĐŊа ҁĐģŅƒŅ‡Đ°Đš, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ OAuth2. + +Đ•ŅĐģи Đ˛Ņ‹ иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ŅƒĐĩŅ‚Đĩ ŅĐ˛ĐžĐš API ҁ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ĐžĐŧ OAuth2, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ и вĐĩŅ€ĐŊŅƒŅ‚ŅŒŅŅ Đē Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API ҁ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đŧи ŅƒŅ‡Ņ‘Ņ‚ĐŊŅ‹Đŧи даĐŊĐŊŅ‹Đŧи, а ĐˇĐ°Ņ‚ĐĩĐŧ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ ĐŊиĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ€ĐĩаĐģҌĐŊŅƒŅŽ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ŅŽ OAuth2. + +Swagger UI ŅĐ´ĐĩĐģаĐĩŅ‚ ŅŅ‚Đž Са Đ˛Đ°Ņ ÂĢСа Đē҃ĐģĐ¸ŅĐ°ĐŧиÂģ, ĐŊĐž Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐĩĐŧ҃ ĐŊ҃ĐļĐĩĐŊ ŅŅ‚ĐžŅ‚ Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ÂĢredirectÂģ ŅĐŊĐ´ĐŋОиĐŊŅ‚. + +/// + +### ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸*, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐžĐ˛ĐĩŅ€Đ¸Ņ‚ŅŒ { #create-a-path-operation-to-test-it } + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž Đ˛ŅŅ‘ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚, ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸*: + +{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *} + +### ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ { #test-it } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ Đ´ĐžĐģĐļĐŊŅ‹ иĐŧĐĩŅ‚ŅŒ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ŅŒ ŅĐ˛ĐžŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:8000/docs и ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŒ ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņƒ — ÂĢĐ°ŅŅĐĩ҂ҋÂģ (ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹) ĐąŅƒĐ´ŅƒŅ‚ ĐˇĐ°ĐŗŅ€ŅƒĐļĐ°Ņ‚ŅŒŅŅ ҁ ĐŊĐžĐ˛ĐžĐŗĐž CDN. + +## ХаĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊŅ‹Đš Ņ…ĐžŅŅ‚Đ¸ĐŊĐŗ JavaScript и CSS Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #self-hosting-javascript-and-css-for-docs } + +ХаĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊŅ‹Đš Ņ…ĐžŅŅ‚Đ¸ĐŊĐŗ JavaScript и CSS ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ ĐŋĐžĐģĐĩСĐĩĐŊ, ĐĩҁĐģи, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, ваĐŧ ĐŊ҃ĐļĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ĐŋŅ€ĐžĐ´ĐžĐģĐļаĐģĐž Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ в ĐžŅ„ĐģаКĐŊĐĩ, ĐąĐĩС Đ´ĐžŅŅ‚ŅƒĐŋа Đē ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ĐžĐŧ҃ ИĐŊŅ‚ĐĩŅ€ĐŊĐĩŅ‚Ņƒ, иĐģи в ĐģĐžĐēаĐģҌĐŊОК ҁĐĩŅ‚Đ¸. + +ЗдĐĩҁҌ Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ, ĐēаĐē ĐžŅ‚Đ´Đ°Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ¸ Ņ„Đ°ĐšĐģŅ‹ ŅĐ°ĐŧĐžŅŅ‚ĐžŅŅ‚ĐĩĐģҌĐŊĐž, в Ņ‚ĐžĐŧ ĐļĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии FastAPI, и ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŊа Đ¸Ņ… Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊиĐĩ. + +### ĐĄŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Ņ„Đ°ĐšĐģОв ĐŋŅ€ĐžĐĩĐēŅ‚Đ° { #project-file-structure } + +ДоĐŋŅƒŅŅ‚Đ¸Đŧ, ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Ņ„Đ°ĐšĐģОв Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€ĐžĐĩĐēŅ‚Đ° Đ˛Ņ‹ĐŗĐģŅĐ´Đ¸Ņ‚ Ņ‚Đ°Đē: + +``` +. +├── app +│ ├── __init__.py +│ ├── main.py +``` + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ Đ´ĐģŅ Ņ…Ņ€Đ°ĐŊĐĩĐŊĐ¸Ņ ŅŅ‚Đ¸Ņ… ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… Ņ„Đ°ĐšĐģОв. + +ĐĐžĐ˛Đ°Ņ ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Ņ„Đ°ĐšĐģОв ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +└── static/ +``` + +### ĐĄĐēĐ°Ņ‡Đ°ĐšŅ‚Đĩ Ņ„Đ°ĐšĐģŅ‹ { #download-the-files } + +ĐĄĐēĐ°Ņ‡Đ°ĐšŅ‚Đĩ ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹, ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, и ĐŋĐžĐŧĐĩŅŅ‚Đ¸Ņ‚Đĩ Đ¸Ņ… в Đ´Đ¸Ņ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ `static/`. + +ĐĄĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐģиĐēĐŊŅƒŅ‚ŅŒ ĐŋŅ€Đ°Đ˛ĐžĐš ĐēĐŊĐžĐŋĐēОК ĐŊа ĐēаĐļдОК ҁҁҋĐģĐēĐĩ и Đ˛Ņ‹ĐąŅ€Đ°Ņ‚ŅŒ Ņ‡Ņ‚Đž-Ņ‚Đž Đ˛Ņ€ĐžĐ´Đĩ ÂĢĐĄĐžŅ…Ņ€Đ°ĐŊĐ¸Ņ‚ŅŒ ҁҁҋĐģĐē҃ ĐēаĐē...Âģ. + +**Swagger UI** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Ņ„Đ°ĐšĐģŅ‹: + +* `swagger-ui-bundle.js` +* `swagger-ui.css` + +А **ReDoc** Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ Ņ„Đ°ĐšĐģ: + +* `redoc.standalone.js` + +ĐŸĐžŅĐģĐĩ ŅŅ‚ĐžĐŗĐž ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ° Ņ„Đ°ĐšĐģОв ĐŧĐžĐļĐĩŅ‚ Đ˛Ņ‹ĐŗĐģŅĐ´ĐĩŅ‚ŅŒ Ņ‚Đ°Đē: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +└── static + ├── redoc.standalone.js + ├── swagger-ui-bundle.js + └── swagger-ui.css +``` + +### ĐŸŅ€ĐĩĐ´ĐžŅŅ‚Đ°Đ˛ŅŒŅ‚Đĩ Đ´ĐžŅŅ‚ŅƒĐŋ Đē ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐŧ Ņ„Đ°ĐšĐģаĐŧ { #serve-the-static-files } + +* ИĐŧĐŋĐžŅ€Ņ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ `StaticFiles`. +* ĐĄĐŧĐžĐŊŅ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ ŅĐēСĐĩĐŧĐŋĐģŅŅ€ `StaticFiles()` в ĐžĐŋŅ€ĐĩĐ´ĐĩĐģŅ‘ĐŊĐŊŅ‹Đš ĐŋŅƒŅ‚ŅŒ. + +{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *} + +### ĐŸŅ€ĐžŅ‚ĐĩŅŅ‚Đ¸Ņ€ŅƒĐšŅ‚Đĩ ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹ { #test-the-static-files } + +ЗаĐŋŅƒŅŅ‚Đ¸Ņ‚Đĩ ŅĐ˛ĐžŅ‘ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ и ĐžŅ‚ĐēŅ€ĐžĐšŅ‚Đĩ http://127.0.0.1:8000/static/redoc.standalone.js. + +Đ’Ņ‹ Đ´ĐžĐģĐļĐŊŅ‹ ŅƒĐ˛Đ¸Đ´ĐĩŅ‚ŅŒ ĐžŅ‡ĐĩĐŊҌ Đ´ĐģиĐŊĐŊŅ‹Đš JavaScript-Ņ„Đ°ĐšĐģ Đ´ĐģŅ **ReDoc**. + +ОĐŊ ĐŧĐžĐļĐĩŅ‚ ĐŊĐ°Ņ‡Đ¸ĐŊĐ°Ņ‚ŅŒŅŅ ĐŋŅ€Đ¸ĐŧĐĩŅ€ĐŊĐž Ņ‚Đ°Đē: + +```JavaScript +/*! For license information please see redoc.standalone.js.LICENSE.txt */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")): +... +``` + +Đ­Ņ‚Đž ĐŋĐžĐ´Ņ‚Đ˛ĐĩŅ€ĐļдаĐĩŅ‚, Ņ‡Ņ‚Đž Đ˛Đ°ŅˆĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ ҃ĐŧĐĩĐĩŅ‚ ĐžŅ‚Đ´Đ°Đ˛Đ°Ņ‚ŅŒ ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹ и Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŋĐžĐŧĐĩŅŅ‚Đ¸Đģи Ņ„Đ°ĐšĐģŅ‹ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ в ĐŊ҃ĐļĐŊĐžĐĩ ĐŧĐĩŅŅ‚Đž. + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŧĐžĐļĐŊĐž ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ Ņ‚Đ°Đē, Ņ‡Ņ‚ĐžĐąŅ‹ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģа ŅŅ‚Đ¸ ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐĩ Ņ„Đ°ĐšĐģŅ‹. + +### ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Đ´ĐģŅ ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… Ņ„Đ°ĐšĐģОв { #disable-the-automatic-docs-for-static-files } + +ĐĸаĐē ĐļĐĩ, ĐēаĐē и ĐŋŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž CDN, ĐŋĐĩŅ€Đ˛Ņ‹Đŧ ŅˆĐ°ĐŗĐžĐŧ ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, Ņ‚Đ°Đē ĐēаĐē ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐžĐŊа Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ CDN. + +Đ§Ņ‚ĐžĐąŅ‹ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐĩŅ‘, ŅƒŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚Đĩ Đ¸Ņ… URL в СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ `None` ĐŋŅ€Đ¸ ŅĐžĐˇĐ´Đ°ĐŊии Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `FastAPI`: + +{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *} + +### ПодĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēŅƒŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ŅĐž ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐŧи Ņ„Đ°ĐšĐģаĐŧи { #include-the-custom-docs-for-static-files } + +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŧ҃ CDN, Ņ‚ĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. + +ĐĄĐŊОва ĐŧĐžĐļĐŊĐž ĐŋĐĩŅ€ĐĩĐ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐĩ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ FastAPI Đ´ĐģŅ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ HTML-ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ† Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ и ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‚ŅŒ иĐŧ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧŅ‹Đĩ Đ°Ņ€ĐŗŅƒĐŧĐĩĐŊ҂ҋ: + +* `openapi_url`: URL, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ HTML-ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Đ° Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž API. ЗдĐĩҁҌ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `app.openapi_url`. +* `title`: ĐˇĐ°ĐŗĐžĐģОвОĐē Đ˛Đ°ŅˆĐĩĐŗĐž API. +* `oauth2_redirect_url`: СдĐĩҁҌ ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `app.swagger_ui_oauth2_redirect_url`, Ņ‡Ņ‚ĐžĐąŅ‹ ĐžŅŅ‚Đ°Đ˛Đ¸Ņ‚ŅŒ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ. +* `swagger_js_url`: URL, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ HTML Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Swagger UI ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ„Đ°ĐšĐģ **JavaScript**. **Đ­Ņ‚Đž Ņ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐžŅ‚Đ´Đ°Ņ‘Ņ‚ Đ˛Đ°ŅˆĐĩ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ**. +* `swagger_css_url`: URL, ĐŋĐž ĐēĐžŅ‚ĐžŅ€ĐžĐŧ҃ HTML Đ´ĐģŅ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Swagger UI ҁĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Ņ„Đ°ĐšĐģ **CSS**. **Đ­Ņ‚Đž Ņ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚ĐĩĐŋĐĩŅ€ŅŒ ĐžŅ‚Đ´Đ°Ņ‘Ņ‚ Đ˛Đ°ŅˆĐĩ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ**. + +АĐŊаĐģĐžĐŗĐ¸Ņ‡ĐŊĐž и Đ´ĐģŅ ReDoc... + +{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *} + +/// tip | ХОвĐĩŅ‚ + +*ОĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ `swagger_ui_redirect` — ŅŅ‚Đž Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ŅĐŊĐ´ĐŋОиĐŊŅ‚ ĐŊа ҁĐģŅƒŅ‡Đ°Đš, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚Đĩ OAuth2. + +Đ•ŅĐģи Đ˛Ņ‹ иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ŅƒĐĩŅ‚Đĩ ŅĐ˛ĐžĐš API ҁ ĐŋŅ€ĐžĐ˛Đ°ĐšĐ´ĐĩŅ€ĐžĐŧ OAuth2, Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸Ņ†Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒŅŅ и вĐĩŅ€ĐŊŅƒŅ‚ŅŒŅŅ Đē Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ API ҁ ĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐŊŅ‹Đŧи ŅƒŅ‡Ņ‘Ņ‚ĐŊŅ‹Đŧи даĐŊĐŊŅ‹Đŧи, а ĐˇĐ°Ņ‚ĐĩĐŧ вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ ĐŊиĐŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Ņ€ĐĩаĐģҌĐŊŅƒŅŽ Đ°ŅƒŅ‚ĐĩĐŊŅ‚Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸ŅŽ OAuth2. + +Swagger UI ŅĐ´ĐĩĐģаĐĩŅ‚ ŅŅ‚Đž Са Đ˛Đ°Ņ ÂĢСа Đē҃ĐģĐ¸ŅĐ°ĐŧиÂģ, ĐŊĐž Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐĩĐŧ҃ ĐŊ҃ĐļĐĩĐŊ ŅŅ‚ĐžŅ‚ Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đš ÂĢredirectÂģ ŅĐŊĐ´ĐŋОиĐŊŅ‚. + +/// + +### ĐĄĐžĐˇĐ´Đ°ĐšŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* Đ´ĐģŅ Ņ‚ĐĩŅŅ‚Đ° ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐ¸Ņ… Ņ„Đ°ĐšĐģОв { #create-a-path-operation-to-test-static-files } + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž Đ˛ŅŅ‘ Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚, ŅĐžĐˇĐ´Đ°ĐšŅ‚Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸*: + +{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *} + +### ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ UI ŅĐž ŅŅ‚Đ°Ņ‚Đ¸Ņ‡ĐĩҁĐēиĐŧи Ņ„Đ°ĐšĐģаĐŧи { #test-static-files-ui } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ Wi‑Fi, ĐžŅ‚ĐēŅ€Ņ‹Ņ‚ŅŒ ŅĐ˛ĐžŅŽ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ ĐŋĐž Đ°Đ´Ņ€Đĩҁ҃ http://127.0.0.1:8000/docs и ĐŋĐĩŅ€ĐĩĐˇĐ°ĐŗŅ€ŅƒĐˇĐ¸Ņ‚ŅŒ ŅŅ‚Ņ€Đ°ĐŊĐ¸Ņ†Ņƒ. + +ДаĐļĐĩ ĐąĐĩС ИĐŊŅ‚ĐĩŅ€ĐŊĐĩŅ‚Đ° Đ˛Ņ‹ ҁĐŧĐžĐļĐĩŅ‚Đĩ видĐĩŅ‚ŅŒ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Đē ŅĐ˛ĐžĐĩĐŧ҃ API и вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ ĐŊиĐŧ. diff --git a/docs/ru/docs/how-to/custom-request-and-route.md b/docs/ru/docs/how-to/custom-request-and-route.md new file mode 100644 index 000000000..df8a5ee3c --- /dev/null +++ b/docs/ru/docs/how-to/custom-request-and-route.md @@ -0,0 +1,109 @@ +# ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиĐĩ ĐēĐģĐ°ŅŅŅ‹ Request и APIRoute { #custom-request-and-apiroute-class } + +В ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģĐžĐŗĐ¸Đē҃, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅƒŅŽ ĐēĐģĐ°ŅŅĐ°Đŧи `Request` и `APIRoute`. + +В Ņ‡Đ°ŅŅ‚ĐŊĐžŅŅ‚Đ¸, ŅŅ‚Đž ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ Ņ…ĐžŅ€ĐžŅˆĐĩĐš аĐģŅŒŅ‚ĐĩŅ€ĐŊĐ°Ņ‚Đ¸Đ˛ĐžĐš ĐģĐžĐŗĐ¸ĐēĐĩ в middleware. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, ĐĩҁĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ иĐģи иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° Đ´Đž Ņ‚ĐžĐŗĐž, ĐēаĐē ĐžĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°ĐŊĐž Đ˛Đ°ŅˆĐ¸Đŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩĐŧ. + +/// danger | ОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ + +Đ­Ņ‚Đž ÂĢĐŋŅ€ĐžĐ´Đ˛Đ¸ĐŊŅƒŅ‚Đ°ŅÂģ вОСĐŧĐžĐļĐŊĐžŅŅ‚ŅŒ. + +Đ•ŅĐģи Đ˛Ņ‹ Ņ‚ĐžĐģҌĐēĐž ĐŊĐ°Ņ‡Đ¸ĐŊаĐĩŅ‚Đĩ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ **FastAPI**, вОСĐŧĐžĐļĐŊĐž, ŅŅ‚ĐžĐ¸Ņ‚ ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ Ņ€Đ°ĐˇĐ´ĐĩĐģ. + +/// + +## ĐĄŅ†ĐĩĐŊĐ°Ņ€Đ¸Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ { #use-cases } + +НĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đ¸: + +* ĐŸŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊиĐĩ Ņ‚ĐĩĐģ СаĐŋŅ€ĐžŅĐžĐ˛, ĐŊĐĩ в Ņ„ĐžŅ€ĐŧĐ°Ņ‚Đĩ JSON, в JSON (ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€, `msgpack`). +* Đ Đ°ŅĐŋаĐēОвĐēа Ņ‚ĐĩĐģ СаĐŋŅ€ĐžŅĐžĐ˛, ҁĐļĐ°Ņ‚Ņ‹Ņ… ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ gzip. +* ĐĐ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēĐžĐĩ ĐģĐžĐŗĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ Đ˛ŅĐĩŅ… Ņ‚ĐĩĐģ СаĐŋŅ€ĐžŅĐžĐ˛. + +## ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŗĐž ĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ° { #handling-custom-request-body-encodings } + +ĐŸĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ ĐēаĐē Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐŋОдĐēĐģĐ°ŅŅ `Request` Đ´ĐģŅ Ņ€Đ°ŅĐŋаĐēОвĐēи gzip-СаĐŋŅ€ĐžŅĐžĐ˛. + +И ĐŋОдĐēĐģĐ°ŅŅ `APIRoute`, Ņ‡Ņ‚ĐžĐąŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚ĐžŅ‚ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ СаĐŋŅ€ĐžŅĐ°. + +### ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ `GzipRequest` { #create-a-custom-gziprequest-class } + +/// tip | ХОвĐĩŅ‚ + +Đ­Ņ‚Đž ŅƒŅ‡ĐĩĐąĐŊŅ‹Đš ĐŋŅ€Đ¸ĐŧĐĩŅ€, Đ´ĐĩĐŧĐžĐŊŅŅ‚Ņ€Đ¸Ņ€ŅƒŅŽŅ‰Đ¸Đš ĐŋŅ€Đ¸ĐŊŅ†Đ¸Đŋ Ņ€Đ°ĐąĐžŅ‚Ņ‹. Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊа ĐŋОддĐĩŅ€ĐļĐēа Gzip, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŗĐžŅ‚ĐžĐ˛Ņ‹Đš [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank}. + +/// + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ŅĐžĐˇĐ´Đ°Đ´Đ¸Đŧ ĐēĐģĐ°ŅŅ `GzipRequest`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ ĐŧĐĩŅ‚ĐžĐ´ `Request.body()` и Ņ€Đ°ŅĐŋаĐē҃ĐĩŅ‚ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° ĐŋŅ€Đ¸ ĐŊаĐģĐ¸Ņ‡Đ¸Đ¸ ŅĐžĐžŅ‚Đ˛ĐĩŅ‚ŅŅ‚Đ˛ŅƒŅŽŅ‰ĐĩĐŗĐž HTTP-ĐˇĐ°ĐŗĐžĐģОвĐēа. + +Đ•ŅĐģи в ĐˇĐ°ĐŗĐžĐģОвĐēĐĩ ĐŊĐĩŅ‚ `gzip`, ĐžĐŊ ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐŋŅ‹Ņ‚Đ°Ņ‚ŅŒŅŅ Ņ€Đ°ŅĐŋаĐēĐžĐ˛Ņ‹Đ˛Đ°Ņ‚ŅŒ Ņ‚ĐĩĐģĐž. + +ĐĸаĐēиĐŧ ĐžĐąŅ€Đ°ĐˇĐžĐŧ, ОдиĐŊ и Ņ‚ĐžŅ‚ ĐļĐĩ ĐēĐģĐ°ŅŅ ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚Đ° ҁĐŧĐžĐļĐĩŅ‚ ĐžĐąŅ€Đ°ĐąĐ°Ņ‚Ņ‹Đ˛Đ°Ņ‚ŅŒ ĐēаĐē gzip-ҁĐļĐ°Ņ‚Ņ‹Đĩ, Ņ‚Đ°Đē и ĐŊĐĩҁĐļĐ°Ņ‚Ņ‹Đĩ СаĐŋŅ€ĐžŅŅ‹. + +{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *} + +### ĐĄĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ `GzipRoute` { #create-a-custom-gziproute-class } + +ДаĐģĐĩĐĩ ŅĐžĐˇĐ´Đ°Đ´Đ¸Đŧ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐŋОдĐēĐģĐ°ŅŅ `fastapi.routing.APIRoute`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `GzipRequest`. + +На ŅŅ‚ĐžŅ‚ Ņ€Đ°Đˇ ĐžĐŊ ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ ĐŧĐĩŅ‚ĐžĐ´ `APIRoute.get_route_handler()`. + +Đ­Ņ‚ĐžŅ‚ ĐŧĐĩŅ‚ĐžĐ´ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ. ИĐŧĐĩĐŊĐŊĐž ŅŅ‚Đ° Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ ĐŋĐžĐģŅƒŅ‡Đ°ĐĩŅ‚ HTTP-СаĐŋŅ€ĐžŅ и Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ HTTP-ĐžŅ‚Đ˛ĐĩŅ‚. + +ЗдĐĩҁҌ ĐŧŅ‹ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧ ĐĩŅ‘, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ `GzipRequest` иС Đ¸ŅŅ…ĐžĐ´ĐŊĐžĐŗĐž HTTP-СаĐŋŅ€ĐžŅĐ°. + +{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *} + +/// note | ĐĸĐĩŅ…ĐŊĐ¸Ņ‡ĐĩҁĐēиĐĩ Đ´ĐĩŅ‚Đ°Đģи + +ĐŖ `Request` ĐĩŅŅ‚ŅŒ Đ°Ņ‚Ņ€Đ¸ĐąŅƒŅ‚ `request.scope` — ŅŅ‚Đž ĐŋŅ€ĐžŅŅ‚Đž Python-`dict`, ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‰Đ¸Đš ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ, ŅĐ˛ŅĐˇĐ°ĐŊĐŊŅ‹Đĩ ҁ HTTP-СаĐŋŅ€ĐžŅĐžĐŧ. + +ĐŖ `Request` Ņ‚Đ°ĐēĐļĐĩ ĐĩŅŅ‚ŅŒ `request.receive` — Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ Đ´ĐģŅ ÂĢĐŋĐžĐģŅƒŅ‡ĐĩĐŊĐ¸ŅÂģ Ņ‚ĐĩĐģа СаĐŋŅ€ĐžŅĐ°. + +И `dict` `scope`, и Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ `receive` ŅĐ˛ĐģŅŅŽŅ‚ŅŅ Ņ‡Đ°ŅŅ‚ŅŒŅŽ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ ASGI. + +ИĐŧĐĩĐŊĐŊĐž ŅŅ‚Đ¸Ņ… Đ´Đ˛ŅƒŅ… ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚ĐžĐ˛ — `scope` и `receive` — Đ´ĐžŅŅ‚Đ°Ņ‚ĐžŅ‡ĐŊĐž, Ņ‡Ņ‚ĐžĐąŅ‹ ŅĐžĐˇĐ´Đ°Ņ‚ŅŒ ĐŊĐžĐ˛Ņ‹Đš ŅĐēСĐĩĐŧĐŋĐģŅŅ€ `Request`. + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ йОĐģҌ҈Đĩ Đž `Request`, ҁĐŧ. Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ Starlette Đž СаĐŋŅ€ĐžŅĐ°Ņ…. + +/// + +ЕдиĐŊŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐĩ, Ņ‡Ņ‚Đž Đ´ĐĩĐģаĐĩŅ‚ ĐŋĐž-Đ´Ņ€ŅƒĐŗĐžĐŧ҃ Ņ„ŅƒĐŊĐēŅ†Đ¸Ņ, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Ņ‘ĐŊĐŊĐ°Ņ `GzipRequest.get_route_handler`, — ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇŅƒĐĩŅ‚ `Request` в `GzipRequest`. + +БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐŧ҃ ĐŊĐ°Ņˆ `GzipRequest` ĐŋĐžĐˇĐ°ĐąĐžŅ‚Đ¸Ņ‚ŅŅ Đž Ņ€Đ°ŅĐŋаĐēОвĐēĐĩ даĐŊĐŊҋ҅ (ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸) Đ´Đž ĐŋĐĩŅ€ĐĩĐ´Đ°Ņ‡Đ¸ Đ¸Ņ… в ĐŊĐ°ŅˆĐ¸ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*. + +ДаĐģҌ҈Đĩ Đ˛ŅŅ ĐģĐžĐŗĐ¸Đēа ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēи ĐžŅŅ‚Đ°Ņ‘Ņ‚ŅŅ ĐŋŅ€ĐĩĐļĐŊĐĩĐš. + +Но ĐąĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ иСĐŧĐĩĐŊĐĩĐŊĐ¸ŅĐŧ в `GzipRequest.body` Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° ĐąŅƒĐ´ĐĩŅ‚ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи Ņ€Đ°ŅĐŋаĐēОваĐŊĐž ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸, ĐēĐžĐŗĐ´Đ° ĐžĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ ĐˇĐ°ĐŗŅ€ŅƒĐļĐĩĐŊĐž **FastAPI**. + +## Đ”ĐžŅŅ‚ŅƒĐŋ Đē Ņ‚ĐĩĐģ҃ СаĐŋŅ€ĐžŅĐ° в ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК { #accessing-the-request-body-in-an-exception-handler } + +/// tip | ХОвĐĩŅ‚ + +ДĐģŅ Ņ€Đĩ҈ĐĩĐŊĐ¸Ņ ŅŅ‚ĐžĐš ĐˇĐ°Đ´Đ°Ņ‡Đ¸, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŊаĐŧĐŊĐžĐŗĐž ĐŋŅ€ĐžŅ‰Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ `body` в ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐžĐŧ ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ `RequestValidationError` ([ĐžĐąŅ€Đ°ĐąĐžŅ‚Đēа ĐžŅˆĐ¸ĐąĐžĐē](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}). + +Но ŅŅ‚ĐžŅ‚ ĐŋŅ€Đ¸ĐŧĐĩŅ€ Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž аĐēŅ‚ŅƒĐ°ĐģĐĩĐŊ и ĐŋĐžĐēĐ°ĐˇŅ‹Đ˛Đ°ĐĩŅ‚, ĐēаĐē вСаиĐŧОдĐĩĐšŅŅ‚Đ˛ĐžĐ˛Đ°Ņ‚ŅŒ ҁ вĐŊŅƒŅ‚Ņ€ĐĩĐŊĐŊиĐŧи ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅ‚Đ°Đŧи. + +/// + +ĐĸĐĩĐŧ ĐļĐĩ ĐŋĐžĐ´Ņ…ĐžĐ´ĐžĐŧ ĐŧĐžĐļĐŊĐž Đ˛ĐžŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ, Ņ‡Ņ‚ĐžĐąŅ‹ ĐŋĐžĐģŅƒŅ‡Đ¸Ņ‚ŅŒ Đ´ĐžŅŅ‚ŅƒĐŋ Đē Ņ‚ĐĩĐģ҃ СаĐŋŅ€ĐžŅĐ° в ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēĐĩ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиК. + +ĐŅƒĐļĐŊĐž ĐģĐ¸ŅˆŅŒ ĐžĐąŅ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ СаĐŋŅ€ĐžŅ вĐŊŅƒŅ‚Ņ€Đ¸ ĐąĐģĐžĐēа `try`/`except`: + +{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *} + +Đ•ŅĐģи ĐŋŅ€ĐžĐ¸ĐˇĐžĐšĐ´Ņ‘Ņ‚ Đ¸ŅĐēĐģŅŽŅ‡ĐĩĐŊиĐĩ, ŅĐēСĐĩĐŧĐŋĐģŅŅ€ `Request` Đ˛ŅŅ‘ Đĩ҉ґ ĐąŅƒĐ´ĐĩŅ‚ в ОйĐģĐ°ŅŅ‚Đ¸ видиĐŧĐžŅŅ‚Đ¸, ĐŋĐžŅŅ‚ĐžĐŧ҃ ĐŧŅ‹ ҁĐŧĐžĐļĐĩĐŧ ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ Ņ‚ĐĩĐģĐž СаĐŋŅ€ĐžŅĐ° и Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐĩĐŗĐž ĐŋŅ€Đ¸ ĐžĐąŅ€Đ°ĐąĐžŅ‚ĐēĐĩ ĐžŅˆĐ¸ĐąĐēи: + +{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *} + +## ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ `APIRoute` в Ņ€ĐžŅƒŅ‚ĐĩŅ€Đĩ { #custom-apiroute-class-in-a-router } + +Đ’Ņ‹ Ņ‚Đ°ĐēĐļĐĩ ĐŧĐžĐļĐĩŅ‚Đĩ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `route_class` ҃ `APIRouter`: + +{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *} + +В ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸*, ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊĐŊŅ‹Đĩ в `router`, ĐąŅƒĐ´ŅƒŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК ĐēĐģĐ°ŅŅ `TimedRoute` и ĐŋĐžĐģŅƒŅ‡Đ°Ņ‚ Đ´ĐžĐŋĐžĐģĐŊĐ¸Ņ‚ĐĩĐģҌĐŊŅ‹Đš HTTP-ĐˇĐ°ĐŗĐžĐģОвОĐē `X-Response-Time` в ĐžŅ‚Đ˛ĐĩŅ‚Đĩ ҁ Đ˛Ņ€ĐĩĐŧĐĩĐŊĐĩĐŧ, ĐˇĐ°Ņ‚Ņ€Đ°Ņ‡ĐĩĐŊĐŊŅ‹Đŧ ĐŊа Ņ„ĐžŅ€ĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°: + +{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *} diff --git a/docs/ru/docs/how-to/extending-openapi.md b/docs/ru/docs/how-to/extending-openapi.md new file mode 100644 index 000000000..2897fb89b --- /dev/null +++ b/docs/ru/docs/how-to/extending-openapi.md @@ -0,0 +1,80 @@ +# Đ Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ OpenAPI { #extending-openapi } + +ИĐŊĐžĐŗĐ´Đ° ĐŧĐžĐļĐĩŅ‚ ĐŋĐžĐŊĐ°Đ´ĐžĐąĐ¸Ņ‚ŅŒŅŅ иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅƒŅŽ ҁ҅ĐĩĐŧ҃ OpenAPI. + +В ŅŅ‚ĐžĐŧ Ņ€Đ°ĐˇĐ´ĐĩĐģĐĩ ĐŋĐžĐēаСаĐŊĐž, ĐēаĐē ŅŅ‚Đž ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ. + +## ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš ĐŋŅ€ĐžŅ†Đĩҁҁ { #the-normal-process } + +ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš (ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ) ĐŋŅ€ĐžŅ†Đĩҁҁ Đ˛Ņ‹ĐŗĐģŅĐ´Đ¸Ņ‚ Ņ‚Đ°Đē. + +ĐŸŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ `FastAPI` (ŅĐēСĐĩĐŧĐŋĐģŅŅ€) иĐŧĐĩĐĩŅ‚ ĐŧĐĩŅ‚ĐžĐ´ `.openapi()`, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Đ´ĐžĐģĐļĐĩĐŊ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI. + +В ĐŋŅ€ĐžŅ†ĐĩҁҁĐĩ ŅĐžĐˇĐ´Đ°ĐŊĐ¸Ņ ĐžĐąŅŠĐĩĐēŅ‚Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ¸Ņ€ŅƒĐĩŅ‚ŅŅ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸* (ĐžĐąŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸Đē ĐŋŅƒŅ‚Đ¸) Đ´ĐģŅ `/openapi.json` (иĐģи Đ´ĐģŅ Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž ҃ĐēаСаĐŊĐž в Đ˛Đ°ŅˆĐĩĐŧ `openapi_url`). + +ОĐŊа ĐŋŅ€ĐžŅŅ‚Đž Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ JSON-ĐžŅ‚Đ˛ĐĩŅ‚ ҁ Ņ€ĐĩĐˇŅƒĐģŅŒŅ‚Đ°Ņ‚ĐžĐŧ Đ˛Ņ‹ĐˇĐžĐ˛Đ° ĐŧĐĩŅ‚ĐžĐ´Đ° ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸Ņ `.openapi()`. + +По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ ĐŧĐĩŅ‚ĐžĐ´ `.openapi()` ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅĐĩŅ‚ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž `.openapi_schema`: ĐĩҁĐģи в ĐŊŅ‘Đŧ ҃ĐļĐĩ ĐĩŅŅ‚ŅŒ даĐŊĐŊŅ‹Đĩ, Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚ Đ¸Ņ…. + +Đ•ŅĐģи ĐŊĐĩŅ‚ — ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩŅ‚ ҁ҅ĐĩĐŧ҃ ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊОК Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ `fastapi.openapi.utils.get_openapi`. + +Đ¤ŅƒĐŊĐēŅ†Đ¸Ņ `get_openapi()` ĐŋŅ€Đ¸ĐŊиĐŧаĐĩŅ‚ ĐŋĐ°Ņ€Đ°ĐŧĐĩ҂Ҁҋ: + +* `title`: Đ—Đ°ĐŗĐžĐģОвОĐē OpenAPI, ĐžŅ‚ĐžĐąŅ€Đ°ĐļаĐĩŅ‚ŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. +* `version`: ВĐĩŅ€ŅĐ¸Ņ Đ˛Đ°ŅˆĐĩĐŗĐž API, ĐŊаĐŋŅ€Đ¸ĐŧĐĩŅ€ `2.5.0`. +* `openapi_version`: ВĐĩŅ€ŅĐ¸Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧОК ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸ĐēĐ°Ņ†Đ¸Đ¸ OpenAPI. По ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ — ĐŋĐžŅĐģĐĩĐ´ĐŊŅŅ: `3.1.0`. +* `summary`: ĐšŅ€Đ°Ņ‚ĐēĐžĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ API. +* `description`: ОĐŋĐ¸ŅĐ°ĐŊиĐĩ Đ˛Đ°ŅˆĐĩĐŗĐž API; ĐŧĐžĐļĐĩŅ‚ вĐēĐģŅŽŅ‡Đ°Ņ‚ŅŒ Markdown и ĐąŅƒĐ´ĐĩŅ‚ ĐžŅ‚ĐžĐąŅ€Đ°ĐļаĐĩŅ‚ŅŅ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸. +* `routes`: ĐĄĐŋĐ¸ŅĐžĐē ĐŧĐ°Ņ€ŅˆŅ€ŅƒŅ‚ĐžĐ˛ — ŅŅ‚Đž ĐēаĐļĐ´Đ°Ņ ĐˇĐ°Ņ€ĐĩĐŗĐ¸ŅŅ‚Ņ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐ°Ņ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Ņ ĐŋŅƒŅ‚Đ¸*. БĐĩŅ€ŅƒŅ‚ŅŅ иС `app.routes`. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ĐŸĐ°Ņ€Đ°ĐŧĐĩ҂Ҁ `summary` Đ´ĐžŅŅ‚ŅƒĐŋĐĩĐŊ в OpenAPI 3.1.0 и Đ˛Ņ‹ŅˆĐĩ, ĐŋОддĐĩŅ€ĐļиваĐĩŅ‚ŅŅ FastAPI вĐĩŅ€ŅĐ¸Đ¸ 0.99.0 и Đ˛Ņ‹ŅˆĐĩ. + +/// + +## ПĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐĩĐŊиĐĩ СĐŊĐ°Ņ‡ĐĩĐŊиК ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ { #overriding-the-defaults } + +Đ˜ŅĐŋĐžĐģŅŒĐˇŅƒŅ иĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸ŅŽ Đ˛Ņ‹ŅˆĐĩ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Ņ‚ĐžĐš ĐļĐĩ Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊОК Ņ„ŅƒĐŊĐēŅ†Đ¸ĐĩĐš ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ OpenAPI и ĐŋĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚ŅŒ ĐģŅŽĐąŅ‹Đĩ ĐŊ҃ĐļĐŊŅ‹Đĩ Ņ‡Đ°ŅŅ‚Đ¸. + +НаĐŋŅ€Đ¸ĐŧĐĩŅ€, дОйавиĐŧ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ OpenAPI ReDoc Đ´ĐģŅ вĐēĐģŅŽŅ‡ĐĩĐŊĐ¸Ņ ŅĐžĐąŅŅ‚Đ˛ĐĩĐŊĐŊĐžĐŗĐž ĐģĐžĐŗĐžŅ‚Đ¸Đŋа. + +### ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đš **FastAPI** { #normal-fastapi } + +ĐĄĐŊĐ°Ņ‡Đ°Đģа ĐŊаĐŋĐ¸ŅˆĐ¸Ņ‚Đĩ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊиĐĩ **FastAPI** ĐēаĐē ĐžĐąŅ‹Ņ‡ĐŊĐž: + +{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *} + +### ĐĄĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐšŅ‚Đĩ ҁ҅ĐĩĐŧ҃ OpenAPI { #generate-the-openapi-schema } + +Đ—Đ°Ņ‚ĐĩĐŧ Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐšŅ‚Đĩ Ņ‚Ņƒ ĐļĐĩ Đ˛ŅĐŋĐžĐŧĐžĐŗĐ°Ņ‚ĐĩĐģҌĐŊŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ Đ´ĐģŅ ĐŗĐĩĐŊĐĩŅ€Đ°Ņ†Đ¸Đ¸ ҁ҅ĐĩĐŧŅ‹ OpenAPI вĐŊŅƒŅ‚Ņ€Đ¸ Ņ„ŅƒĐŊĐēŅ†Đ¸Đ¸ `custom_openapi()`: + +{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *} + +### ИСĐŧĐĩĐŊĐ¸Ņ‚Đĩ ҁ҅ĐĩĐŧ҃ OpenAPI { #modify-the-openapi-schema } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ ĐŧĐžĐļĐŊĐž Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ€Đ°ŅŅˆĐ¸Ņ€ĐĩĐŊиĐĩ ReDoc, дОйавив ĐēĐ°ŅŅ‚ĐžĐŧĐŊŅ‹Đš `x-logo` в ÂĢĐžĐąŅŠĐĩĐēŅ‚Âģ `info` в ҁ҅ĐĩĐŧĐĩ OpenAPI: + +{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *} + +### ĐšŅŅˆĐ¸Ņ€ŅƒĐšŅ‚Đĩ ҁ҅ĐĩĐŧ҃ OpenAPI { #cache-the-openapi-schema } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅĐ˛ĐžĐšŅŅ‚Đ˛Đž `.openapi_schema` ĐēаĐē ÂĢĐēŅŅˆÂģ Đ´ĐģŅ Ņ…Ņ€Đ°ĐŊĐĩĐŊĐ¸Ņ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊОК ҁ҅ĐĩĐŧŅ‹. + +ĐĸаĐē ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊĐ¸ŅŽ ĐŊĐĩ ĐŋŅ€Đ¸Đ´Ņ‘Ņ‚ŅŅ ĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ҁ҅ĐĩĐŧ҃ ĐēаĐļĐ´Ņ‹Đš Ņ€Đ°Đˇ, ĐēĐžĐŗĐ´Đ° ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌ ĐžŅ‚ĐēŅ€Ņ‹Đ˛Đ°ĐĩŅ‚ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ API. + +ОĐŊа ĐąŅƒĐ´ĐĩŅ‚ ŅĐžĐˇĐ´Đ°ĐŊа ОдиĐŊ Ņ€Đ°Đˇ, а ĐˇĐ°Ņ‚ĐĩĐŧ Ņ‚ĐžŅ‚ ĐļĐĩ ĐēŅŅˆĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš Đ˛Đ°Ņ€Đ¸Đ°ĐŊŅ‚ ĐąŅƒĐ´ĐĩŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒŅŅ Đ´ĐģŅ ĐŋĐžŅĐģĐĩĐ´ŅƒŅŽŅ‰Đ¸Ņ… СаĐŋŅ€ĐžŅĐžĐ˛. + +{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *} + +### ПĐĩŅ€ĐĩĐžĐŋŅ€ĐĩĐ´ĐĩĐģĐ¸Ņ‚Đĩ ĐŧĐĩŅ‚ĐžĐ´ { #override-the-method } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ СаĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ĐŧĐĩŅ‚ĐžĐ´ `.openapi()` ĐŊа Đ˛Đ°ŅˆŅƒ ĐŊĐžĐ˛ŅƒŅŽ Ņ„ŅƒĐŊĐēŅ†Đ¸ŅŽ. + +{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *} + +### ĐŸŅ€ĐžĐ˛ĐĩŅ€ŅŒŅ‚Đĩ { #check-it } + +ПĐĩŅ€ĐĩĐšĐ´Đ¸Ņ‚Đĩ ĐŊа http://127.0.0.1:8000/redoc — Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ, Ņ‡Ņ‚Đž Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩŅ‚ŅŅ Đ˛Đ°Ņˆ ĐēĐ°ŅŅ‚ĐžĐŧĐŊŅ‹Đš ĐģĐžĐŗĐžŅ‚Đ¸Đŋ (в ŅŅ‚ĐžĐŧ ĐŋŅ€Đ¸ĐŧĐĩŅ€Đĩ — ĐģĐžĐŗĐžŅ‚Đ¸Đŋ **FastAPI**): + + diff --git a/docs/ru/docs/how-to/general.md b/docs/ru/docs/how-to/general.md new file mode 100644 index 000000000..029ea1d27 --- /dev/null +++ b/docs/ru/docs/how-to/general.md @@ -0,0 +1,39 @@ +# ĐžĐąŅ‰ĐĩĐĩ — КаĐē ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ — Đ Đĩ҆ĐĩĐŋ҂ҋ { #general-how-to-recipes } + +ЗдĐĩҁҌ ĐŊĐĩҁĐēĐžĐģҌĐēĐž ҃ĐēĐ°ĐˇĐ°Ņ‚ĐĩĐģĐĩĐš ĐŊа Đ´Ņ€ŅƒĐŗĐ¸Đĩ ĐŧĐĩŅŅ‚Đ° в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Đ´ĐģŅ ĐžĐąŅ‰Đ¸Ņ… иĐģи Ņ‡Đ°ŅŅ‚Ņ‹Ņ… вОĐŋŅ€ĐžŅĐžĐ˛. + +## ФиĐģŅŒŅ‚Ņ€Đ°Ņ†Đ¸Ņ даĐŊĐŊҋ҅ — БĐĩСОĐŋĐ°ŅĐŊĐžŅŅ‚ŅŒ { #filter-data-security } + +Đ§Ņ‚ĐžĐąŅ‹ ŅƒĐąĐĩĐ´Đ¸Ņ‚ŅŒŅŅ, Ņ‡Ņ‚Đž Đ˛Ņ‹ ĐŊĐĩ Đ˛ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩŅ‚Đĩ йОĐģҌ҈Đĩ даĐŊĐŊҋ҅, ҇ĐĩĐŧ ҁĐģĐĩĐ´ŅƒĐĩŅ‚, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — МодĐĩĐģҌ ĐžŅ‚Đ˛ĐĩŅ‚Đ° — Đ’ĐžĐˇĐ˛Ņ€Đ°Ņ‰Đ°ĐĩĐŧŅ‹Đš Ņ‚Đ¸Đŋ](../tutorial/response-model.md){.internal-link target=_blank}. + +## ĐĸĐĩĐŗĐ¸ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ — OpenAPI { #documentation-tags-openapi } + +Đ§Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ Ņ‚ĐĩĐŗĐ¸ Đē Đ˛Đ°ŅˆĐ¸Đŧ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧ ĐŋŅƒŅ‚Đ¸* и ĐŗŅ€ŅƒĐŋĐŋĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Đ¸Ņ… в иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — КоĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸ — ĐĸĐĩĐŗĐ¸](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}. + +## ĐšŅ€Đ°Ņ‚ĐēĐžĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ и ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ — OpenAPI { #documentation-summary-and-description-openapi } + +Đ§Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐēŅ€Đ°Ņ‚ĐēĐžĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ и ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ Đē Đ˛Đ°ŅˆĐ¸Đŧ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅĐŧ ĐŋŅƒŅ‚Đ¸* и ĐžŅ‚ĐžĐąŅ€Đ°ĐˇĐ¸Ņ‚ŅŒ Đ¸Ņ… в иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — КоĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸ — ĐšŅ€Đ°Ņ‚ĐēĐžĐĩ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ и ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}. + +## ОĐŋĐ¸ŅĐ°ĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ° в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ — OpenAPI { #documentation-response-description-openapi } + +Đ§Ņ‚ĐžĐąŅ‹ ĐˇĐ°Đ´Đ°Ņ‚ŅŒ ĐžĐŋĐ¸ŅĐ°ĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°, ĐžŅ‚ĐžĐąŅ€Đ°ĐļаĐĩĐŧĐžĐĩ в иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — КоĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸ — ОĐŋĐ¸ŅĐ°ĐŊиĐĩ ĐžŅ‚Đ˛ĐĩŅ‚Đ°](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}. + +## ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ — ĐŋĐžĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸ ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐĩĐš — OpenAPI { #documentation-deprecate-a-path-operation-openapi } + +Đ§Ņ‚ĐžĐąŅ‹ ĐŋĐžĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸* ĐēаĐē ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆŅƒŅŽ и ĐŋĐžĐēĐ°ĐˇĐ°Ņ‚ŅŒ ŅŅ‚Đž в иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — КоĐŊŅ„Đ¸ĐŗŅƒŅ€Đ°Ņ†Đ¸Đ¸ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đš ĐŋŅƒŅ‚Đ¸ — ПоĐŧĐĩŅ‚Đ¸Ņ‚ŅŒ ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸ŅŽ ĐŋŅƒŅ‚Đ¸ ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐĩĐš](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}. + +## ĐŸŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°ĐŊиĐĩ ĐģŅŽĐąŅ‹Ņ… даĐŊĐŊҋ҅ Đē Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņƒ, ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐžĐŧ҃ ҁ JSON { #convert-any-data-to-json-compatible } + +Đ§Ņ‚ĐžĐąŅ‹ ĐŋŅ€ĐĩĐžĐąŅ€Đ°ĐˇĐžĐ˛Đ°Ņ‚ŅŒ ĐģŅŽĐąŅ‹Đĩ даĐŊĐŊŅ‹Đĩ Đē Ņ„ĐžŅ€ĐŧĐ°Ņ‚Ņƒ, ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧĐžĐŧ҃ ҁ JSON, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — JSON-ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅ‹Đš ĐēĐžĐ´Đ¸Ņ€ĐžĐ˛Ņ‰Đ¸Đē](../tutorial/encoder.md){.internal-link target=_blank}. + +## МĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ OpenAPI — ДоĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ { #openapi-metadata-docs } + +Đ§Ņ‚ĐžĐąŅ‹ Đ´ĐžĐąĐ°Đ˛Đ¸Ņ‚ŅŒ ĐŧĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ в Đ˛Đ°ŅˆŅƒ ҁ҅ĐĩĐŧ҃ OpenAPI, вĐēĐģŅŽŅ‡Đ°Ņ ĐģĐ¸Ņ†ĐĩĐŊĐˇĐ¸ŅŽ, вĐĩŅ€ŅĐ¸ŅŽ, ĐēĐžĐŊŅ‚Đ°Đē҂ҋ и Ņ‚.Đ´., ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — МĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ и URL Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸](../tutorial/metadata.md){.internal-link target=_blank}. + +## ПоĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēиК URL OpenAPI { #openapi-custom-url } + +Đ§Ņ‚ĐžĐąŅ‹ ĐŊĐ°ŅŅ‚Ņ€ĐžĐ¸Ņ‚ŅŒ URL OpenAPI (иĐģи ŅƒĐ´Đ°ĐģĐ¸Ņ‚ŅŒ ĐĩĐŗĐž), ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — МĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ и URL Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}. + +## URL Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ OpenAPI { #openapi-docs-urls } + +Đ§Ņ‚ĐžĐąŅ‹ иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ URL, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Đĩ Đ´ĐģŅ Đ°Đ˛Ņ‚ĐžĐŧĐ°Ņ‚Đ¸Ņ‡ĐĩҁĐēи ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊҋ҅ ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅĐžĐ˛ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸, ĐŋŅ€ĐžŅ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ŅŽ: [Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž — МĐĩŅ‚Đ°Đ´Đ°ĐŊĐŊŅ‹Đĩ и URL Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}. diff --git a/docs/ru/docs/how-to/graphql.md b/docs/ru/docs/how-to/graphql.md new file mode 100644 index 000000000..9ed6d95ca --- /dev/null +++ b/docs/ru/docs/how-to/graphql.md @@ -0,0 +1,60 @@ +# GraphQL { #graphql } + +ĐĸаĐē ĐēаĐē **FastAPI** ĐžŅĐŊОваĐŊ ĐŊа ŅŅ‚Đ°ĐŊĐ´Đ°Ņ€Ņ‚Đĩ **ASGI**, ĐžŅ‡ĐĩĐŊҌ ĐģĐĩĐŗĐēĐž иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐģŅŽĐąŅƒŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃ **GraphQL**, Ņ‚Đ°ĐēĐļĐĩ ŅĐžĐ˛ĐŧĐĩŅŅ‚Đ¸ĐŧŅƒŅŽ ҁ ASGI. + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐēĐžĐŧйиĐŊĐ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đĩ *ĐžĐŋĐĩŅ€Đ°Ņ†Đ¸Đ¸ ĐŋŅƒŅ‚Đ¸* FastAPI ҁ GraphQL в ОдĐŊĐžĐŧ ĐŋŅ€Đ¸ĐģĐžĐļĐĩĐŊии. + +/// tip | ХОвĐĩŅ‚ + +**GraphQL** Ņ€ĐĩŅˆĐ°ĐĩŅ‚ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ ĐžŅ‡ĐĩĐŊҌ ҁĐŋĐĩŅ†Đ¸Ņ„Đ¸Ņ‡ĐĩҁĐēиĐĩ ĐˇĐ°Đ´Đ°Ņ‡Đ¸. + +ĐŖ ĐŊĐĩĐŗĐž ĐĩŅŅ‚ŅŒ ĐēаĐē **ĐŋŅ€ĐĩиĐŧŅƒŅ‰ĐĩŅŅ‚Đ˛Đ°**, Ņ‚Đ°Đē и **ĐŊĐĩĐ´ĐžŅŅ‚Đ°Ņ‚Đēи** ĐŋĐž ŅŅ€Đ°Đ˛ĐŊĐĩĐŊĐ¸ŅŽ ҁ ĐžĐąŅ‹Ņ‡ĐŊŅ‹Đŧи **вĐĩĐą-API**. + +ĐŖĐąĐĩĐ´Đ¸Ņ‚ĐĩҁҌ, Ņ‡Ņ‚Đž **Đ˛Ņ‹ĐŗĐžĐ´Ņ‹** Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ҁĐģŅƒŅ‡Đ°Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ ĐŋĐĩŅ€ĐĩвĐĩŅˆĐ¸Đ˛Đ°ŅŽŅ‚ **ĐŊĐĩĐ´ĐžŅŅ‚Đ°Ņ‚Đēи**. 🤓 + +/// + +## БибĐģĐ¸ĐžŅ‚ĐĩĐēи GraphQL { #graphql-libraries } + +НиĐļĐĩ ĐŋŅ€Đ¸Đ˛ĐĩĐ´ĐĩĐŊŅ‹ ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Đĩ йийĐģĐ¸ĐžŅ‚ĐĩĐēи **GraphQL** ҁ ĐŋОддĐĩŅ€ĐļĐēОК **ASGI**. Đ˜Ņ… ĐŧĐžĐļĐŊĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ҁ **FastAPI**: + +* Strawberry 🍓 + * ĐĄ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš Đ´ĐģŅ FastAPI +* Ariadne + * ĐĄ Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš Đ´ĐģŅ FastAPI +* Tartiflette + * ĐĄ Tartiflette ASGI Đ´ĐģŅ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ ҁ ASGI +* Graphene + * ĐĄ starlette-graphene3 + +## GraphQL ŅĐž Strawberry { #graphql-with-strawberry } + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐŊĐž иĐģи Ņ…ĐžŅ‡ĐĩŅ‚ŅŅ Ņ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ **GraphQL**, **Strawberry** — **Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩĐŧĐ°Ņ** йийĐģĐ¸ĐžŅ‚ĐĩĐēа, Ņ‚Đ°Đē ĐēаĐē ĐĩŅ‘ диСаКĐŊ ĐąĐģиĐļĐĩ Đ˛ŅĐĩĐŗĐž Đē диСаКĐŊ҃ **FastAPI**, Đ˛ŅŅ‘ ĐžŅĐŊОваĐŊĐž ĐŊа **аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŅ… Ņ‚Đ¸ĐŋОв**. + +В ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ Đ˛Đ°ŅˆĐĩĐŗĐž ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Ņ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐŋŅ€ĐĩĐ´ĐŋĐžŅ‡ĐĩŅŅ‚ŅŒ Đ´Ņ€ŅƒĐŗŅƒŅŽ йийĐģĐ¸ĐžŅ‚ĐĩĐē҃, ĐŊĐž ĐĩҁĐģи ĐąŅ‹ Đ˛Ņ‹ ҁĐŋŅ€ĐžŅĐ¸Đģи ĐŧĐĩĐŊŅ, Ņ, ҁĐēĐžŅ€ĐĩĐĩ Đ˛ŅĐĩĐŗĐž, ĐŋŅ€ĐĩĐ´ĐģĐžĐļиĐģ ĐąŅ‹ ĐŋĐžĐŋŅ€ĐžĐąĐžĐ˛Đ°Ņ‚ŅŒ **Strawberry**. + +Đ’ĐžŅ‚ ĐŊĐĩйОĐģŅŒŅˆĐžĐš ĐŋŅ€Đ¸ĐŧĐĩŅ€ Ņ‚ĐžĐŗĐž, ĐēаĐē ĐŧĐžĐļĐŊĐž иĐŊŅ‚ĐĩĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ Strawberry ҁ FastAPI: + +{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *} + +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Đž Strawberry ĐŧĐžĐļĐŊĐž ŅƒĐˇĐŊĐ°Ņ‚ŅŒ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ Strawberry. + +А Ņ‚Đ°ĐēĐļĐĩ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ĐŋĐž иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ Strawberry ҁ FastAPI. + +## ĐŖŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐ¸Đš `GraphQLApp` иС Starlette { #older-graphqlapp-from-starlette } + +В ĐŋŅ€ĐĩĐ´Ņ‹Đ´ŅƒŅ‰Đ¸Ņ… вĐĩŅ€ŅĐ¸ŅŅ… Starlette ĐąŅ‹Đģ ĐēĐģĐ°ŅŅ `GraphQLApp` Đ´ĐģŅ иĐŊŅ‚ĐĩĐŗŅ€Đ°Ņ†Đ¸Đ¸ ҁ Graphene. + +ОĐŊ ĐąŅ‹Đģ ĐžĐąŅŠŅĐ˛ĐģĐĩĐŊ ŅƒŅŅ‚Đ°Ņ€ĐĩĐ˛ŅˆĐ¸Đŧ в Starlette, ĐŊĐž ĐĩҁĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ĐēОд, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš ĐĩĐŗĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Đģ, Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐģĐĩĐŗĐēĐž **ĐŧĐ¸ĐŗŅ€Đ¸Ņ€ĐžĐ˛Đ°Ņ‚ŅŒ** ĐŊа starlette-graphene3, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ€ĐĩŅˆĐ°ĐĩŅ‚ Ņ‚Ņƒ ĐļĐĩ ĐˇĐ°Đ´Đ°Ņ‡Ņƒ и иĐŧĐĩĐĩŅ‚ **ĐŋĐžŅ‡Ņ‚Đ¸ идĐĩĐŊŅ‚Đ¸Ņ‡ĐŊŅ‹Đš иĐŊŅ‚ĐĩҀ҄ĐĩĐšŅ**. + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи ваĐŧ ĐŊ҃ĐļĐĩĐŊ GraphQL, Ņ Đ˛ŅŅ‘ ĐļĐĩ Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒŅŽ ĐŋĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ Strawberry, Ņ‚Đ°Đē ĐēаĐē ĐžĐŊ ĐžŅĐŊОваĐŊ ĐŊа аĐŊĐŊĐžŅ‚Đ°Ņ†Đ¸ŅŅ… Ņ‚Đ¸ĐŋОв, а ĐŊĐĩ ĐŊа ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģҌҁĐēĐ¸Ņ… ĐēĐģĐ°ŅŅĐ°Ņ… и Ņ‚Đ¸ĐŋĐ°Ņ…. + +/// + +## ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ { #learn-more } + +ĐŸĐžĐ´Ņ€ĐžĐąĐŊĐĩĐĩ Đž **GraphQL** Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ŅƒĐˇĐŊĐ°Ņ‚ŅŒ в ĐžŅ„Đ¸Ņ†Đ¸Đ°ĐģҌĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ GraphQL. + +ĐĸаĐēĐļĐĩ ĐŧĐžĐļĐŊĐž ĐŋĐžŅ‡Đ¸Ņ‚Đ°Ņ‚ŅŒ йОĐģҌ҈Đĩ Đž ĐēаĐļдОК иС ҃ĐēаСаĐŊĐŊҋ҅ Đ˛Ņ‹ŅˆĐĩ йийĐģĐ¸ĐžŅ‚ĐĩĐē ĐŋĐž ĐŋŅ€Đ¸Đ˛ĐĩĐ´Ņ‘ĐŊĐŊŅ‹Đŧ ҁҁҋĐģĐēаĐŧ. diff --git a/docs/ru/docs/how-to/index.md b/docs/ru/docs/how-to/index.md new file mode 100644 index 000000000..228c125dd --- /dev/null +++ b/docs/ru/docs/how-to/index.md @@ -0,0 +1,13 @@ +# КаĐē ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒ — Đ Đĩ҆ĐĩĐŋ҂ҋ { #how-to-recipes } + +ЗдĐĩҁҌ Đ˛Ņ‹ ĐŊаКдĐĩŅ‚Đĩ Ņ€Đ°ĐˇĐŊŅ‹Đĩ Ņ€Đĩ҆ĐĩĐŋ҂ҋ и Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đ° ÂĢĐēаĐē ŅĐ´ĐĩĐģĐ°Ņ‚ŅŒÂģ ĐŋĐž Ņ€Đ°ĐˇĐģĐ¸Ņ‡ĐŊŅ‹Đŧ Ņ‚ĐĩĐŧаĐŧ. + +БоĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đž иС ŅŅ‚Đ¸Ņ… идĐĩĐš йОĐģĐĩĐĩ-ĐŧĐĩĐŊĐĩĐĩ ĐŊĐĩĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧŅ‹, и в йОĐģŅŒŅˆĐ¸ĐŊŅŅ‚Đ˛Đĩ ҁĐģŅƒŅ‡Đ°Đĩв ваĐŧ ŅŅ‚ĐžĐ¸Ņ‚ Đ¸ĐˇŅƒŅ‡Đ°Ņ‚ŅŒ Đ¸Ņ… Ņ‚ĐžĐģҌĐēĐž ĐĩҁĐģи ĐžĐŊи ĐŊаĐŋŅ€ŅĐŧŅƒŅŽ ĐžŅ‚ĐŊĐžŅŅŅ‚ŅŅ Đē Đ˛Đ°ŅˆĐĩĐŧ҃ ĐŋŅ€ĐžĐĩĐēŅ‚Ņƒ. + +Đ•ŅĐģи Ņ‡Ņ‚Đž-Ņ‚Đž ĐēаĐļĐĩŅ‚ŅŅ иĐŊŅ‚ĐĩŅ€ĐĩҁĐŊŅ‹Đŧ и ĐŋĐžĐģĐĩСĐŊŅ‹Đŧ Đ´ĐģŅ Đ˛Đ°ŅˆĐĩĐŗĐž ĐŋŅ€ĐžĐĩĐēŅ‚Đ°, ҁĐŧĐĩĐģĐž Đ¸ĐˇŅƒŅ‡Đ°ĐšŅ‚Đĩ; в ĐŋŅ€ĐžŅ‚Đ¸Đ˛ĐŊĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ, вĐĩŅ€ĐžŅŅ‚ĐŊĐž, ĐŧĐžĐļĐŊĐž ĐŋŅ€ĐžŅŅ‚Đž ĐŋŅ€ĐžĐŋŅƒŅŅ‚Đ¸Ņ‚ŅŒ. + +/// tip | ХОвĐĩŅ‚ + +Đ•ŅĐģи Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ Đ¸ĐˇŅƒŅ‡Đ¸Ņ‚ŅŒ FastAPI ŅŅ‚Ņ€ŅƒĐēŅ‚ŅƒŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊĐž (Ņ€ĐĩĐēĐžĐŧĐĩĐŊĐ´ŅƒĐĩŅ‚ŅŅ), вĐŧĐĩŅŅ‚Đž ŅŅ‚ĐžĐŗĐž Ņ‡Đ¸Ņ‚Đ°ĐšŅ‚Đĩ [ĐŖŅ‡ĐĩĐąĐŊиĐē — Đ ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ĐĩĐģŅ](../tutorial/index.md){.internal-link target=_blank} ĐŋĐž ĐŗĐģаваĐŧ. + +/// diff --git a/docs/ru/docs/how-to/separate-openapi-schemas.md b/docs/ru/docs/how-to/separate-openapi-schemas.md new file mode 100644 index 000000000..5b1214016 --- /dev/null +++ b/docs/ru/docs/how-to/separate-openapi-schemas.md @@ -0,0 +1,104 @@ +# РаСдĐĩĐģŅŅ‚ŅŒ ҁ҅ĐĩĐŧŅ‹ OpenAPI Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ° и Đ˛Ņ‹Ņ…ĐžĐ´Đ° иĐģи ĐŊĐĩŅ‚ { #separate-openapi-schemas-for-input-and-output-or-not } + +ĐŸŅ€Đ¸ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊии **Pydantic v2** ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš OpenAPI ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ Ņ‡ŅƒŅ‚ŅŒ йОĐģĐĩĐĩ Ņ‚ĐžŅ‡ĐŊŅ‹Đŧ и **ĐēĐžŅ€Ņ€ĐĩĐēŅ‚ĐŊŅ‹Đŧ**, ҇ĐĩĐŧ Ņ€Đ°ĐŊҌ҈Đĩ. 😎 + +На ŅĐ°ĐŧĐžĐŧ Đ´ĐĩĐģĐĩ, в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… в OpenAPI ĐąŅƒĐ´ĐĩŅ‚ даĐļĐĩ **двĐĩ JSON ҁ҅ĐĩĐŧŅ‹** Đ´ĐģŅ ОдĐŊОК и Ņ‚ĐžĐš ĐļĐĩ Pydantic‑ĐŧОдĐĩĐģи: Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ° и Đ´ĐģŅ Đ˛Ņ‹Ņ…ĐžĐ´Đ° — в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ ĐŊаĐģĐ¸Ņ‡Đ¸Ņ **СĐŊĐ°Ņ‡ĐĩĐŊиК ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ**. + +ĐŸĐžŅĐŧĐžŅ‚Ņ€Đ¸Đŧ, ĐēаĐē ŅŅ‚Đž Ņ€Đ°ĐąĐžŅ‚Đ°ĐĩŅ‚, и ĐēаĐē ŅŅ‚Đž иСĐŧĐĩĐŊĐ¸Ņ‚ŅŒ ĐŋŅ€Đ¸ ĐŊĐĩĐžĐąŅ…ĐžĐ´Đ¸ĐŧĐžŅŅ‚Đ¸. + +## Pydantic‑ĐŧОдĐĩĐģи Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ° и Đ˛Ņ‹Ņ…ĐžĐ´Đ° { #pydantic-models-for-input-and-output } + +ĐŸŅ€ĐĩĐ´ĐŋĐžĐģĐžĐļиĐŧ, ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ Pydantic‑ĐŧОдĐĩĐģҌ ŅĐž СĐŊĐ°Ņ‡ĐĩĐŊĐ¸ŅĐŧи ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, ĐēаĐē СдĐĩҁҌ: + +{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *} + +### МодĐĩĐģҌ Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ° { #model-for-input } + +Đ•ŅĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ ŅŅ‚Ņƒ ĐŧОдĐĩĐģҌ ĐēаĐē Đ˛Ņ…ĐžĐ´ĐŊŅƒŅŽ, ĐēаĐē СдĐĩҁҌ: + +{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *} + +â€ĻŅ‚Đž ĐŋĐžĐģĐĩ `description` **ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ**, ĐŋĐžŅ‚ĐžĐŧ҃ Ņ‡Ņ‚Đž ҃ ĐŊĐĩĐŗĐž СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ `None`. + +### Đ’Ņ…ĐžĐ´ĐŊĐ°Ņ ĐŧОдĐĩĐģҌ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #input-model-in-docs } + +В Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ŅŅ‚Đž видĐŊĐž: ҃ ĐŋĐžĐģŅ `description` ĐŊĐĩŅ‚ **ĐēŅ€Đ°ŅĐŊОК ĐˇĐ˛Ņ‘ĐˇĐ´ĐžŅ‡Đēи** — ĐžĐŊĐž ĐŊĐĩ ĐžŅ‚ĐŧĐĩ҇ĐĩĐŊĐž ĐēаĐē ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐžĐĩ: + +
+ +
+ +### МодĐĩĐģҌ Đ´ĐģŅ Đ˛Ņ‹Ņ…ĐžĐ´Đ° { #model-for-output } + +Но ĐĩҁĐģи Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°Ņ‚ŅŒ Ņ‚Ņƒ ĐļĐĩ ĐŧОдĐĩĐģҌ ĐēаĐē Đ˛Ņ‹Ņ…ĐžĐ´ĐŊŅƒŅŽ, ĐēаĐē СдĐĩҁҌ: + +{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *} + +â€ĻŅ‚Đž, ĐŋĐžŅĐēĐžĐģҌĐē҃ ҃ `description` ĐĩŅŅ‚ŅŒ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ, даĐļĐĩ ĐĩҁĐģи Đ˛Ņ‹ **ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩ вĐĩŅ€ĐŊґ҂Đĩ** Đ´ĐģŅ ŅŅ‚ĐžĐŗĐž ĐŋĐžĐģŅ, ĐžĐŊĐž Đ˛ŅŅ‘ Ņ€Đ°Đ˛ĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ иĐŧĐĩŅ‚ŅŒ ŅŅ‚Đž **СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ**. + +### МодĐĩĐģҌ Đ´ĐģŅ даĐŊĐŊҋ҅ ĐžŅ‚Đ˛ĐĩŅ‚Đ° { #model-for-output-response-data } + +Đ•ŅĐģи ĐŋĐžŅ€Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ҁ иĐŊŅ‚ĐĩŅ€Đ°ĐēŅ‚Đ¸Đ˛ĐŊОК Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸ĐĩĐš и ĐŋĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ ĐžŅ‚Đ˛ĐĩŅ‚, Ņ‚Đž, Ņ…ĐžŅ‚Ņ ĐēОд ĐŊĐ¸Ņ‡ĐĩĐŗĐž ĐŊĐĩ дОйавиĐģ в ОдĐŊĐž иС ĐŋĐžĐģĐĩĐš `description`, JSONâ€‘ĐžŅ‚Đ˛ĐĩŅ‚ ŅĐžĐ´ĐĩŅ€ĐļĐ¸Ņ‚ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ (`null`): + +
+ +
+ +Đ­Ņ‚Đž ОСĐŊĐ°Ņ‡Đ°ĐĩŅ‚, Ņ‡Ņ‚Đž ҃ ĐŊĐĩĐŗĐž **Đ˛ŅĐĩĐŗĐ´Đ° ĐąŅƒĐ´ĐĩŅ‚ ĐēаĐēĐžĐĩâ€‘Ņ‚Đž СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ**, ĐŋŅ€ĐžŅŅ‚Đž иĐŊĐžĐŗĐ´Đ° ŅŅ‚Đž СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ `None` (иĐģи `null` в JSON). + +ĐĄĐģĐĩĐ´ĐžĐ˛Đ°Ņ‚ĐĩĐģҌĐŊĐž, ĐēĐģиĐĩĐŊŅ‚Đ°Đŧ, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅŽŅ‰Đ¸Đŧ Đ˛Đ°Ņˆ API, ĐŊĐĩ ĐŊ҃ĐļĐŊĐž ĐŋŅ€ĐžĐ˛ĐĩŅ€ŅŅ‚ŅŒ ĐŊаĐģĐ¸Ņ‡Đ¸Đĩ ŅŅ‚ĐžĐŗĐž СĐŊĐ°Ņ‡ĐĩĐŊĐ¸Ņ: ĐžĐŊи ĐŧĐžĐŗŅƒŅ‚ **Đ¸ŅŅ…ĐžĐ´Đ¸Ņ‚ŅŒ иС Ņ‚ĐžĐŗĐž, Ņ‡Ņ‚Đž ĐŋĐžĐģĐĩ Đ˛ŅĐĩĐŗĐ´Đ° ĐŋŅ€Đ¸ŅŅƒŅ‚ŅŅ‚Đ˛ŅƒĐĩŅ‚**, а в ĐŊĐĩĐēĐžŅ‚ĐžŅ€Ņ‹Ņ… ҁĐģŅƒŅ‡Đ°ŅŅ… иĐŧĐĩĐĩŅ‚ СĐŊĐ°Ņ‡ĐĩĐŊиĐĩ ĐŋĐž ҃ĐŧĐžĐģŅ‡Đ°ĐŊĐ¸ŅŽ `None`. + +В OpenAPI ŅŅ‚Đž ĐžĐŋĐ¸ŅŅ‹Đ˛Đ°ĐĩŅ‚ŅŅ Ņ‚ĐĩĐŧ, Ņ‡Ņ‚Đž ĐŋĐžĐģĐĩ ĐŋĐžĐŧĐĩŅ‡Đ°ĐĩŅ‚ŅŅ ĐēаĐē **ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐžĐĩ**, ĐŋĐžŅĐēĐžĐģҌĐē҃ ĐžĐŊĐž Đ˛ŅĐĩĐŗĐ´Đ° ĐŋŅ€Đ¸ŅŅƒŅ‚ŅŅ‚Đ˛ŅƒĐĩŅ‚. + +Из‑за ŅŅ‚ĐžĐŗĐž JSON Schema Đ´ĐģŅ ĐŧОдĐĩĐģи ĐŧĐžĐļĐĩŅ‚ ĐžŅ‚ĐģĐ¸Ņ‡Đ°Ņ‚ŅŒŅŅ в ĐˇĐ°Đ˛Đ¸ŅĐ¸ĐŧĐžŅŅ‚Đ¸ ĐžŅ‚ Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸Ņ Đ´ĐģŅ **Đ˛Ņ…ĐžĐ´Đ°** иĐģи **Đ˛Ņ‹Ņ…ĐžĐ´Đ°**: + +* Đ´ĐģŅ **Đ˛Ņ…ĐžĐ´Đ°** `description` ĐŊĐĩ ĐąŅƒĐ´ĐĩŅ‚ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ +* Đ´ĐģŅ **Đ˛Ņ‹Ņ…ĐžĐ´Đ°** ĐžĐŊĐž ĐąŅƒĐ´ĐĩŅ‚ **ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ** (и ĐŋŅ€Đ¸ ŅŅ‚ĐžĐŧ ĐŧĐžĐļĐĩŅ‚ ĐąŅ‹Ņ‚ŅŒ `None`, иĐģи, в Ņ‚ĐĩŅ€ĐŧиĐŊĐ°Ņ… JSON, `null`) + +### Đ’Ņ‹Ņ…ĐžĐ´ĐŊĐ°Ņ ĐŧОдĐĩĐģҌ в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #model-for-output-in-docs } + +В Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ ŅŅ‚Đž Ņ‚ĐžĐļĐĩ видĐŊĐž, Ņ‡Ņ‚Đž **Ойа**: `name` и `description`, ĐŋĐžĐŧĐĩ҇ĐĩĐŊŅ‹ **ĐēŅ€Đ°ŅĐŊОК ĐˇĐ˛Ņ‘ĐˇĐ´ĐžŅ‡ĐēОК** ĐēаĐē **ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đĩ**: + +
+ +
+ +### МодĐĩĐģи Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ° и Đ˛Ņ‹Ņ…ĐžĐ´Đ° в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #model-for-input-and-output-in-docs } + +Đ•ŅĐģи ĐŋĐžŅĐŧĐžŅ‚Ņ€ĐĩŅ‚ŅŒ Đ˛ŅĐĩ Đ´ĐžŅŅ‚ŅƒĐŋĐŊŅ‹Đĩ ҁ҅ĐĩĐŧŅ‹ (JSON Schema) в OpenAPI, Đ˛Ņ‹ ŅƒĐ˛Đ¸Đ´Đ¸Ņ‚Đĩ двĐĩ: `Item-Input` и `Item-Output`. + +ДĐģŅ `Item-Input` ĐŋĐžĐģĐĩ `description` **ĐŊĐĩ ŅĐ˛ĐģŅĐĩŅ‚ŅŅ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ** — ĐēŅ€Đ°ŅĐŊОК ĐˇĐ˛Ņ‘ĐˇĐ´ĐžŅ‡Đēи ĐŊĐĩŅ‚. + +А Đ´ĐģŅ `Item-Output` `description` **ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊĐž** — ĐēŅ€Đ°ŅĐŊĐ°Ņ ĐˇĐ˛Ņ‘ĐˇĐ´ĐžŅ‡Đēа ĐĩŅŅ‚ŅŒ. + +
+ +
+ +БĐģĐ°ĐŗĐžĐ´Đ°Ņ€Ņ ŅŅ‚ĐžĐš вОСĐŧĐžĐļĐŊĐžŅŅ‚Đ¸ **Pydantic v2** Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Ņ Đ˛Đ°ŅˆĐĩĐŗĐž API ŅŅ‚Đ°ĐŊĐžĐ˛Đ¸Ņ‚ŅŅ йОĐģĐĩĐĩ **Ņ‚ĐžŅ‡ĐŊОК**; ĐĩҁĐģи ҃ Đ˛Đ°Ņ ĐĩŅŅ‚ŅŒ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đĩ ĐēĐģиĐĩĐŊ҂ҋ и SDK, ĐžĐŊи Ņ‚ĐžĐļĐĩ ĐąŅƒĐ´ŅƒŅ‚ Ņ‚ĐžŅ‡ĐŊĐĩĐĩ, ҁ ĐģŅƒŅ‡ŅˆĐ¸Đŧ **ŅƒĐ´ĐžĐąŅŅ‚Đ˛ĐžĐŧ Đ´ĐģŅ Ņ€Đ°ĐˇŅ€Đ°ĐąĐžŅ‚Ņ‡Đ¸ĐēОв** и йОĐģҌ҈ĐĩĐš ĐēĐžĐŊŅĐ¸ŅŅ‚ĐĩĐŊŅ‚ĐŊĐžŅŅ‚ŅŒŅŽ. 🎉 + +## НĐĩ Ņ€Đ°ĐˇĐ´ĐĩĐģŅŅ‚ŅŒ ҁ҅ĐĩĐŧŅ‹ { #do-not-separate-schemas } + +ОдĐŊаĐēĐž ĐąŅ‹Đ˛Đ°ŅŽŅ‚ ҁĐģŅƒŅ‡Đ°Đ¸, ĐēĐžĐŗĐ´Đ° Đ˛Ņ‹ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ иĐŧĐĩŅ‚ŅŒ **ОдĐŊ҃ и Ņ‚Ņƒ ĐļĐĩ ҁ҅ĐĩĐŧ҃ Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ° и Đ˛Ņ‹Ņ…ĐžĐ´Đ°**. + +ГĐģавĐŊŅ‹Đš ҁ҆ĐĩĐŊĐ°Ņ€Đ¸Đš — ĐēĐžĐŗĐ´Đ° ҃ Đ˛Đ°Ņ ҃ĐļĐĩ ĐĩŅŅ‚ŅŒ ŅĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ĐžĐ˛Đ°ĐŊĐŊŅ‹Đš ĐēĐģиĐĩĐŊ҂ҁĐēиК ĐēОд/SDK, и Đ˛Ņ‹ ĐŋĐžĐēа ĐŊĐĩ Ņ…ĐžŅ‚Đ¸Ņ‚Đĩ ОйĐŊОвĐģŅŅ‚ŅŒ вĐĩҁҌ ŅŅ‚ĐžŅ‚ Đ°Đ˛Ņ‚ĐžĐŗĐĩĐŊĐĩŅ€Đ¸Ņ€ŅƒĐĩĐŧŅ‹Đš ĐēОд/SDK (Ņ€Đ°ĐŊĐž иĐģи ĐŋОСдĐŊĐž Đ˛Ņ‹ ŅŅ‚Đž ŅĐ´ĐĩĐģаĐĩŅ‚Đĩ, ĐŊĐž ĐŊĐĩ ҁĐĩĐšŅ‡Đ°Ņ). + +В Ņ‚Đ°ĐēĐžĐŧ ҁĐģŅƒŅ‡Đ°Đĩ Đ˛Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ ĐžŅ‚ĐēĐģŅŽŅ‡Đ¸Ņ‚ŅŒ ŅŅ‚Ņƒ Ņ„ŅƒĐŊĐēŅ†Đ¸ĐžĐŊаĐģҌĐŊĐžŅŅ‚ŅŒ в FastAPI ҁ ĐŋĐžĐŧĐžŅ‰ŅŒŅŽ ĐŋĐ°Ņ€Đ°ĐŧĐĩŅ‚Ņ€Đ° `separate_input_output_schemas=False`. + +/// info | ИĐŊŅ„ĐžŅ€ĐŧĐ°Ņ†Đ¸Ņ + +ПоддĐĩŅ€ĐļĐēа `separate_input_output_schemas` ĐŋĐžŅĐ˛Đ¸ĐģĐ°ŅŅŒ в FastAPI `0.102.0`. 🤓 + +/// + +{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *} + +### ОдĐŊа и Ņ‚Đ° ĐļĐĩ ҁ҅ĐĩĐŧа Đ´ĐģŅ Đ˛Ņ…ĐžĐ´ĐŊОК и Đ˛Ņ‹Ņ…ĐžĐ´ĐŊОК ĐŧОдĐĩĐģĐĩĐš в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ { #same-schema-for-input-and-output-models-in-docs } + +ĐĸĐĩĐŋĐĩŅ€ŅŒ Đ´ĐģŅ ŅŅ‚ĐžĐš ĐŧОдĐĩĐģи ĐąŅƒĐ´ĐĩŅ‚ ОдĐŊа ĐžĐąŅ‰Đ°Ņ ҁ҅ĐĩĐŧа и Đ´ĐģŅ Đ˛Ņ…ĐžĐ´Đ°, и Đ´ĐģŅ Đ˛Ņ‹Ņ…ĐžĐ´Đ° — Ņ‚ĐžĐģҌĐēĐž `Item`, и в ĐŊĐĩĐš `description` ĐąŅƒĐ´ĐĩŅ‚ **ĐŊĐĩ ĐžĐąŅĐˇĐ°Ņ‚ĐĩĐģҌĐŊŅ‹Đŧ**: + +
+ +
+ +Đ­Ņ‚Đž Ņ‚Đž ĐļĐĩ ĐŋОвĐĩĐ´ĐĩĐŊиĐĩ, Ņ‡Ņ‚Đž и в Pydantic v1. 🤓 diff --git a/docs/ru/docs/how-to/testing-database.md b/docs/ru/docs/how-to/testing-database.md new file mode 100644 index 000000000..18f4deeca --- /dev/null +++ b/docs/ru/docs/how-to/testing-database.md @@ -0,0 +1,7 @@ +# ĐĸĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊиĐĩ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅ { #testing-a-database } + +Đ’Ņ‹ ĐŧĐžĐļĐĩŅ‚Đĩ Đ¸ĐˇŅƒŅ‡Đ¸Ņ‚ŅŒ ĐąĐ°ĐˇŅ‹ даĐŊĐŊҋ҅, SQL и SQLModel в Đ´ĐžĐē҃ĐŧĐĩĐŊŅ‚Đ°Ņ†Đ¸Đ¸ SQLModel. 🤓 + +Đ•ŅŅ‚ŅŒ ĐŧиĐŊи-Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đž ĐŋĐž Đ¸ŅĐŋĐžĐģŅŒĐˇĐžĐ˛Đ°ĐŊĐ¸ŅŽ SQLModel ҁ FastAPI. ✨ + +В ŅŅ‚ĐžĐŧ Ņ€ŅƒĐēĐžĐ˛ĐžĐ´ŅŅ‚Đ˛Đĩ ĐĩŅŅ‚ŅŒ Ņ€Đ°ĐˇĐ´ĐĩĐģ Đž Ņ‚ĐĩŅŅ‚Đ¸Ņ€ĐžĐ˛Đ°ĐŊии SQL-йаС даĐŊĐŊҋ҅. 😎 diff --git a/docs/ru/docs/index.md b/docs/ru/docs/index.md index a9546cf1e..1fcc9ea9d 100644 --- a/docs/ru/docs/index.md +++ b/docs/ru/docs/index.md @@ -1,4 +1,4 @@ -# FastAPI +# FastAPI { #fastapi } - -

- FastAPI -

-

- Ìlànà wáēšĖáēšĖbÚ FastAPI, iášŖáēšĖ gíga, Ãŗ ráģrÚn lÃĄti káģĖ€, o yÃĄra lÃĄti kÃŗÃ˛dÚ, Ãŗ sÃŦ ášŖetÃĄn fÃēn iášŖeláģpáģ ní lílo -

-

- - Test - - - Coverage - - - Package version - - - Supported Python versions - -

- ---- - -**ÀkáģsíláēšĖ€**: https://fastapi.tiangolo.com - -**Orisun KÃŗÃ˛dÚ**: https://github.com/fastapi/fastapi - ---- - -FastAPI jáēšĖ ÃŦgbàlÃŗdÊ, tí Ãŗ yÃĄra (iášŖáēš-giga), ÃŦlànà wáēšĖáēšĖbÚ fÃēn kikáģ Ã wáģn API páēšĖ€lÃē Python èyí tí Ãŗ da lori àwáģn ÃŦtáģĖkasí àmÃŦ irÃēfáēšĖ Python. - -Àwáģn áēšya pàtàkÃŦ ni: - -* **Ó yÃĄra**: IášŖáēš tí Ãŗ ga pÃēpáģĖ€, tí Ãŗ wa ni ibamu páēšĖ€lÃē **NodeJS** àti **Go** (áģpáēš si Starlette àti Pydantic). [áģŒkan nínÃē àwáģn ÃŦlànà Python ti o yÃĄra jÚláģ ti o wa](#isesi). -* **Ó yÃĄra lÃĄti kÃŗÃ˛dÚ**: O mu iyara páģ si lÃĄti káģ Ã wáģn áēšya tuntun kÃŗÃ˛dÚ nipasáēš "Igba ÃŦdÃĄ áģgáģĖrÚn-Ãēn" (i.e. 200%) si "áģĖ€áģĖdÃērÃēn ÃŦdÃĄ áģgáģĖrÚn-Ãēn" (i.e. 300%). -* **ÀÃŦtáģĖ kÊkerÊ**: O n din aášŖiášŖe ku bi áģgbon ÃŦdÃĄ áģgáģĖrÚn-Ãēn (i.e. 40%) ti eda eniyan (oášŖiášŖáēš kÃŗÃ˛dÚ) fa. * -* **áģŒgbáģĖn àti ÃŦmáģĖ€**: Atiláēšyin olootu nla. Ìparí nibi gbogbo. ÀkÃŗkÃ˛ díáēšĖ€ nipa wíwÃĄ ibi tí ÃŦášŖÃ˛ro kÃŗÃ˛dÚ wà. -* **Iráģrun**: A káģ kí Ãŗ le ráģrun lÃĄti lo àti lÃĄti káģ áēškáģ nínÃē rè. Ó mÃĄa fÃēn áģ ní àkÃŗkÃ˛ díáēšĖ€ lÃĄtÄą ka àkáģsíláēš. -* **Ó kÃēkurÃē ní kikáģ**: Ó dín àtÃēnkáģ Ã ti àtÃēntÃ˛ kÃŗÃ˛dÚ kÚ. ÌkÊde Ã ášŖÃ yàn káģĖ€áģĖ€kan nínÃē ráēšĖ€ ní áģĖ€páģĖ€láģpáģĖ€ àwáģn ÃŦlÃ˛. O ášŖe iranláģwáģ lÃĄti mÃĄ ášŖe ní áģĖ€páģĖ€láģpáģĖ€ Ã ášŖÃŦášŖe. -* **Ó lÃĄgbÃĄra**: Ó ń ášŖe àgbÊjÃĄde kÃŗÃ˛dÚ tí Ãŗ ášŖetÃĄn fÃēn ÃŦášŖeláģĖpáģĖ€. PáēšĖ€lÃē àkáģsíláēšĖ€ tí Ãŗ mÃĄa ášŖÃ làyÊ ara ráēšĖ€ fÃēn áēš ní ÃŦbÃĄášŖepáģĖ€ alÃĄdÃ ÃĄášŖiášŖáēšĖ páēšĖ€lÃē rè. -* **AjohunÅĄe/ÌtáģĖkasí**: Ó da lori (àti ibamu ni kikun páēšĖ€lÃē) àwáģn ÃŦmáģ ajohunÅĄe/ÃŦtáģĖkasí fÃēn àwáģn API: OpenAPI (èyí tí a máģ táēšláēš si Swagger) àti JSON Schema. - -* iášŖiro yi da lori àwáģn idanwo tí áēšgbáēš ÃŦdàgbàsÃŗkè FastAPI ášŖe, nígbàtí wáģn káģ Ã wáģn ohun elo iášŖeláģpáģ kÃŗÃ˛dÚ páēšĖ€lÃē ráēš. - -## Àwáģn onígbáģĖ€wáģĖ - - - -{% if sponsors %} -{% for sponsor in sponsors.gold -%} - -{% endfor -%} -{%- for sponsor in sponsors.silver -%} - -{% endfor %} -{% endif %} - - - -Àwáģn onígbáģĖ€wáģĖ míràn - -## Àwáģn ero àti èsÃŦ - -"_[...] MÃ˛ ń lo **FastAPI** pÃēpáģĖ€ ní láēšĖnu àÃŦpáēšĖ yÃŦí. [...] Mo n gbero lÃĄti lo o páēšĖ€lÃē àwáģn áēšgbáēš mi fÃēn gbogbo iášŖáēš **ML wa ni Microsoft**. Diáēš nínÃē wáģn ni afikun ti ifileláēš Ã wáģn áēšya ara ti áģja **Windows** wa páēšĖ€lÃē àwáģn ti **Office**._" - -
Kabir Khan - Microsoft (ref)
- ---- - -"_A gba àwáģn ohun èlÃ˛ ÃŦwÊ afáģwáģkáģ **FastAPI** tí kÃ˛ yí padà lÃĄti ášŖáēšĖ€dÃĄ olÚpín **REST** tí a lè bÊèrè láģĖwáģĖ ráēšĖ€ lÃĄti gba **àsáģtáēšĖláēšĖ€**. [fÃēn Ludwig]_" - -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
- ---- - -"_**Netflix** ni inudidun lÃĄti kede itusiláēš orisun kÃŗÃ˛dÚ ti ÃŦlànà iášŖáģkan **iášŖakoso ÃŒášŖÃ˛ro** wa: **ÌfirÃĄnášŖáēšĖ**! [a káģ páēšĖ€lÃē **FastAPI**]_" - -
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
- ---- - -"_InÃē mi dÚn pÃēpáģĖ€ nípa **FastAPI**. Ó mÃē inÃē áēšnÃŦ dÚn pÃēpáģĖ€!_" - -
Brian Okken - Python Bytes podcast host (ref)
- ---- - -"_Ní tÃ˛ÃŗtáģĖ, ohun tí o káģ dÃĄra Ãŗ sÃŦ tÃēn dÃĄn. Ní áģĖ€páģĖ€láģpáģĖ€ áģĖ€nà, ohun tí mo fáēšĖ kí **Hug** jáēšĖ nÃŦyáēšn - Ãŗ wÃēni lÃŗrí gan-an lÃĄti rí áēšnÃŦkan tí Ãŗ káģĖ nĮškan bí èyí._" - -
Timothy Crosley - Hug creator (ref)
- ---- - -"_Ti o ba n wa lÃĄti káģ áģkan **ÃŦlànà igbalode** fÃēn kikáģ Ã wáģn REST API, ášŖayáēšwo **FastAPI** [...] Ó yÃĄra, Ãŗ ráģrÚn lÃĄti lÃ˛, Ãŗ sÃŦ ráģrÚn lÃĄti káģĖ[...]_" - -"_A ti yipada si **FastAPI** fÃēn **APIs** wa [...] Mo lÊrÃ˛ pÊ wà ÃĄ fáēšĖràn ráēšĖ€ [...]_" - -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
- ---- - -"_Ti áēšnikáēšni ba n wa lÃĄti káģ iášŖeláģpáģ API páēšĖ€lÃē Python, èmi yÃŗÃ˛ ášŖe'dÃērÃŗ fÃēn **FastAPI**. Ó jáēšĖ ohun tí **àgbÊkaláēšĖ€ ráēšĖ€ láēšĖwà**, **Ãŗ ráģrÚn lÃĄti lÃ˛** àti wipe Ãŗ ni **ÃŦwáģĖ€n gíga**, o tí dí **báģtini paati** nínÃē alakáģkáģ API ÃŦdàgbàsÃŗkè kikáģ fÃēn wa, àti pe o ni ipa lori adaášŖiášŖáēš Ã ti àwáģn iášŖáēš gáēšĖgáēšĖ bíi OnímáģĖ€-áēšĖ€ráģ TAC tí Ãŗrí ÍńtÃĄnáēšĖáēšĖ€tÃŦ_" - -
Deon Pillsbury - Cisco (ref)
- ---- - -## **Typer**, FastAPI ti CLIs - - - -Ti o ba n káģ ohun èlÃ˛ CLI lÃĄti ášŖeÊ láģ nínÃē ohun èlÃ˛ lori ebute káģmputa dipo API, ášŖayáēšwo **Typer**. - -**Typer** jáēšĖ àbÃērÃ˛ ÃŦyÃĄ FastAPI kÊkerÊ. Àti pÊ wáģĖn káģĖ lÃĄti jáēšĖ **FastAPI ti CLIs**. âŒ¨ī¸ 🚀 - -## ÈrÃ˛jà - -FastAPI dÃērÃŗ lÃŗrí àwáģn èjÃŦkÃĄ tí àwáģn Ã˛míràn: - -* Starlette fÃēn àwáģn áēšĖ€yà ayÊlujÃĄra. -* Pydantic fÃēn àwáģn áēšĖ€yà àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛. - -## Fifi sÃŗrí áēšráģ - -
- -```console -$ pip install fastapi - ----> 100% -``` - -
-Iwáģ yÃŗÃ˛ tÃēn nílÃ˛ olupin ASGI, fÃēn iášŖeláģpáģ bii Uvicorn tabi Hypercorn. - -
- -```console -$ pip install "uvicorn[standard]" - ----> 100% -``` - -
- -## Àpáēšáēšráēš - -### ášĸáēšĖ€dÃĄ ráēšĖ€ - -* ášĸáēšĖ€dÃĄ fÃĄÃŦlÃŦ `main.py (èyí tíí ášŖe, akáģkáģ.py)` páēšĖ€lÃē: - -```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} -``` - -
-Tàbí lÃ˛ async def... - -Tí kÃŗÃ˛dÚ ráēšĖ€ bÃĄ ń lÃ˛ `async` / `await`, lÃ˛ `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} -``` - -**Akiyesi**: - -Tí o kÃ˛ bÃĄ máģĖ€, ášŖÃ yáēšĖ€wÃ˛ ibi tí a ti ní _"In a hurry?"_ (i.e. _"Ní kÃ­ÃĄkÃ­ÃĄ?"_) nípa `async` and `await` nínÃē àkáģsíláēšĖ€. - -
- -### Mu ášŖiášŖáēš - -MÃē olupin ášŖiášŖáēš páēšĖ€lÃē: - -
- -```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. -``` - -
- -
-Nipa aášŖáēš kÃŗÃ˛dÚ nÃĄÃ  uvicorn main:app --reload... - -Ã€ášŖáēš `uvicorn main:app` ń táģĖka sí: - -* `main`: fÃĄÃŦlÃŦ nÃĄÃ  'main.py' (Python "module"). -* `app` jáēš object( i.e. nĮškan) tí a ášŖáēšĖ€dÃĄ nínÃē `main.py` páēšĖ€lÃē ilà `app = FastAPI()`. -* `--reload`: èyí yÃŗÃ˛ jáēšĖ ki olupin tÃēn báēšĖ€ráēšĖ€ láēšĖhÃŦn àwáģn àyípadà kÃŗÃ˛dÚ. JáģĖ€wáģĖ, ášŖe èyí fÃēn ÃŦdàgbàsÃŗkè kÃŗÃ˛dÚ nÃŦkan, mÃĄ ášŖe Ê ášŖe lori àgbÊjÃĄde kÃŗÃ˛dÚ tabi fÃēn iášŖeláģpáģ kÃŗÃ˛dÚ. - - -
- -### ášĸayáēšwo ráēš - -ášĸii aášŖÃ wÃĄkiri káģĖ€ĮšpÃētà ráēš ni http://127.0.0.1:8000/items/5?q=somequery. - -Ìwáģ yÃŗÃ˛ sÃŦ rí ÃŦdÃĄhÚn JSON bíi: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -O tí ášŖáēšĖ€dÃĄ API èyí tí yÃŗÃ˛: - -* Gbà àwáģn ÃŦbÊèrè HTTP ni àwáģn _ipa áģĖ€nà_ `/` àti `/items/{item_id}`. -* Èyí tí àwáģn _ipa áģĖ€nà_ (i.e. _paths_) mÊjèèjÃŦ gbà àwáģn iášŖáēš `GET` (a tun máģ si _àwáģn áģna_ HTTP). -* Èyí tí _ipa áģĖ€nà_ (i.e. _paths_) `/items/{item_id}` ní _àwáģn ohun-ini ipa áģĖ€nà_ tí Ãŗ yáēš kí Ãŗ jáēšĖ `int` i.e. `ÒĮ¸KÀ`. -* Èyí tí _ipa áģĖ€nà_ (i.e. _paths_) `/items/{item_id}` ní Ã ášŖÃ yàn `str` _àwáģn ohun-ini_ (i.e. _query parameter_) `q`. - -### ÌbÃĄášŖepáģĖ€ àkáģsíláēšĖ€ API - -Ní bÃĄyÃŦí, láģ sí http://127.0.0.1:8000/docs. - -LáēšĖyÃŦn nÃĄÃ , iwáģ yÃŗÃ˛ rí ÃŦdÃĄhÚn àkáģsíláēšĖ€ API tí Ãŗ jáēšĖ ÃŦbÃĄášŖepáģĖ€ alaifáģwáģyi/alÃĄdÃ ÃĄášŖiášŖáēšĖ (tí a pÃ¨ášŖÃ¨ nípaášŖáēšĖ€ Swagger UI): - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) - -### ÌdàkejÃŦ àkáģsíláēšĖ€ API - -Ní bÃĄyÃŦí, láģ sí http://127.0.0.1:8000/redoc. - -Wà ÃĄ rí àwáģn àkáģsíláēšĖ€ alÃĄdÃ ÃĄášŖiášŖáēšĖ mÃŦíràn (tí a pese nipasáēš ReDoc): - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) - -## Àpáēšáēšráēš ÃŦgbÊsÃŗkè mÃŦíràn - -Ní bÃĄyÃŦí ášŖe àtÃēnášŖe fÃĄÃŦlÃŦ `main.py` lÃĄti gba kÃŗkÃŗ èsÃŦ lÃĄti inÃē ÃŦbÊèrè `PUT`. - -Ní bÃĄyÃŦí, ášŖe ÃŦkÊde kÃŗkÃŗ èsÃŦ API nínÃē kÃŗÃ˛dÚ ráēš nipa lílo àwáģn ÃŦtáģĖkasí àmÃŦ irÃēfáēšĖ Python, áģpáēšĖ pàtàkÃŦsi sí 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} -``` - -Olupin yÃŗÃ˛ tÃēn ášŖe àtÃēnášŖe laifáģwáģyi/alÃĄdÃ ÃĄášŖiášŖáēšĖ (nítorí wípÊ Ãŗ se àfikÃēn `-reload` si Ã ášŖáēš kÃŗÃ˛dÚ `uvicorn` lÃŗkè). - -### ÌbÃĄášŖepáģĖ€ ÃŦgbÊsÃŗkè àkáģsíláēšĖ€ API - -Ní bÃĄyÃŦí, láģ sí http://127.0.0.1:8000/docs. - -* ÌbÃĄášŖepáģĖ€ àkáģsíláēšĖ€ API yÃŗÃ˛ ášŖe imudojuiwáģn àkáģsíláēšĖ€ API laifáģwáģyi, páēšĖ€lÃē kÃŗkÃŗ èsÃŦ ÃŦdÃĄhÚn API tuntun: - -![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) - -* Táēš báģtini "Gbiyanju ráēš" i.e. "Try it out", yÃŗÃ˛ gbà áģĖ lÃĄÃ yè lÃĄti jáēšĖ kí Ãŗ táēšĖ àlàyÊ tí Ãŗ nílÃ˛ kí Ãŗ le sáģĖ€ráģĖ€ tààrà páēšĖ€lÃē API: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) - -* Láēšhinna táēš báģtini "ášĸiášŖe" i.e. "Execute", olÚmÃēlÃ˛ (i.e. user interface) yÃŗÃ˛ sáģráģ páēšĖ€lÃē API ráēš, yÃŗÃ˛ ášŖe afiranášŖáēš Ã wáģn èrÃ˛jà, pÃ ÃĄpÃ ÃĄ jÚláģ yÃŗÃ˛ gba àwáģn àbÃĄjÃĄde yÃŗÃ˛ si ášŖafihan wáģn loju ÃŦbÃ˛jÃē: - -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) - -### ÌdàkejÃŦ ÃŦgbÊsÃŗkè àkáģsíláēšĖ€ API - -Ní bÃĄyÃŦí, láģ sí http://127.0.0.1:8000/redoc. - -* ÌdàkejÃŦ àkáģsíláēšĖ€ API yÃŗÃ˛ ášŖ'afihan ÃŦbÊèrè èrÃ˛jà/pàrÃĄmítà tuntun àti kÃŗkÃŗ èsÃŦ ti API: - -![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) - -### ÀtÃēnyáēšĖ€wÃ˛ - -Ni akopáģ, ÃŦwáģ yÃŗÃ˛ kÊde ni **kete** àwáģn iru èrÃ˛jà/pàrÃĄmítà, kÃŗkÃŗ èsÃŦ API, abbl (i.e. àti báēšbáēš láģ), bi àwáģn èrÃ˛jà iášŖáēš. - -O ášŖe ÃŦyáēšn páēšĖ€lÃē irÃēfáēšĖ àmÃŦ ÃŦtáģĖkasí ÃŦgbàlÃŗdÊ Python. - -O Ã˛ nílÃ˛ lÃĄti káģĖ síńtÃĄÃ sÃŦ tuntun, ÃŦlànà tàbí áģĖ€wáģĖ kílÃĄÃ sÃŦ kan pàtÃŗ, abbl (i.e. àti báēšbáēš láģ). - -ÌtáģĖkasí **Python** - -FÃēn àpáēšáēšráēš, fÃēn `int`: - -```Python -item_id: int -``` - -tàbí fÃēn àwÃ˛ášŖe `Item` tí Ãŗ nira díáēšĖ€ síi: - -```Python -item: Item -``` - -... àti páēšĖ€lÃē ÃŦkÊde kan ášŖoášŖo yáēšn ÃŦwáģ yÃŗÃ˛ gbà: - -* Atiláēšyin olootu, páēšĖ€lÃē: - * Pipari. - * ÀyáēšĖ€wÃ˛ irÃēfáēšĖ àmÃŦ ÃŦtáģĖkasí. -* ÌfáģwáģĖsí àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛ (i.e. data): - * AášŖiášŖe alaifáģwáģyi/alÃĄdÃ ÃĄášŖiášŖáēšĖ àti aášŖiášŖe ti Ãŗ hàn kedere nígbàtí àwáģn àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛ (i.e. data) kÃ˛ wulo tabi tí kÃ˛ fáēšsáēšĖ€ mÃēláēšĖ€. - * ÌfáģwáģĖsí fÃēn ohun elo JSON tí Ãŗ jÃŦn gan-an. -* Ìyípadà tí input àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛: tí Ãŗ wà lÃĄti náēštiwáģáģki si àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛ àti irÃēfáēšĖ àmÃŦ ÃŦtáģĖkasí Python. Ó ń ka lÃĄti: - * JSON. - * èrÃ˛jà áģĖ€nà tí Ã˛ gbÊ gbà. - * èrÃ˛jà ÃŦbÊèrè. - * Àwáģn KÃēkÃŦ - * Àwáģn ÀkáģlÊ - * Àwáģn Fáģáģmu - * Àwáģn FÃĄÃŦlÃŦ -* Ìyípadà èsÃŦ àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛: yíyípadà lÃĄti àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛ àti irÃēfáēšĖ àmÃŦ ÃŦtáģĖkasí Python si náēštiwáģáģki (gáēšĖgáēšĖ bí JSON): - * Yí irÃēfáēšĖ àmÃŦ ÃŦtáģĖkasí padà (`str`, `int`, `float`, `bool`, `list`, abbl i.e. àti bèbè lÃŗ). - * Àwáģn ohun èlÃ˛ `datetime`. - * Àwáģn ohun èlÃ˛ `UUID`. - * Àwáģn awoášŖáēšĖ ibi ÃŦpamáģĖ àkÃŗjáģf'ÃĄyáēšĖ€wÃ˛. - * ...àti áģĖ€páģĖ€láģpáģĖ€ díáēšĖ€ síi. -* ÌbÃĄášŖepáģĖ€ àkáģsíláēšĖ€ API alÃĄdÃ ÃĄášŖiášŖáēšĖ, páēšĖ€lÃē ÃŦdàkejÃŦ àgbÊkaláēšĖ€-àwáģn-olÚmÃēlÃ˛ (i.e user interfaces) mÊjÃŦ: - * ÀgbÊkaláēšĖ€-olÚmÃēlÃ˛ Swagger. - * ReDoc. - ---- - -Nisinsin yi, tí Ãŗ padà sí àpáēšáēšráēš ti táēšĖláēšĖ€, **FastAPI** yÃŗÃ˛: - -* FáģwáģĖ sí i pÊ `item_id` wà nínÃē áģĖ€nà ÃŦbÊèrè HTTP fÃēn `GET` àti `PUT`. -* FáģwáģĖ sí i pÊ `item_id` jáēšĖ irÃēfáēšĖ àmÃŦ ÃŦtáģĖkasí `int` fÃēn ÃŦbÊèrè HTTP `GET` àti `PUT`. - * Tí kÃŦí bÃĄ ášŖe báēš, oníbÃ ÃĄrà yÃŗÃ˛ ríi Ã ášŖÃŦášŖe tí Ãŗ wÃēlÃ˛, kedere. -* ášĸàyáēšĖ€wÃ˛ bÃŗyÃĄ ÃŦbÊèrè Ã ášŖÃ yàn pàrÃĄmítà kan wà tí orÃēkáģ ráēšĖ€ ń jáēšĖ `q` (gáēšĖgáēšĖ bíi `http://127.0.0.1:8000/items/foo?q=somequery`) fÃēn ÃŦbÊèrè HTTP `GET`. - * Bí wáģĖn ášŖe kÊde pàrÃĄmítà `q` páēšĖ€lÃē `= None`, Ãŗ jáēšĖ Ã ášŖÃ yàn (i.e optional). - * LÃĄÃŦsí `None` yÃŗÃ˛ nílÃ˛ (gáēšĖgáēšĖ bí kÃŗkÃŗ èsÃŦ ÃŦbÊèrè HTTP ášŖe wà páēšĖ€lÃē `PUT`). -* FÃēn àwáģn ÃŦbÊèrè HTTP `PUT` sí `/items/{item_id}`, kà kÃŗkÃŗ èsÃŦ ÃŦbÊèrè HTTP gáēšĖgáēšĖ bí JSON: - * ášĸàyáēšĖ€wÃ˛ pÊ Ãŗ ní àbÚdÃĄ tí Ãŗ nílÃ˛ èyí tíí ášŖe `name` i.e. `orÃēkáģ` tí Ãŗ yáēš kí Ãŗ jáēšĖ `str`. - * ášĸàyáēšĖ€wÃ˛ pÊ Ãŗ ní àbÚdÃĄ tí Ãŗ nílÃ˛ èyí tíí ášŖe `price` i.e. `iye` tí Ãŗ gbáģĖdáģĖ€ jáēšĖ `float`. - * ášĸàyáēšĖ€wÃ˛ pÊ Ãŗ ní àbÚdÃĄ Ã ášŖÃ yàn `is_offer`, tí Ãŗ yáēš kí Ãŗ jáēšĖ `bool`, tí Ãŗ bÃĄ wà níbáēšĖ€. - * Gbogbo èyí yÃŗÃ˛ tÃēn ášŖiášŖáēšĖ fÃēn àwáģn ohun èlÃ˛ JSON tí Ãŗ jÃŦn gidi gan-an. -* YÃŦí padà lÃĄti àti sí JSON lai fi áģwáģĖ yi. -* ášĸe àkáģsíláēšĖ€ ohun gbogbo páēšĖ€lÃē OpenAPI, èyí tí yÃŗÃ˛ wà ní lílo nípaášŖáēšĖ€: - * Àwáģn ètÃ˛ àkáģsíláēšĖ€ ÃŦbÃĄášŖepáģĖ€. - * AlÃĄdÃ ÃĄášŖiášŖáēšĖ oníbÃĄrà èlètÃ˛ tíí ášŖáēšĖ€dÃĄ kÃŗÃ˛dÚ, fÃēn áģĖ€páģĖ€láģpáģĖ€ àwáģn èdè. -* Pese àkáģsíláēšĖ€ Ã˛ní ÃŦbÃĄášŖepáģĖ€ ti àwáģn àgbÊkaláēšĖ€ ayÊlujÃĄra mÊjÃŦ tààrà. - ---- - -A ń ášŖáēšĖ€ášŖáēšĖ€ ń mÃē áēšyáēš báģĖ làpÃ˛ ní, ášŖÃšgbáģĖn Ãŗ ti ni Ã˛ye bí gbogbo ráēšĖ€ ášŖe ń ášŖiášŖáēšĖ. - -Gbiyanju lÃĄti yí ÃŦlà padà páēšĖ€lÃē: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...lÃĄti: - -```Python - ... "item_name": item.name ... -``` - -...ášŖÃ­: - -```Python - ... "item_price": item.price ... -``` - -.. kí o sÃŦ wo bí olÃŗÃ˛tÃē ráēš yÃŗÃ˛ ášŖe parí àwáģn àbÚdÃĄ nÃĄÃ  fÃēnra ráēšĖ€, yÃŗÃ˛ sÃŦ máģ irÃēfáēšĖ wáģn: - -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) - -FÃēn àpáēšáēšráēš pípÊ síi páēšĖ€lÃē àwáģn àbÚdÃĄ mÃŦíràn, wo ÌdÃĄniláēšĖkáģĖ€áģĖ - ÌtáģĖsáģĖnà OlÚmÃēlÃ˛. - -**Itaniji gáēšĖgáēšĖ bí isáģ'ye**: ÃŦdÃĄniláēšĖkáģĖ€áģĖ - itáģsáģna olÚmÃēlÃ˛ páēšĖ€lÃē: - -* ÌkÊde Ã ášŖÃ yàn **pàrÃĄmítà** lÃĄti àwáģn oriášŖiriášŖi ibÃ˛míràn gáēšĖgáēšĖ bíi: àwáģn **àkáģlÊ èsÃŦ API**, **kÃēkÃŦ**, **ààyè fáģáģmu**, àti **fÃĄÃŦlÃŦ**. -* Bíi Ãŗ ášŖe lÊ ášŖÃ¨tÃ˛ **àwáģn ÃŦdíwáģĖ ÃŦfáģwáģĖsí** bí `maximum_length` tàbí `regex`. -* Ó lÃĄgbÃĄra pÃēpáģĖ€ Ãŗ sÃŦ ráģrÚn lÃĄti lo ètÃ˛ **ÀfikÃēn ÌgbáēšĖkáēšĖ€lÊ KÃŗÃ˛dÚ**. -* ÀàbÃ˛ àti ÃŦfáģwáģĖsowáģĖpáģĖ€, páēšĖ€lÃē àtÃŦláēšĖyÃŦn fÃēn **OAuth2** páēšĖ€lÃē **àmÃŦ JWT** àti **HTTP Ipiláēš ÃŦfáģwáģĖsowáģĖpáģĖ€**. -* Àwáģn ÃŦlànà ÃŦláģsíwÃĄjÃē (ášŖÃšgbáģĖn tí Ãŗ ráģrÚn bÃĄkan nÃĄÃ ) fÃēn ÃŦkÊde **àwáģn àwÃ˛ášŖe JSON tÃŗ jinláēšĖ€** (áģpáēšĖ pàtàkÃŦsi sí Pydantic). -* IášŖáģpáģ **GraphQL** páēšĖ€lÃē Strawberry àti àwáģn ohun èlÃ˛ ÃŦwÊ kÃŗÃ˛dÚ afáģwáģkáģ mÃŦíràn tí kÃ˛ yí padà. -* áģŒpáģláģpáģ Ã wáģn àfikÃēn àwáģn áēšĖ€yà (áģpáēšĖ pàtàkÃŦsi sí Starlette) bí: - * **WebSockets** - * àwáģn ÃŦdÃĄnwÃ˛ tí Ãŗ ráģrÚn pÃēpáģĖ€ lÃŗrí HTTPX àti `pytest` - * **CORS** - * **Cookie Sessions** - * ...àti síwÃĄjÃē síi. - -## ÃŒášŖesí - -Àwáģn àlÃĄ TechEmpower fi hàn pÊ **FastAPI** ń ášŖiášŖáēšĖ lÃĄbáēšĖ Uvicorn gáēšĖgáēšĖ bí áģĖ€kan lÃĄra àwáģn ÃŦlànà Python tí Ãŗ yÃĄra jÚláģ tí Ãŗ wà, ní ÃŦsàláēšĖ€ Starlette àti Uvicorn fÃēnra wáģn (tí FastAPI ń lÃ˛ fÃēnra ráēšĖ€). (*) - -LÃĄti ní Ã˛ye síi nípa ráēšĖ€, wo abala àwáģn ÀlÃĄ. - -## Ã€ášŖÃ yàn Àwáģn ÀfikÃēn ÌgbáēšĖkáēšĖ€lÊ KÃŗÃ˛dÚ - -Èyí tí Pydantic ń lÃ˛: - -* email-validator - fÃēn ifáģwáģsi ímeèlÃŦ. -* pydantic-settings - fÃēn ètÃ˛ ÃŦsàkÃŗso. -* pydantic-extra-types - fÃēn àfikÃēn orÃ­ášŖi lÃĄti láģ páēšĖ€lÃē Pydantic. - -Èyí tí Starlette ń lÃ˛: - -* httpx - NílÃ˛ tí Ãŗ bÃĄ fáēšĖ lÃĄti láģ `TestClient`. -* jinja2 - NílÃ˛ tí Ãŗ bÃĄ fáēšĖ lÃĄti láģ iášŖeto awoášŖe aiyipada. -* python-multipart - NílÃ˛ tí Ãŗ bÃĄ fáēšĖ lÃĄti ášŖe àtÃŦláēšĖyÃŦn fÃēn "àyáēšĖ€wÃ˛" fáģáģmu, páēšĖ€lÃē `request.form()`. -* itsdangerous - NílÃ˛ fÃēn àtÃŦláēšĖyÃŦn `SessionMiddleware`. -* pyyaml - NílÃ˛ fÃēn àtÃŦláēšĖyÃŦn Starlette's `SchemaGenerator` (Ãŗ ášŖe ášŖe kí Ãŗ mÃĄ nílÃ˛ ráēšĖ€ fÃēn FastAPI). - -Èyí tí FastAPI / Starlette ń lÃ˛: - -* uvicorn - FÃēn olupin tí yÃŗÃ˛ sáēšĖ àmÃēyáēš Ã ti tí yÃŗÃ˛ ášŖe ÃŦpèsè fÃēn iášŖáēšĖ ráēš tàbí ohun èlÃ˛ ráēš. -* orjson - NílÃ˛ tí Ãŗ bÃĄ fáēšĖ lÃĄti láģ `ORJSONResponse`. -* ujson - NílÃ˛ tí Ãŗ bÃĄ fáēšĖ lÃĄti láģ `UJSONResponse`. - -Ó lè fi gbogbo àwáģn wáģĖ€nyí sÃŗrí áēšráģ páēšĖ€lÃē `pip install "fastapi[all]"`. - -## Iwe-aášŖáēš - -IášŖáēšĖ yÃŦí ni iwe-aášŖáēš lÃĄbáēšĖ àwáģn Ã˛fin tí iwe-aášŖáēš MIT. diff --git a/docs/yo/mkdocs.yml b/docs/yo/mkdocs.yml deleted file mode 100644 index de18856f4..000000000 --- a/docs/yo/mkdocs.yml +++ /dev/null @@ -1 +0,0 @@ -INHERIT: ../en/mkdocs.yml diff --git a/docs/zh-hant/docs/async.md b/docs/zh-hant/docs/async.md index 6ab75d2ab..09e2bf994 100644 --- a/docs/zh-hant/docs/async.md +++ b/docs/zh-hant/docs/async.md @@ -381,7 +381,7 @@ Starlette īŧˆå’Œ **FastAPI**īŧ‰ 是åŸēæ–ŧ Gevent。äŊ†é€™äē›į¨‹åŧįĸŧčĻæ›´é›ŖäģĨį†č§Ŗã€čĒŋčŠĻå’Œæ€č€ƒã€‚ -在čŧƒčˆŠįš„ NodeJS / į€čĻŊ器 JavaScript 中īŧŒäŊ æœƒäŊŋį”¨ã€Œå›žå‘ŧ」īŧŒé€™å¯čƒŊæœƒå°Žč‡´å›žå‘ŧåœ°į„ã€‚ +在čŧƒčˆŠįš„ NodeJS / į€čĻŊ器 JavaScript 中īŧŒäŊ æœƒäŊŋį”¨ã€Œå›žå‘ŧ」īŧŒé€™å¯čƒŊæœƒå°Žč‡´â€œå›žå‘ŧåœ°į„â€ã€‚ ## å”į¨‹ diff --git a/docs/zh-hant/docs/deployment/cloud.md b/docs/zh-hant/docs/deployment/cloud.md index 29ebe3ff5..426937d3e 100644 --- a/docs/zh-hant/docs/deployment/cloud.md +++ b/docs/zh-hant/docs/deployment/cloud.md @@ -10,8 +10,4 @@ é€™äšŸåą•įžäē†äģ–們對 FastAPI 和å…ļ**į¤žįž¤**īŧˆåŒ…æ‹ŦäŊ īŧ‰įš„įœŸæ­Ŗæ‰ŋčĢžīŧŒäģ–們不僅希望į‚ēäŊ æäž›**å„ĒčŗĒįš„æœå‹™**īŧŒé‚„希望įĸēäŋäŊ æ“æœ‰ä¸€å€‹**艝åĨŊ且åĨåēˇįš„æĄ†æžļ**īŧšFastAPIã€‚đŸ™‡ -äŊ å¯čƒŊæœƒæƒŗå˜—čŠĻäģ–å€‘įš„æœå‹™īŧŒäģĨ下有äģ–å€‘įš„æŒ‡å—īŧš - -* Platform.sh -* Porter -* Coherence +äŊ å¯čƒŊæœƒæƒŗå˜—čŠĻäģ–å€‘įš„æœå‹™īŧŒäģĨ下有äģ–å€‘įš„æŒ‡å—. diff --git a/docs/zh-hant/docs/index.md b/docs/zh-hant/docs/index.md index 81d99ede4..168ad5c4c 100644 --- a/docs/zh-hant/docs/index.md +++ b/docs/zh-hant/docs/index.md @@ -81,7 +81,7 @@ FastAPI æ˜¯ä¸€å€‹įžäģŖã€åŋĢ速īŧˆéĢ˜æ•ˆčƒŊīŧ‰įš„ web æĄ†æžļīŧŒį”¨æ–ŧ Python "_我對 **FastAPI** 興åĨŽåž—不垗äē†ã€‚åރå¤Ē有čļŖäē†īŧ_" -
Brian Okken - Python Bytes podcast host (ref)
+
Brian Okken - Python Bytes podcast host (ref)
--- @@ -95,7 +95,7 @@ FastAPI æ˜¯ä¸€å€‹įžäģŖã€åŋĢ速īŧˆéĢ˜æ•ˆčƒŊīŧ‰įš„ web æĄ†æžļīŧŒį”¨æ–ŧ Python "_æˆ‘å€‘įš„ **APIs** 厞į”šį”¨ **FastAPI** [...] æˆ‘æƒŗäŊ æœƒå–œæ­Ąåރ [...]_" -
Ines Montani - Matthew Honnibal - Explosion AI å‰ĩčžĻäēē - spaCy creators (ref) - (ref)
+
Ines Montani - Matthew Honnibal - Explosion AI å‰ĩčžĻäēē - spaCy creators (ref) - (ref)
--- diff --git a/docs/zh/docs/async.md b/docs/zh/docs/async.md index 9e6962eb1..4028ed51a 100644 --- a/docs/zh/docs/async.md +++ b/docs/zh/docs/async.md @@ -383,7 +383,7 @@ Starlette īŧˆå’Œ **FastAPI**īŧ‰ 是åŸēäēŽ Gevent。äŊ†äģŖį įš„į†č§Ŗã€č°ƒč¯•å’Œæ€č€ƒéƒŊčĻå¤æ‚čŽ¸å¤šã€‚ -在äģĨå‰į‰ˆæœŦįš„ NodeJS / æĩč§ˆå™¨ JavaScript 中īŧŒäŊ äŧšäŊŋᔍ"å›žč°ƒ"īŧŒå› æ­¤äšŸå¯čƒŊå¯ŧč‡´å›žč°ƒåœ°į‹ąã€‚ +在äģĨå‰į‰ˆæœŦįš„ NodeJS / æĩč§ˆå™¨ JavaScript 中īŧŒäŊ äŧšäŊŋᔍ"å›žč°ƒ"īŧŒå› æ­¤äšŸå¯čƒŊå¯ŧč‡´â€œå›žč°ƒåœ°į‹ąâ€ã€‚ ## åį¨‹ diff --git a/docs/zh/docs/deployment/cloud.md b/docs/zh/docs/deployment/cloud.md index b086b7b6b..8a892a560 100644 --- a/docs/zh/docs/deployment/cloud.md +++ b/docs/zh/docs/deployment/cloud.md @@ -10,7 +10,4 @@ čŋ™čĄ¨æ˜Žäē†äģ–äģŦ寚 FastAPI 及å…ļ**į¤žåŒē**īŧˆæ‚¨īŧ‰įš„įœŸæ­Ŗæ‰ŋč¯ēīŧŒå› ä¸ēäģ–äģŦ不äģ…æƒŗä¸ē您提䞛**艝åĨŊįš„æœåŠĄ**īŧŒč€Œä¸”čŋ˜æƒŗįĄŽäŋæ‚¨æ‹Ĩ有一ä¸Ē**艝åĨŊ且åĨåēˇįš„æĄ†æžļ**īŧšFastAPI。 🙇 -您可čƒŊæƒŗå°č¯•äģ–äģŦįš„æœåŠĄåšļ阅č¯ģäģ–äģŦįš„æŒ‡å—īŧš - -* Platform.sh -* Porter +您可čƒŊæƒŗå°č¯•äģ–äģŦįš„æœåŠĄåšļ阅č¯ģäģ–äģŦįš„æŒ‡å—. diff --git a/docs/zh/docs/help-fastapi.md b/docs/zh/docs/help-fastapi.md index 09f37a44b..f01eb9eb5 100644 --- a/docs/zh/docs/help-fastapi.md +++ b/docs/zh/docs/help-fastapi.md @@ -22,7 +22,7 @@ ## åœ¨æŽ¨į‰šä¸Šå…ŗæŗ¨ FastAPI -在 **Twitter**Â ä¸Šå…ŗæŗ¨ @fastapi čŽˇå– **FastAPI** įš„æœ€æ–°æļˆæ¯ã€‚đŸĻ +在 **X (Twitter)**Â ä¸Šå…ŗæŗ¨ @fastapi čŽˇå– **FastAPI** įš„æœ€æ–°æļˆæ¯ã€‚đŸĻ ## 在 GitHub 上ä¸ē **FastAPI** 加星 @@ -47,19 +47,19 @@ * 在 **GitHub**Â ä¸Šå…ŗæŗ¨æˆ‘ * äē†č§Ŗå…ļ厃我创åģēįš„åŧ€æēéĄšį›ŽīŧŒæˆ–čŽ¸å¯šæ‚¨äŧšæœ‰å¸ŽåŠŠ * å…ŗæŗ¨æˆ‘äģ€äšˆæ—ļ候创åģēæ–°įš„åŧ€æēéĄšį›Ž -* 在 **Twitter**Â ä¸Šå…ŗæŗ¨æˆ‘ +* 在 **X (Twitter)**Â ä¸Šå…ŗæŗ¨æˆ‘ * å‘Šč¯‰æˆ‘æ‚¨äŊŋᔍ FastAPIīŧˆæˆ‘非常ä𐿄åŦ到čŋ™į§æļˆæ¯īŧ‰ * æŽĨæ”ļ我发布å…Ŧ告或新åˇĨå…ˇįš„æļˆæ¯ - * 您čŋ˜å¯äģĨå…ŗæŗ¨@fastapi on TwitterīŧŒčŋ™æ˜¯ä¸Ēį‹ŦįĢ‹įš„č´Ļåˇ + * 您čŋ˜å¯äģĨå…ŗæŗ¨@fastapi on X (Twitter)īŧŒčŋ™æ˜¯ä¸Ēį‹ŦįĢ‹įš„č´Ļåˇ * 在**éĸ†č‹ą**上联įŗģ我 - * æŽĨæ”ļ我发布å…Ŧ告或新åˇĨå…ˇįš„æļˆæ¯īŧˆč™Ŋį„ļæˆ‘ᔍ Twitter æ¯”čžƒå¤šīŧ‰ + * æŽĨæ”ļ我发布å…Ŧ告或新åˇĨå…ˇįš„æļˆæ¯īŧˆč™Ŋį„ļæˆ‘ᔍ X (Twitter) æ¯”čžƒå¤šīŧ‰ * 阅č¯ģ我在 **Dev.to** 或 **Medium** ä¸Šįš„æ–‡įĢ īŧŒæˆ–å…ŗæŗ¨æˆ‘ * 阅č¯ģæˆ‘įš„å…ļåŽƒæƒŗæŗ•ã€æ–‡įĢ īŧŒäē†č§Ŗæˆ‘创åģēįš„åˇĨå…ˇ * å…ŗæŗ¨æˆ‘īŧŒčŋ™æ ˇå°ąå¯äģĨ随æ—ļįœ‹åˆ°æˆ‘å‘å¸ƒįš„æ–°æ–‡įĢ  ## Tweet about **FastAPI** -Tweet about **FastAPI** čŽŠæˆ‘å’Œå¤§åŽļįŸĨ道您ä¸ēäģ€äšˆå–œæŦĸ FastAPIã€‚đŸŽ‰ +Tweet about **FastAPI** čŽŠæˆ‘å’Œå¤§åŽļįŸĨ道您ä¸ēäģ€äšˆå–œæŦĸ FastAPIã€‚đŸŽ‰ įŸĨ道有äēēäŊŋᔍ **FastAPI**īŧŒæˆ‘äŧšåžˆåŧ€åŋƒīŧŒæˆ‘ä🿃ŗįŸĨ道您ä¸ēäģ€äšˆå–œæŦĸ FastAPIīŧŒäģĨ及您在äģ€äšˆéĄšį›Ž/å“Ēäē›å…Ŧ司äŊŋᔍ FastAPIīŧŒį­‰į­‰ã€‚ diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md index 94cf8745c..680e2db50 100644 --- a/docs/zh/docs/index.md +++ b/docs/zh/docs/index.md @@ -88,7 +88,7 @@ FastAPI 是一ä¸ĒᔍäēŽæž„åģē API įš„įŽ°äģŖã€åŋĢ速īŧˆéĢ˜æ€§čƒŊīŧ‰įš„ web æĄ† 「_**FastAPI** čŽŠæˆ‘å…´åĨ‹įš„æŦŖå–œč‹Ĩį‹‚ã€‚åŽƒå¤ĒæŖ’äē†īŧ_」 -
Brian Okken - Python Bytes 播åŽĸä¸ģ持äēē (ref)
+
Brian Okken - Python Bytes 播åŽĸä¸ģ持äēē (ref)
--- @@ -102,7 +102,7 @@ FastAPI 是一ä¸ĒᔍäēŽæž„åģē API įš„įŽ°äģŖã€åŋĢ速īŧˆéĢ˜æ€§čƒŊīŧ‰įš„ web æĄ† 「_我äģŦ厞įģå°† **API** æœåŠĄåˆ‡æĸ到äē† **FastAPI** [...] æˆ‘čŽ¤ä¸ēäŊ äŧšå–œæŦĸåŽƒįš„ [...]_」 -
Ines Montani - Matthew Honnibal - Explosion AI 创始äēē - spaCy äŊœč€… (ref) - (ref)
+
Ines Montani - Matthew Honnibal - Explosion AI 创始äēē - spaCy äŊœč€… (ref) - (ref)
--- diff --git a/docs/zh/docs/python-types.md b/docs/zh/docs/python-types.md index ba767da87..a7f76d97f 100644 --- a/docs/zh/docs/python-types.md +++ b/docs/zh/docs/python-types.md @@ -240,7 +240,29 @@ John Doe 下éĸįš„äž‹å­æĨč‡Ē Pydantic åŽ˜æ–šæ–‡æĄŖīŧš -{* ../../docs_src/python_types/tutorial010.py *} +//// tab | Python 3.10+ + +```Python +{!> ../../docs_src/python_types/tutorial011_py310.py!} +``` + +//// + +//// tab | Python 3.9+ + +```Python +{!> ../../docs_src/python_types/tutorial011_py39.py!} +``` + +//// + +//// tab | Python 3.8+ + +```Python +{!> ../../docs_src/python_types/tutorial011.py!} +``` + +//// /// info diff --git a/docs/zh/docs/tutorial/security/index.md b/docs/zh/docs/tutorial/security/index.md index e888a4fe9..1484b99fd 100644 --- a/docs/zh/docs/tutorial/security/index.md +++ b/docs/zh/docs/tutorial/security/index.md @@ -22,7 +22,7 @@ OAuth2是一ä¸Ē规范īŧŒåŽƒåŽšäš‰äē†å‡ į§å¤„ᐆčēĢäģŊčŽ¤č¯å’ŒæŽˆæƒįš„æ–šæŗ• 厃包æ‹Ŧäē†äŊŋį”¨ã€ŒįŦŦ三斚」čŋ›čĄŒčēĢäģŊčŽ¤č¯įš„æ–šæŗ•ã€‚ -čŋ™å°ąæ˜¯æ‰€æœ‰å¸Ļ有「äŊŋᔍ FacebookīŧŒGoogleīŧŒTwitterīŧŒGitHub į™ģåŊ•ã€įš„įŗģįģŸčƒŒåŽæ‰€äŊŋį”¨įš„æœēåˆļ。 +čŋ™å°ąæ˜¯æ‰€æœ‰å¸Ļ有「äŊŋᔍ FacebookīŧŒGoogleīŧŒX (Twitter)īŧŒGitHub į™ģåŊ•ã€įš„įŗģįģŸčƒŒåŽæ‰€äŊŋį”¨įš„æœēåˆļ。 ### OAuth 1 @@ -79,7 +79,7 @@ OpenAPI 厚䚉äē†äģĨä¸‹åŽ‰å…¨æ–šæĄˆīŧš * HTTP Basic čŽ¤č¯æ–šåŧã€‚ * HTTP DigestīŧŒį­‰į­‰ã€‚ * `oauth2`īŧšæ‰€æœ‰įš„ OAuth2 å¤„į†åŽ‰å…¨æ€§įš„æ–šåŧīŧˆį§°ä¸ē「æĩį¨‹ã€īŧ‰ã€‚ - *äģĨä¸‹å‡ į§æĩį¨‹é€‚合构åģē OAuth 2.0 čēĢäģŊčŽ¤č¯įš„æäž›č€…īŧˆäž‹åĻ‚ GoogleīŧŒFacebookīŧŒTwitterīŧŒGitHub į­‰īŧ‰īŧš + *äģĨä¸‹å‡ į§æĩį¨‹é€‚合构åģē OAuth 2.0 čēĢäģŊčŽ¤č¯įš„æäž›č€…īŧˆäž‹åĻ‚ GoogleīŧŒFacebookīŧŒX (Twitter)īŧŒGitHub į­‰īŧ‰īŧš * `implicit` * `clientCredentials` * `authorizationCode` @@ -91,7 +91,7 @@ OpenAPI 厚䚉äē†äģĨä¸‹åŽ‰å…¨æ–šæĄˆīŧš /// tip -集成å…ļäģ–čēĢäģŊčŽ¤č¯/æŽˆæƒæäž›č€…īŧˆäž‹åĻ‚GoogleīŧŒFacebookīŧŒTwitterīŧŒGitHubį­‰īŧ‰ä🿘¯å¯čƒŊįš„īŧŒč€Œä¸”čžƒä¸ē厚易。 +集成å…ļäģ–čēĢäģŊčŽ¤č¯/æŽˆæƒæäž›č€…īŧˆäž‹åĻ‚GoogleīŧŒFacebookīŧŒX (Twitter)īŧŒGitHubį­‰īŧ‰ä🿘¯å¯čƒŊįš„īŧŒč€Œä¸”čžƒä¸ē厚易。 æœ€å¤æ‚įš„é—Žéĸ˜æ˜¯åˆ›åģē一ä¸Ē像čŋ™æ ˇįš„čēĢäģŊčŽ¤č¯/æŽˆæƒæäž›į¨‹åēīŧŒäŊ†æ˜¯ **FastAPI** ä¸ēäŊ æäž›äē†čŊģæžåŽŒæˆäģģåŠĄįš„åˇĨå…ˇīŧŒåŒæ—ļä¸ēäŊ č§Ŗå†ŗäē†é‡æ´ģ。 diff --git a/docs_src/app_testing/tutorial004.py b/docs_src/app_testing/tutorial004.py new file mode 100644 index 000000000..f83ac9ae9 --- /dev/null +++ b/docs_src/app_testing/tutorial004.py @@ -0,0 +1,43 @@ +from contextlib import asynccontextmanager + +from fastapi import FastAPI +from fastapi.testclient import TestClient + +items = {} + + +@asynccontextmanager +async def lifespan(app: FastAPI): + items["foo"] = {"name": "Fighters"} + items["bar"] = {"name": "Tenders"} + yield + # clean up items + items.clear() + + +app = FastAPI(lifespan=lifespan) + + +@app.get("/items/{item_id}") +async def read_items(item_id: str): + return items[item_id] + + +def test_read_items(): + # Before the lifespan starts, "items" is still empty + assert items == {} + + with TestClient(app) as client: + # Inside the "with TestClient" block, the lifespan starts and items added + assert items == {"foo": {"name": "Fighters"}, "bar": {"name": "Tenders"}} + + response = client.get("/items/foo") + assert response.status_code == 200 + assert response.json() == {"name": "Fighters"} + + # After the requests is done, the items are still there + assert items == {"foo": {"name": "Fighters"}, "bar": {"name": "Tenders"}} + + # The end of the "with TestClient" block simulates terminating the app, so + # the lifespan ends and items are cleaned up + assert items == {} diff --git a/docs_src/behind_a_proxy/tutorial001_01.py b/docs_src/behind_a_proxy/tutorial001_01.py new file mode 100644 index 000000000..52b114395 --- /dev/null +++ b/docs_src/behind_a_proxy/tutorial001_01.py @@ -0,0 +1,8 @@ +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/items/") +def read_items(): + return ["plumbus", "portal gun"] diff --git a/docs_src/dependencies/tutorial013_an_py310.py b/docs_src/dependencies/tutorial013_an_py310.py new file mode 100644 index 000000000..0c2f62c4f --- /dev/null +++ b/docs_src/dependencies/tutorial013_an_py310.py @@ -0,0 +1,38 @@ +import time +from typing import Annotated + +from fastapi import Depends, FastAPI, HTTPException +from fastapi.responses import StreamingResponse +from sqlmodel import Field, Session, SQLModel, create_engine + +engine = create_engine("postgresql+psycopg://postgres:postgres@localhost/db") + + +class User(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str + + +app = FastAPI() + + +def get_session(): + with Session(engine) as session: + yield session + + +def get_user(user_id: int, session: Annotated[Session, Depends(get_session)]): + user = session.get(User, user_id) + if not user: + raise HTTPException(status_code=403, detail="Not authorized") + + +def generate_stream(query: str): + for ch in query: + yield ch + time.sleep(0.1) + + +@app.get("/generate", dependencies=[Depends(get_user)]) +def generate(query: str): + return StreamingResponse(content=generate_stream(query)) diff --git a/docs_src/dependencies/tutorial014_an_py310.py b/docs_src/dependencies/tutorial014_an_py310.py new file mode 100644 index 000000000..ed7c1809a --- /dev/null +++ b/docs_src/dependencies/tutorial014_an_py310.py @@ -0,0 +1,39 @@ +import time +from typing import Annotated + +from fastapi import Depends, FastAPI, HTTPException +from fastapi.responses import StreamingResponse +from sqlmodel import Field, Session, SQLModel, create_engine + +engine = create_engine("postgresql+psycopg://postgres:postgres@localhost/db") + + +class User(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str + + +app = FastAPI() + + +def get_session(): + with Session(engine) as session: + yield session + + +def get_user(user_id: int, session: Annotated[Session, Depends(get_session)]): + user = session.get(User, user_id) + if not user: + raise HTTPException(status_code=403, detail="Not authorized") + session.close() + + +def generate_stream(query: str): + for ch in query: + yield ch + time.sleep(0.1) + + +@app.get("/generate", dependencies=[Depends(get_user)]) +def generate(query: str): + return StreamingResponse(content=generate_stream(query)) diff --git a/docs_src/handling_errors/tutorial005.py b/docs_src/handling_errors/tutorial005.py index 6e0b81d31..0e04fa086 100644 --- a/docs_src/handling_errors/tutorial005.py +++ b/docs_src/handling_errors/tutorial005.py @@ -1,4 +1,4 @@ -from fastapi import FastAPI, Request, status +from fastapi import FastAPI, Request from fastapi.encoders import jsonable_encoder from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse @@ -10,7 +10,7 @@ app = FastAPI() @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): return JSONResponse( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + status_code=422, content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}), ) diff --git a/docs_src/security/tutorial004.py b/docs_src/security/tutorial004.py index 222589618..130dc699a 100644 --- a/docs_src/security/tutorial004.py +++ b/docs_src/security/tutorial004.py @@ -5,7 +5,7 @@ import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel # to get a string like this run: @@ -20,7 +20,7 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, } } @@ -46,7 +46,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -54,11 +54,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): diff --git a/docs_src/security/tutorial004_an.py b/docs_src/security/tutorial004_an.py index e2221cd39..018234e30 100644 --- a/docs_src/security/tutorial004_an.py +++ b/docs_src/security/tutorial004_an.py @@ -5,7 +5,7 @@ import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel from typing_extensions import Annotated @@ -21,7 +21,7 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, } } @@ -47,7 +47,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -55,11 +55,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): diff --git a/docs_src/security/tutorial004_an_py310.py b/docs_src/security/tutorial004_an_py310.py index a3f74fc0e..18ea96bc5 100644 --- a/docs_src/security/tutorial004_an_py310.py +++ b/docs_src/security/tutorial004_an_py310.py @@ -5,7 +5,7 @@ import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel # to get a string like this run: @@ -20,7 +20,7 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, } } @@ -46,7 +46,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -54,11 +54,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): diff --git a/docs_src/security/tutorial004_an_py39.py b/docs_src/security/tutorial004_an_py39.py index b33d677ed..d3fd29e5a 100644 --- a/docs_src/security/tutorial004_an_py39.py +++ b/docs_src/security/tutorial004_an_py39.py @@ -5,7 +5,7 @@ import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel # to get a string like this run: @@ -20,7 +20,7 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, } } @@ -46,7 +46,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -54,11 +54,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): diff --git a/docs_src/security/tutorial004_py310.py b/docs_src/security/tutorial004_py310.py index d46ce26bf..cd1dcff46 100644 --- a/docs_src/security/tutorial004_py310.py +++ b/docs_src/security/tutorial004_py310.py @@ -4,7 +4,7 @@ import jwt from fastapi import Depends, FastAPI, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel # to get a string like this run: @@ -19,7 +19,7 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, } } @@ -45,7 +45,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -53,11 +53,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): diff --git a/docs_src/security/tutorial005.py b/docs_src/security/tutorial005.py index ccad07969..fdd73bcd8 100644 --- a/docs_src/security/tutorial005.py +++ b/docs_src/security/tutorial005.py @@ -9,7 +9,7 @@ from fastapi.security import ( SecurityScopes, ) from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel, ValidationError # to get a string like this run: @@ -24,14 +24,14 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Chains", "email": "alicechains@example.com", - "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", "disabled": True, }, } @@ -58,7 +58,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", @@ -69,11 +69,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): @@ -119,7 +119,8 @@ async def get_current_user( username: str = payload.get("sub") if username is None: raise credentials_exception - token_scopes = payload.get("scopes", []) + scope: str = payload.get("scope", "") + token_scopes = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (InvalidTokenError, ValidationError): raise credentials_exception @@ -153,7 +154,7 @@ async def login_for_access_token( raise HTTPException(status_code=400, detail="Incorrect username or password") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( - data={"sub": user.username, "scopes": form_data.scopes}, + data={"sub": user.username, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires, ) return Token(access_token=access_token, token_type="bearer") diff --git a/docs_src/security/tutorial005_an.py b/docs_src/security/tutorial005_an.py index 2e8bb3bdb..e1d7b4f62 100644 --- a/docs_src/security/tutorial005_an.py +++ b/docs_src/security/tutorial005_an.py @@ -9,7 +9,7 @@ from fastapi.security import ( SecurityScopes, ) from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel, ValidationError from typing_extensions import Annotated @@ -25,14 +25,14 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Chains", "email": "alicechains@example.com", - "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", "disabled": True, }, } @@ -59,7 +59,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", @@ -70,11 +70,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): @@ -120,7 +120,8 @@ async def get_current_user( username = payload.get("sub") if username is None: raise credentials_exception - token_scopes = payload.get("scopes", []) + scope: str = payload.get("scope", "") + token_scopes = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (InvalidTokenError, ValidationError): raise credentials_exception @@ -154,7 +155,7 @@ async def login_for_access_token( raise HTTPException(status_code=400, detail="Incorrect username or password") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( - data={"sub": user.username, "scopes": form_data.scopes}, + data={"sub": user.username, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires, ) return Token(access_token=access_token, token_type="bearer") diff --git a/docs_src/security/tutorial005_an_py310.py b/docs_src/security/tutorial005_an_py310.py index 90781587f..df55951c0 100644 --- a/docs_src/security/tutorial005_an_py310.py +++ b/docs_src/security/tutorial005_an_py310.py @@ -9,7 +9,7 @@ from fastapi.security import ( SecurityScopes, ) from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel, ValidationError # to get a string like this run: @@ -24,14 +24,14 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Chains", "email": "alicechains@example.com", - "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", "disabled": True, }, } @@ -58,7 +58,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", @@ -69,11 +69,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): @@ -119,7 +119,8 @@ async def get_current_user( username = payload.get("sub") if username is None: raise credentials_exception - token_scopes = payload.get("scopes", []) + scope: str = payload.get("scope", "") + token_scopes = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (InvalidTokenError, ValidationError): raise credentials_exception @@ -153,7 +154,7 @@ async def login_for_access_token( raise HTTPException(status_code=400, detail="Incorrect username or password") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( - data={"sub": user.username, "scopes": form_data.scopes}, + data={"sub": user.username, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires, ) return Token(access_token=access_token, token_type="bearer") diff --git a/docs_src/security/tutorial005_an_py39.py b/docs_src/security/tutorial005_an_py39.py index a5192d8d6..983c1c22c 100644 --- a/docs_src/security/tutorial005_an_py39.py +++ b/docs_src/security/tutorial005_an_py39.py @@ -9,7 +9,7 @@ from fastapi.security import ( SecurityScopes, ) from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel, ValidationError # to get a string like this run: @@ -24,14 +24,14 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Chains", "email": "alicechains@example.com", - "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", "disabled": True, }, } @@ -58,7 +58,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", @@ -69,11 +69,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): @@ -119,7 +119,8 @@ async def get_current_user( username = payload.get("sub") if username is None: raise credentials_exception - token_scopes = payload.get("scopes", []) + scope: str = payload.get("scope", "") + token_scopes = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (InvalidTokenError, ValidationError): raise credentials_exception @@ -153,7 +154,7 @@ async def login_for_access_token( raise HTTPException(status_code=400, detail="Incorrect username or password") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( - data={"sub": user.username, "scopes": form_data.scopes}, + data={"sub": user.username, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires, ) return Token(access_token=access_token, token_type="bearer") diff --git a/docs_src/security/tutorial005_py310.py b/docs_src/security/tutorial005_py310.py index b244ef08e..d08e2c59f 100644 --- a/docs_src/security/tutorial005_py310.py +++ b/docs_src/security/tutorial005_py310.py @@ -8,7 +8,7 @@ from fastapi.security import ( SecurityScopes, ) from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel, ValidationError # to get a string like this run: @@ -23,14 +23,14 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Chains", "email": "alicechains@example.com", - "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", "disabled": True, }, } @@ -57,7 +57,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", @@ -68,11 +68,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): @@ -118,7 +118,8 @@ async def get_current_user( username: str = payload.get("sub") if username is None: raise credentials_exception - token_scopes = payload.get("scopes", []) + scope: str = payload.get("scope", "") + token_scopes = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (InvalidTokenError, ValidationError): raise credentials_exception @@ -152,7 +153,7 @@ async def login_for_access_token( raise HTTPException(status_code=400, detail="Incorrect username or password") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( - data={"sub": user.username, "scopes": form_data.scopes}, + data={"sub": user.username, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires, ) return Token(access_token=access_token, token_type="bearer") diff --git a/docs_src/security/tutorial005_py39.py b/docs_src/security/tutorial005_py39.py index 8f0e93376..5bde47ef4 100644 --- a/docs_src/security/tutorial005_py39.py +++ b/docs_src/security/tutorial005_py39.py @@ -9,7 +9,7 @@ from fastapi.security import ( SecurityScopes, ) from jwt.exceptions import InvalidTokenError -from passlib.context import CryptContext +from pwdlib import PasswordHash from pydantic import BaseModel, ValidationError # to get a string like this run: @@ -24,14 +24,14 @@ fake_users_db = { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", - "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Chains", "email": "alicechains@example.com", - "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", + "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", "disabled": True, }, } @@ -58,7 +58,7 @@ class UserInDB(User): hashed_password: str -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer( tokenUrl="token", @@ -69,11 +69,11 @@ app = FastAPI() def verify_password(plain_password, hashed_password): - return pwd_context.verify(plain_password, hashed_password) + return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): - return pwd_context.hash(password) + return password_hash.hash(password) def get_user(db, username: str): @@ -119,7 +119,8 @@ async def get_current_user( username: str = payload.get("sub") if username is None: raise credentials_exception - token_scopes = payload.get("scopes", []) + scope: str = payload.get("scope", "") + token_scopes = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (InvalidTokenError, ValidationError): raise credentials_exception @@ -153,7 +154,7 @@ async def login_for_access_token( raise HTTPException(status_code=400, detail="Incorrect username or password") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( - data={"sub": user.username, "scopes": form_data.scopes}, + data={"sub": user.username, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires, ) return Token(access_token=access_token, token_type="bearer") diff --git a/fastapi/__init__.py b/fastapi/__init__.py index b02bf8b4f..03a5aaad5 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.116.1" +__version__ = "0.118.0" from starlette import status as status diff --git a/fastapi/_compat.py b/fastapi/_compat.py index 227ad837d..26b6638c8 100644 --- a/fastapi/_compat.py +++ b/fastapi/_compat.py @@ -393,9 +393,10 @@ else: ) definitions.update(m_definitions) model_name = model_name_map[model] + definitions[model_name] = m_schema + for m_schema in definitions.values(): if "description" in m_schema: m_schema["description"] = m_schema["description"].split("\f")[0] - definitions[model_name] = m_schema return definitions def is_pv1_scalar_field(field: ModelField) -> bool: diff --git a/fastapi/applications.py b/fastapi/applications.py index 05c7bd2be..915f5f70a 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -22,6 +22,7 @@ from fastapi.exception_handlers import ( ) from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError from fastapi.logger import logger +from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware from fastapi.openapi.docs import ( get_redoc_html, get_swagger_ui_html, @@ -36,10 +37,12 @@ from starlette.datastructures import State from starlette.exceptions import HTTPException from starlette.middleware import Middleware from starlette.middleware.base import BaseHTTPMiddleware +from starlette.middleware.errors import ServerErrorMiddleware +from starlette.middleware.exceptions import ExceptionMiddleware from starlette.requests import Request from starlette.responses import HTMLResponse, JSONResponse, Response from starlette.routing import BaseRoute -from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send +from starlette.types import ASGIApp, ExceptionHandler, Lifespan, Receive, Scope, Send from typing_extensions import Annotated, Doc, deprecated AppType = TypeVar("AppType", bound="FastAPI") @@ -810,6 +813,32 @@ class FastAPI(Starlette): """ ), ] = True, + openapi_external_docs: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + This field allows you to provide additional external documentation links. + If provided, it must be a dictionary containing: + + * `description`: A brief description of the external documentation. + * `url`: The URL pointing to the external documentation. The value **MUST** + be a valid URL format. + + **Example**: + + ```python + from fastapi import FastAPI + + external_docs = { + "description": "Detailed API Reference", + "url": "https://example.com/api-docs", + } + + app = FastAPI(openapi_external_docs=external_docs) + ``` + """ + ), + ] = None, **extra: Annotated[ Any, Doc( @@ -838,6 +867,7 @@ class FastAPI(Starlette): self.swagger_ui_parameters = swagger_ui_parameters self.servers = servers or [] self.separate_input_output_schemas = separate_input_output_schemas + self.openapi_external_docs = openapi_external_docs self.extra = extra self.openapi_version: Annotated[ str, @@ -963,6 +993,54 @@ class FastAPI(Starlette): self.middleware_stack: Union[ASGIApp, None] = None self.setup() + def build_middleware_stack(self) -> ASGIApp: + # Duplicate/override from Starlette to add AsyncExitStackMiddleware + # inside of ExceptionMiddleware, inside of custom user middlewares + debug = self.debug + error_handler = None + exception_handlers: dict[Any, ExceptionHandler] = {} + + for key, value in self.exception_handlers.items(): + if key in (500, Exception): + error_handler = value + else: + exception_handlers[key] = value + + middleware = ( + [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] + + self.user_middleware + + [ + Middleware( + ExceptionMiddleware, handlers=exception_handlers, debug=debug + ), + # Add FastAPI-specific AsyncExitStackMiddleware for closing files. + # Before this was also used for closing dependencies with yield but + # those now have their own AsyncExitStack, to properly support + # streaming responses while keeping compatibility with the previous + # versions (as of writing 0.117.1) that allowed doing + # except HTTPException inside a dependency with yield. + # This needs to happen after user middlewares because those create a + # new contextvars context copy by using a new AnyIO task group. + # This AsyncExitStack preserves the context for contextvars, not + # strictly necessary for closing files but it was one of the original + # intentions. + # If the AsyncExitStack lived outside of the custom middlewares and + # contextvars were set, for example in a dependency with 'yield' + # in that internal contextvars context, the values would not be + # available in the outer context of the AsyncExitStack. + # By placing the middleware and the AsyncExitStack here, inside all + # user middlewares, the same context is used. + # This is currently not needed, only for closing files, but used to be + # important when dependencies with yield were closed here. + Middleware(AsyncExitStackMiddleware), + ] + ) + + app = self.router + for cls, args, kwargs in reversed(middleware): + app = cls(app, *args, **kwargs) + return app + def openapi(self) -> Dict[str, Any]: """ Generate the OpenAPI schema of the application. This is called by FastAPI @@ -992,6 +1070,7 @@ class FastAPI(Starlette): tags=self.openapi_tags, servers=self.servers, separate_input_output_schemas=self.separate_input_output_schemas, + external_docs=self.openapi_external_docs, ) return self.openapi_schema diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 081b63a8b..e49380cb3 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -1,4 +1,5 @@ import inspect +import sys from contextlib import AsyncExitStack, contextmanager from copy import copy, deepcopy from dataclasses import dataclass @@ -73,6 +74,11 @@ from starlette.responses import Response from starlette.websockets import WebSocket from typing_extensions import Annotated, get_args, get_origin +if sys.version_info >= (3, 13): # pragma: no cover + from inspect import iscoroutinefunction +else: # pragma: no cover + from asyncio import iscoroutinefunction + multipart_not_installed_error = ( 'Form data requires "python-multipart" to be installed. \n' 'You can install "python-multipart" with: \n\n' @@ -248,6 +254,8 @@ def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any: if isinstance(annotation, str): annotation = ForwardRef(annotation) annotation = evaluate_forwardref(annotation, globalns, globalns) + if annotation is type(None): + return None return annotation @@ -529,11 +537,11 @@ def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None: def is_coroutine_callable(call: Callable[..., Any]) -> bool: if inspect.isroutine(call): - return inspect.iscoroutinefunction(call) + return iscoroutinefunction(call) if inspect.isclass(call): return False dunder_call = getattr(call, "__call__", None) # noqa: B004 - return inspect.iscoroutinefunction(dunder_call) + return iscoroutinefunction(dunder_call) def is_async_gen_callable(call: Callable[..., Any]) -> bool: @@ -587,7 +595,8 @@ async def solve_dependencies( response = Response() del response.headers["content-length"] response.status_code = None # type: ignore - dependency_cache = dependency_cache or {} + if dependency_cache is None: + dependency_cache = {} sub_dependant: Dependant for sub_dependant in dependant.dependencies: sub_dependant.call = cast(Callable[..., Any], sub_dependant.call) @@ -624,7 +633,6 @@ async def solve_dependencies( embed_body_fields=embed_body_fields, ) background_tasks = solved_result.background_tasks - dependency_cache.update(solved_result.dependency_cache) if solved_result.errors: errors.extend(solved_result.errors) continue @@ -864,20 +872,19 @@ async def _extract_form_body( received_body: FormData, ) -> Dict[str, Any]: values = {} - first_field = body_fields[0] - first_field_info = first_field.field_info for field in body_fields: value = _get_multidict_value(field, received_body) + field_info = field.field_info if ( - isinstance(first_field_info, params.File) + isinstance(field_info, params.File) and is_bytes_field(field) and isinstance(value, UploadFile) ): value = await value.read() elif ( is_bytes_sequence_field(field) - and isinstance(first_field_info, params.File) + and isinstance(field_info, params.File) and value_is_sequence(value) ): # For types @@ -916,7 +923,11 @@ async def request_body_to_args( fields_to_extract: List[ModelField] = body_fields - if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel): + if ( + single_not_embedded_field + and lenient_issubclass(first_field.type_, BaseModel) + and isinstance(received_body, FormData) + ): fields_to_extract = get_cached_model_fields(first_field.type_) if isinstance(received_body, FormData): diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 451ea0760..b037f8bb5 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -219,7 +219,7 @@ def jsonable_encoder( if not PYDANTIC_V2: encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined] if custom_encoder: - encoders.update(custom_encoder) + encoders = {**encoders, **custom_encoder} obj_dict = _model_dump( obj, mode="json", @@ -241,6 +241,7 @@ def jsonable_encoder( sqlalchemy_safe=sqlalchemy_safe, ) if dataclasses.is_dataclass(obj): + assert not isinstance(obj, type) obj_dict = dataclasses.asdict(obj) return jsonable_encoder( obj_dict, diff --git a/fastapi/exception_handlers.py b/fastapi/exception_handlers.py index 6c2ba7fed..475dd7bdd 100644 --- a/fastapi/exception_handlers.py +++ b/fastapi/exception_handlers.py @@ -5,7 +5,7 @@ from fastapi.websockets import WebSocket from starlette.exceptions import HTTPException from starlette.requests import Request from starlette.responses import JSONResponse, Response -from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, WS_1008_POLICY_VIOLATION +from starlette.status import WS_1008_POLICY_VIOLATION async def http_exception_handler(request: Request, exc: HTTPException) -> Response: @@ -21,7 +21,7 @@ async def request_validation_exception_handler( request: Request, exc: RequestValidationError ) -> JSONResponse: return JSONResponse( - status_code=HTTP_422_UNPROCESSABLE_ENTITY, + status_code=422, content={"detail": jsonable_encoder(exc.errors())}, ) diff --git a/fastapi/middleware/asyncexitstack.py b/fastapi/middleware/asyncexitstack.py new file mode 100644 index 000000000..4ce3f5a62 --- /dev/null +++ b/fastapi/middleware/asyncexitstack.py @@ -0,0 +1,18 @@ +from contextlib import AsyncExitStack + +from starlette.types import ASGIApp, Receive, Scope, Send + + +# Used mainly to close files after the request is done, dependencies are closed +# in their own AsyncExitStack +class AsyncExitStackMiddleware: + def __init__( + self, app: ASGIApp, context_name: str = "fastapi_middleware_astack" + ) -> None: + self.app = app + self.context_name = context_name + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + async with AsyncExitStack() as stack: + scope[self.context_name] = stack + await self.app(scope, receive, send) diff --git a/fastapi/openapi/models.py b/fastapi/openapi/models.py index ed07b40f5..81d276aed 100644 --- a/fastapi/openapi/models.py +++ b/fastapi/openapi/models.py @@ -121,6 +121,12 @@ class ExternalDocumentation(BaseModelWithConfig): url: AnyUrl +# Ref JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation#name-type +SchemaType = Literal[ + "array", "boolean", "integer", "null", "number", "object", "string" +] + + class Schema(BaseModelWithConfig): # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-json-schema-core-vocabu # Core Vocabulary @@ -145,7 +151,7 @@ class Schema(BaseModelWithConfig): dependentSchemas: Optional[Dict[str, "SchemaOrBool"]] = None prefixItems: Optional[List["SchemaOrBool"]] = None # TODO: uncomment and remove below when deprecating Pydantic v1 - # It generales a list of schemas for tuples, before prefixItems was available + # It generates a list of schemas for tuples, before prefixItems was available # items: Optional["SchemaOrBool"] = None items: Optional[Union["SchemaOrBool", List["SchemaOrBool"]]] = None contains: Optional["SchemaOrBool"] = None @@ -157,7 +163,7 @@ class Schema(BaseModelWithConfig): unevaluatedProperties: Optional["SchemaOrBool"] = None # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural # A Vocabulary for Structural Validation - type: Optional[str] = None + type: Optional[Union[SchemaType, List[SchemaType]]] = None enum: Optional[List[Any]] = None const: Optional[Any] = None multipleOf: Optional[float] = Field(default=None, gt=0) diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py index 808646cc2..21105cf65 100644 --- a/fastapi/openapi/utils.py +++ b/fastapi/openapi/utils.py @@ -35,7 +35,6 @@ from fastapi.utils import ( from pydantic import BaseModel from starlette.responses import JSONResponse from starlette.routing import BaseRoute -from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY from typing_extensions import Literal validation_error_definition = { @@ -416,7 +415,7 @@ def get_openapi_path( ) deep_dict_update(openapi_response, process_response) openapi_response["description"] = description - http422 = str(HTTP_422_UNPROCESSABLE_ENTITY) + http422 = "422" all_route_params = get_flat_params(route.dependant) if (all_route_params or route.body_field) and not any( status in operation["responses"] @@ -489,6 +488,7 @@ def get_openapi( contact: Optional[Dict[str, Union[str, Any]]] = None, license_info: Optional[Dict[str, Union[str, Any]]] = None, separate_input_output_schemas: bool = True, + external_docs: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: info: Dict[str, Any] = {"title": title, "version": version} if summary: @@ -566,4 +566,6 @@ def get_openapi( output["webhooks"] = webhook_paths if tags: output["tags"] = tags + if external_docs: + output["externalDocs"] = external_docs return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore diff --git a/fastapi/routing.py b/fastapi/routing.py index 54c75a027..65f739d95 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -1,13 +1,15 @@ -import asyncio import dataclasses import email.message +import functools import inspect import json +import sys from contextlib import AsyncExitStack, asynccontextmanager from enum import Enum, IntEnum from typing import ( Any, AsyncIterator, + Awaitable, Callable, Collection, Coroutine, @@ -59,6 +61,8 @@ from fastapi.utils import ( ) from pydantic import BaseModel from starlette import routing +from starlette._exception_handler import wrap_app_handling_exceptions +from starlette._utils import is_async_callable from starlette.concurrency import run_in_threadpool from starlette.exceptions import HTTPException from starlette.requests import Request @@ -68,14 +72,84 @@ from starlette.routing import ( Match, compile_path, get_name, - request_response, - websocket_session, ) from starlette.routing import Mount as Mount # noqa -from starlette.types import AppType, ASGIApp, Lifespan, Scope +from starlette.types import AppType, ASGIApp, Lifespan, Receive, Scope, Send from starlette.websockets import WebSocket from typing_extensions import Annotated, Doc, deprecated +if sys.version_info >= (3, 13): # pragma: no cover + from inspect import iscoroutinefunction +else: # pragma: no cover + from asyncio import iscoroutinefunction + + +# Copy of starlette.routing.request_response modified to include the +# dependencies' AsyncExitStack +def request_response( + func: Callable[[Request], Union[Awaitable[Response], Response]], +) -> ASGIApp: + """ + Takes a function or coroutine `func(request) -> response`, + and returns an ASGI application. + """ + f: Callable[[Request], Awaitable[Response]] = ( + func if is_async_callable(func) else functools.partial(run_in_threadpool, func) # type:ignore + ) + + async def app(scope: Scope, receive: Receive, send: Send) -> None: + request = Request(scope, receive, send) + + async def app(scope: Scope, receive: Receive, send: Send) -> None: + # Starts customization + response_awaited = False + async with AsyncExitStack() as stack: + scope["fastapi_inner_astack"] = stack + # Same as in Starlette + response = await f(request) + await response(scope, receive, send) + # Continues customization + response_awaited = True + if not response_awaited: + raise FastAPIError( + "Response not awaited. There's a high chance that the " + "application code is raising an exception and a dependency with yield " + "has a block with a bare except, or a block with except Exception, " + "and is not raising the exception again. Read more about it in the " + "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except" + ) + + # Same as in Starlette + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + + return app + + +# Copy of starlette.routing.websocket_session modified to include the +# dependencies' AsyncExitStack +def websocket_session( + func: Callable[[WebSocket], Awaitable[None]], +) -> ASGIApp: + """ + Takes a coroutine `func(session)`, and returns an ASGI application. + """ + # assert asyncio.iscoroutinefunction(func), "WebSocket endpoints must be async" + + async def app(scope: Scope, receive: Receive, send: Send) -> None: + session = WebSocket(scope, receive=receive, send=send) + + async def app(scope: Scope, receive: Receive, send: Send) -> None: + # Starts customization + async with AsyncExitStack() as stack: + scope["fastapi_inner_astack"] = stack + # Same as in Starlette + await func(session) + + # Same as in Starlette + await wrap_app_handling_exceptions(app, session)(scope, receive, send) + + return app + def _prepare_response_content( res: Any, @@ -120,6 +194,7 @@ def _prepare_response_content( for k, v in res.items() } elif dataclasses.is_dataclass(res): + assert not isinstance(res, type) return dataclasses.asdict(res) return res @@ -231,7 +306,7 @@ def get_request_handler( embed_body_fields: bool = False, ) -> Callable[[Request], Coroutine[Any, Any, Response]]: assert dependant.call is not None, "dependant.call must be a function" - is_coroutine = asyncio.iscoroutinefunction(dependant.call) + is_coroutine = iscoroutinefunction(dependant.call) is_body_form = body_field and isinstance(body_field.field_info, params.Form) if isinstance(response_class, DefaultPlaceholder): actual_response_class: Type[Response] = response_class.value @@ -240,119 +315,120 @@ def get_request_handler( async def app(request: Request) -> Response: response: Union[Response, None] = None - async with AsyncExitStack() as file_stack: - try: - body: Any = None - if body_field: - if is_body_form: - body = await request.form() - file_stack.push_async_callback(body.close) - else: - body_bytes = await request.body() - if body_bytes: - json_body: Any = Undefined - content_type_value = request.headers.get("content-type") - if not content_type_value: - json_body = await request.json() - else: - message = email.message.Message() - message["content-type"] = content_type_value - if message.get_content_maintype() == "application": - subtype = message.get_content_subtype() - if subtype == "json" or subtype.endswith("+json"): - json_body = await request.json() - if json_body != Undefined: - body = json_body - else: - body = body_bytes - except json.JSONDecodeError as e: - validation_error = RequestValidationError( - [ - { - "type": "json_invalid", - "loc": ("body", e.pos), - "msg": "JSON decode error", - "input": {}, - "ctx": {"error": e.msg}, - } - ], - body=e.doc, - ) - raise validation_error from e - except HTTPException: - # If a middleware raises an HTTPException, it should be raised again - raise - except Exception as e: - http_error = HTTPException( - status_code=400, detail="There was an error parsing the body" - ) - raise http_error from e - errors: List[Any] = [] - async with AsyncExitStack() as async_exit_stack: - solved_result = await solve_dependencies( - request=request, - dependant=dependant, - body=body, - dependency_overrides_provider=dependency_overrides_provider, - async_exit_stack=async_exit_stack, - embed_body_fields=embed_body_fields, - ) - errors = solved_result.errors - if not errors: - raw_response = await run_endpoint_function( - dependant=dependant, - values=solved_result.values, - is_coroutine=is_coroutine, - ) - if isinstance(raw_response, Response): - if raw_response.background is None: - raw_response.background = solved_result.background_tasks - response = raw_response - else: - response_args: Dict[str, Any] = { - "background": solved_result.background_tasks - } - # If status_code was set, use it, otherwise use the default from the - # response class, in the case of redirect it's 307 - current_status_code = ( - status_code - if status_code - else solved_result.response.status_code - ) - if current_status_code is not None: - response_args["status_code"] = current_status_code - if solved_result.response.status_code: - response_args["status_code"] = ( - solved_result.response.status_code - ) - content = await serialize_response( - field=response_field, - response_content=raw_response, - include=response_model_include, - exclude=response_model_exclude, - by_alias=response_model_by_alias, - exclude_unset=response_model_exclude_unset, - exclude_defaults=response_model_exclude_defaults, - exclude_none=response_model_exclude_none, - is_coroutine=is_coroutine, - ) - response = actual_response_class(content, **response_args) - if not is_body_allowed_for_status_code(response.status_code): - response.body = b"" - response.headers.raw.extend(solved_result.response.headers.raw) - if errors: - validation_error = RequestValidationError( - _normalize_errors(errors), body=body - ) - raise validation_error - if response is None: - raise FastAPIError( - "No response object was returned. There's a high chance that the " - "application code is raising an exception and a dependency with yield " - "has a block with a bare except, or a block with except Exception, " - "and is not raising the exception again. Read more about it in the " - "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except" + file_stack = request.scope.get("fastapi_middleware_astack") + assert isinstance(file_stack, AsyncExitStack), ( + "fastapi_middleware_astack not found in request scope" + ) + + # Read body and auto-close files + try: + body: Any = None + if body_field: + if is_body_form: + body = await request.form() + file_stack.push_async_callback(body.close) + else: + body_bytes = await request.body() + if body_bytes: + json_body: Any = Undefined + content_type_value = request.headers.get("content-type") + if not content_type_value: + json_body = await request.json() + else: + message = email.message.Message() + message["content-type"] = content_type_value + if message.get_content_maintype() == "application": + subtype = message.get_content_subtype() + if subtype == "json" or subtype.endswith("+json"): + json_body = await request.json() + if json_body != Undefined: + body = json_body + else: + body = body_bytes + except json.JSONDecodeError as e: + validation_error = RequestValidationError( + [ + { + "type": "json_invalid", + "loc": ("body", e.pos), + "msg": "JSON decode error", + "input": {}, + "ctx": {"error": e.msg}, + } + ], + body=e.doc, ) + raise validation_error from e + except HTTPException: + # If a middleware raises an HTTPException, it should be raised again + raise + except Exception as e: + http_error = HTTPException( + status_code=400, detail="There was an error parsing the body" + ) + raise http_error from e + + # Solve dependencies and run path operation function, auto-closing dependencies + errors: List[Any] = [] + async_exit_stack = request.scope.get("fastapi_inner_astack") + assert isinstance(async_exit_stack, AsyncExitStack), ( + "fastapi_inner_astack not found in request scope" + ) + solved_result = await solve_dependencies( + request=request, + dependant=dependant, + body=body, + dependency_overrides_provider=dependency_overrides_provider, + async_exit_stack=async_exit_stack, + embed_body_fields=embed_body_fields, + ) + errors = solved_result.errors + if not errors: + raw_response = await run_endpoint_function( + dependant=dependant, + values=solved_result.values, + is_coroutine=is_coroutine, + ) + if isinstance(raw_response, Response): + if raw_response.background is None: + raw_response.background = solved_result.background_tasks + response = raw_response + else: + response_args: Dict[str, Any] = { + "background": solved_result.background_tasks + } + # If status_code was set, use it, otherwise use the default from the + # response class, in the case of redirect it's 307 + current_status_code = ( + status_code if status_code else solved_result.response.status_code + ) + if current_status_code is not None: + response_args["status_code"] = current_status_code + if solved_result.response.status_code: + response_args["status_code"] = solved_result.response.status_code + content = await serialize_response( + field=response_field, + response_content=raw_response, + include=response_model_include, + exclude=response_model_exclude, + by_alias=response_model_by_alias, + exclude_unset=response_model_exclude_unset, + exclude_defaults=response_model_exclude_defaults, + exclude_none=response_model_exclude_none, + is_coroutine=is_coroutine, + ) + response = actual_response_class(content, **response_args) + if not is_body_allowed_for_status_code(response.status_code): + response.body = b"" + response.headers.raw.extend(solved_result.response.headers.raw) + if errors: + validation_error = RequestValidationError( + _normalize_errors(errors), body=body + ) + raise validation_error + + # Return response + assert response return response return app @@ -364,24 +440,23 @@ def get_websocket_app( embed_body_fields: bool = False, ) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]: async def app(websocket: WebSocket) -> None: - async with AsyncExitStack() as async_exit_stack: - # TODO: remove this scope later, after a few releases - # This scope fastapi_astack is no longer used by FastAPI, kept for - # compatibility, just in case - websocket.scope["fastapi_astack"] = async_exit_stack - solved_result = await solve_dependencies( - request=websocket, - dependant=dependant, - dependency_overrides_provider=dependency_overrides_provider, - async_exit_stack=async_exit_stack, - embed_body_fields=embed_body_fields, + async_exit_stack = websocket.scope.get("fastapi_inner_astack") + assert isinstance(async_exit_stack, AsyncExitStack), ( + "fastapi_inner_astack not found in request scope" + ) + solved_result = await solve_dependencies( + request=websocket, + dependant=dependant, + dependency_overrides_provider=dependency_overrides_provider, + async_exit_stack=async_exit_stack, + embed_body_fields=embed_body_fields, + ) + if solved_result.errors: + raise WebSocketRequestValidationError( + _normalize_errors(solved_result.errors) ) - if solved_result.errors: - raise WebSocketRequestValidationError( - _normalize_errors(solved_result.errors) - ) - assert dependant.call is not None, "dependant.call must be a function" - await dependant.call(**solved_result.values) + assert dependant.call is not None, "dependant.call must be a function" + await dependant.call(**solved_result.values) return app diff --git a/fastapi/security/api_key.py b/fastapi/security/api_key.py index 70c2dca8a..6d6dd01d9 100644 --- a/fastapi/security/api_key.py +++ b/fastapi/security/api_key.py @@ -100,7 +100,7 @@ class APIKeyQuery(APIKeyBase): ] = True, ): self.model: APIKey = APIKey( - **{"in": APIKeyIn.query}, # type: ignore[arg-type] + **{"in": APIKeyIn.query}, name=name, description=description, ) @@ -188,7 +188,7 @@ class APIKeyHeader(APIKeyBase): ] = True, ): self.model: APIKey = APIKey( - **{"in": APIKeyIn.header}, # type: ignore[arg-type] + **{"in": APIKeyIn.header}, name=name, description=description, ) @@ -276,7 +276,7 @@ class APIKeyCookie(APIKeyBase): ] = True, ): self.model: APIKey = APIKey( - **{"in": APIKeyIn.cookie}, # type: ignore[arg-type] + **{"in": APIKeyIn.cookie}, name=name, description=description, ) diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py index 88e394db1..fdedbc2da 100644 --- a/fastapi/security/oauth2.py +++ b/fastapi/security/oauth2.py @@ -89,7 +89,7 @@ class OAuth2PasswordRequestForm: Doc( """ `password` string. The OAuth2 spec requires the exact field name - `password". + `password`. """ ), ], @@ -243,7 +243,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): Doc( """ `password` string. The OAuth2 spec requires the exact field name - `password". + `password`. """ ), ], diff --git a/fastapi/utils.py b/fastapi/utils.py index 4c7350fea..98725ff19 100644 --- a/fastapi/utils.py +++ b/fastapi/utils.py @@ -137,6 +137,7 @@ def create_cloned_field( new_field.alias = field.alias # type: ignore[misc] new_field.class_validators = field.class_validators # type: ignore[attr-defined] new_field.default = field.default # type: ignore[misc] + new_field.default_factory = field.default_factory # type: ignore[attr-defined] new_field.required = field.required # type: ignore[misc] new_field.model_config = field.model_config # type: ignore[attr-defined] new_field.field_info = field.field_info diff --git a/pyproject.toml b/pyproject.toml index 7709451ff..41ef1eb76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", ] dependencies = [ - "starlette>=0.40.0,<0.48.0", + "starlette>=0.40.0,<0.49.0", "pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0", "typing-extensions>=4.8.0", ] @@ -60,7 +60,7 @@ Changelog = "https://fastapi.tiangolo.com/release-notes/" standard = [ "fastapi-cli[standard] >=0.0.8", # For the test client - "httpx >=0.23.0", + "httpx >=0.23.0,<1.0.0", # For templates "jinja2 >=3.1.5", # For forms and file uploads @@ -79,7 +79,7 @@ standard = [ standard-no-fastapi-cloud-cli = [ "fastapi-cli[standard-no-fastapi-cloud-cli] >=0.0.8", # For the test client - "httpx >=0.23.0", + "httpx >=0.23.0,<1.0.0", # For templates "jinja2 >=3.1.5", # For forms and file uploads @@ -98,7 +98,7 @@ standard-no-fastapi-cloud-cli = [ all = [ "fastapi-cli[standard] >=0.0.8", # # For the test client - "httpx >=0.23.0", + "httpx >=0.23.0,<1.0.0", # For templates "jinja2 >=3.1.5", # For forms and file uploads @@ -142,6 +142,7 @@ source-includes = [ name = "fastapi-slim" [tool.mypy] +plugins = ["pydantic.mypy"] strict = true [[tool.mypy.overrides]] @@ -171,8 +172,6 @@ junit_family = "xunit2" filterwarnings = [ "error", 'ignore:starlette.middleware.wsgi is deprecated and will be removed in a future release\..*:DeprecationWarning:starlette', - # For passlib - "ignore:'crypt' is deprecated and slated for removal in Python 3.13:DeprecationWarning", # see https://trio.readthedocs.io/en/stable/history.html#trio-0-22-0-2022-09-28 "ignore:You seem to already have a custom.*:RuntimeWarning:trio", # TODO: remove after upgrading SQLAlchemy to a version that includes the following changes diff --git a/requirements-docs-tests.txt b/requirements-docs-tests.txt index 71f4a7ab9..c1107b9b0 100644 --- a/requirements-docs-tests.txt +++ b/requirements-docs-tests.txt @@ -1,4 +1,4 @@ # For mkdocstrings and tests -httpx >=0.23.0,<0.28.0 +httpx >=0.23.0,<1.0.0 # For linting and generating docs versions -ruff ==0.11.2 +ruff ==0.12.7 diff --git a/requirements-docs.txt b/requirements-docs.txt index 5c5701f73..24b79236c 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -1,6 +1,6 @@ -e . -r requirements-docs-tests.txt -mkdocs-material==9.6.15 +mkdocs-material==9.6.16 mdx-include >=1.4.1,<2.0.0 mkdocs-redirects>=1.2.1,<1.3.0 typer == 0.16.0 @@ -10,10 +10,10 @@ jieba==0.42.1 # For image processing by Material for MkDocs pillow==11.3.0 # For image processing by Material for MkDocs -cairosvg==2.7.1 +cairosvg==2.8.2 mkdocstrings[python]==0.26.1 griffe-typingdoc==0.2.8 # For griffe, it formats with black black==25.1.0 -mkdocs-macros-plugin==1.3.7 +mkdocs-macros-plugin==1.3.9 markdown-include-variants==0.0.4 diff --git a/requirements-github-actions.txt b/requirements-github-actions.txt index 920aefea6..a6a733447 100644 --- a/requirements-github-actions.txt +++ b/requirements-github-actions.txt @@ -1,6 +1,6 @@ PyGithub>=2.3.0,<3.0.0 pydantic>=2.5.3,<3.0.0 pydantic-settings>=2.1.0,<3.0.0 -httpx>=0.27.0,<0.28.0 +httpx>=0.27.0,<1.0.0 pyyaml >=5.3.1,<7.0.0 smokeshow diff --git a/requirements-tests.txt b/requirements-tests.txt index b9f2b2b66..53ec28d2e 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -2,14 +2,14 @@ -r requirements-docs-tests.txt pytest >=7.1.3,<9.0.0 coverage[toml] >= 6.5.0,< 8.0 -mypy ==1.8.0 +mypy ==1.14.1 dirty-equals ==0.9.0 sqlmodel==0.0.24 flask >=1.1.2,<4.0.0 anyio[trio] >=3.2.1,<5.0.0 -PyJWT==2.8.0 +PyJWT==2.9.0 pyyaml >=5.3.1,<7.0.0 -passlib[bcrypt] >=1.7.2,<2.0.0 +pwdlib[argon2] >=0.2.1 inline-snapshot>=0.21.1 # types types-ujson ==5.10.0.20240515 diff --git a/requirements-translations.txt b/requirements-translations.txt index 7a2a8004e..a62ba3ac1 100644 --- a/requirements-translations.txt +++ b/requirements-translations.txt @@ -1 +1,2 @@ -pydantic-ai==0.0.30 +pydantic-ai==0.4.10 +GitPython==3.1.45 diff --git a/scripts/deploy_docs_status.py b/scripts/deploy_docs_status.py index c652cdb6e..e620b15ba 100644 --- a/scripts/deploy_docs_status.py +++ b/scripts/deploy_docs_status.py @@ -1,7 +1,8 @@ import logging import re +from typing import Literal -from github import Github +from github import Auth, Github from pydantic import BaseModel, SecretStr from pydantic_settings import BaseSettings @@ -12,7 +13,7 @@ class Settings(BaseSettings): deploy_url: str | None = None commit_sha: str run_id: int - is_done: bool = False + state: Literal["pending", "success", "error"] = "pending" class LinkData(BaseModel): @@ -26,7 +27,7 @@ def main() -> None: settings = Settings() logging.info(f"Using config: {settings.model_dump_json()}") - g = Github(settings.github_token.get_secret_value()) + g = Github(auth=Auth.Token(settings.github_token.get_secret_value())) repo = g.get_repo(settings.github_repository) use_pr = next( (pr for pr in repo.get_pulls() if pr.head.sha == settings.commit_sha), None @@ -37,16 +38,7 @@ def main() -> None: commits = list(use_pr.get_commits()) current_commit = [c for c in commits if c.sha == settings.commit_sha][0] run_url = f"https://github.com/{settings.github_repository}/actions/runs/{settings.run_id}" - if settings.is_done and not settings.deploy_url: - current_commit.create_status( - state="success", - description="No Docs Changes", - context="deploy-docs", - target_url=run_url, - ) - logging.info("No docs changes found") - return - if not settings.deploy_url: + if settings.state == "pending": current_commit.create_status( state="pending", description="Deploying Docs", @@ -55,6 +47,26 @@ def main() -> None: ) logging.info("No deploy URL available yet") return + if settings.state == "error": + current_commit.create_status( + state="error", + description="Error Deploying Docs", + context="deploy-docs", + target_url=run_url, + ) + logging.info("Error deploying docs") + return + assert settings.state == "success" + if not settings.deploy_url: + current_commit.create_status( + state="success", + description="No Docs Changes", + context="deploy-docs", + target_url=run_url, + ) + logging.info("No docs changes found") + return + assert settings.deploy_url current_commit.create_status( state="success", description="Docs Deployed", @@ -104,7 +116,9 @@ def main() -> None: current_lang_links.sort(key=lambda x: x.preview_link) links.extend(current_lang_links) - message = f"📝 Docs preview for commit {settings.commit_sha} at: {deploy_url}" + header = "## 📝 Docs preview" + message = header + message += f"\n\nLast commit {settings.commit_sha} at: {deploy_url}" if links: message += "\n\n### Modified Pages\n\n" @@ -116,7 +130,17 @@ def main() -> None: message += "\n" print(message) - use_pr.as_issue().create_comment(message) + issue = use_pr.as_issue() + comments = list(issue.get_comments()) + for comment in comments: + if ( + comment.body.startswith(header) + and comment.user.login == "github-actions[bot]" + ): + comment.edit(message) + break + else: + issue.create_comment(message) logging.info("Finished") diff --git a/scripts/docs.py b/scripts/docs.py index 8462e2bc1..56ffb9d36 100644 --- a/scripts/docs.py +++ b/scripts/docs.py @@ -44,6 +44,8 @@ en_config_path: Path = en_docs_path / mkdocs_name site_path = Path("site").absolute() build_site_path = Path("site_build").absolute() +header_with_permalink_pattern = re.compile(r"^(#{1,6}) (.+?)(\s*\{\s*#.*\s*\})\s*$") + @lru_cache def is_mkdocs_insiders() -> bool: @@ -154,9 +156,21 @@ index_sponsors_template = """ """ +def remove_header_permalinks(content: str): + lines: list[str] = [] + for line in content.split("\n"): + match = header_with_permalink_pattern.match(line) + if match: + hashes, title, *_ = match.groups() + line = f"{hashes} {title}" + lines.append(line) + return "\n".join(lines) + + def generate_readme_content() -> str: en_index = en_docs_path / "docs" / "index.md" content = en_index.read_text("utf-8") + content = remove_header_permalinks(content) # remove permalinks from headers match_pre = re.search(r"\n\n", content) match_start = re.search(r"", content) match_end = re.search(r"", content) diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py index 0bc4929a4..b9e4ff59e 100644 --- a/scripts/mkdocs_hooks.py +++ b/scripts/mkdocs_hooks.py @@ -110,7 +110,7 @@ def generate_renamed_section_items( # Creating a new section makes it render it collapsed by default # no idea why, so, let's just modify the existing one # new_section = Section(title=new_title, children=new_children) - item.title = new_title + item.title = new_title.split("{ #")[0] item.children = new_children new_items.append(item) else: @@ -132,6 +132,15 @@ def on_pre_page(page: Page, *, config: MkDocsConfig, files: Files) -> Page: def on_page_markdown( markdown: str, *, page: Page, config: MkDocsConfig, files: Files ) -> str: + # Set matadata["social"]["cards_layout_options"]["title"] to clean title (without + # permalink) + title = page.title + clean_title = title.split("{ #")[0] + if clean_title: + page.meta.setdefault("social", {}) + page.meta["social"].setdefault("cards_layout_options", {}) + page.meta["social"]["cards_layout_options"]["title"] = clean_title + if isinstance(page.file, EnFile): for excluded_section in non_translated_sections: if page.file.src_path.startswith(excluded_section): diff --git a/scripts/translate.py b/scripts/translate.py index 9a2136d1b..ede101e8f 100644 --- a/scripts/translate.py +++ b/scripts/translate.py @@ -1,13 +1,20 @@ +import secrets +import subprocess +from collections.abc import Iterable from functools import lru_cache +from os import sep as pathsep from pathlib import Path -from typing import Iterable +from typing import Annotated +import git import typer import yaml +from github import Github from pydantic_ai import Agent +from rich import print non_translated_sections = ( - "reference/", + f"reference{pathsep}", "release-notes.md", "fastapi-people.md", "external-links.md", @@ -19,21 +26,655 @@ non_translated_sections = ( general_prompt = """ -For technical terms in English that don't have a common translation term use the original term in English. +### About literal text in this prompt -For code snippets or fragments, surrounded by backticks (`), don't translate the content, keep the original in English. For example, `list`, `dict`, keep them as is. +1) In the following instructions (after I say: `The above rules are in effect now`) the two characters `ÂĢ` and `Âģ` will be used to surround LITERAL TEXT, which is text or characters you shall interpret literally. The `ÂĢ` and the `Âģ` are not part of the literal text, they are the meta characters denoting it. -The content is written in markdown, write the translation in markdown as well. Don't add triple backticks (`) around the generated translation content. +2) Furthermore, text surrounded by `ÂĢÂĢÂĢ` and `ÂģÂģÂģ` is a BLOCK OF LITERAL TEXT which spans multiple lines. To get its content, dedent all lines of the block until the `ÂĢÂĢÂĢ` and `ÂģÂģÂģ` are at column zero, then remove the newline (`\n`) after the `ÂĢÂĢÂĢ` and the newline before the `ÂģÂģÂģ`. The `ÂĢÂĢÂĢ` and the `ÂģÂģÂģ` are not part of the literal text block, they are the meta characters denoting it. -When there's an example of code, the console or a terminal, normally surrounded by triple backticks and a keyword like "console" or "bash" (e.g. ```console), do not translate the content, keep the original in English. +3) If you see backticks or any other quotes inside literal text – inside `ÂĢ` and `Âģ` – or inside blocks of literal text – inside `ÂĢÂĢÂĢ` and `ÂģÂģÂģ` – then interpret them as literal characters, do NOT interpret them as meta characters. + +The above rules are in effect now. + + +### Definitions of terms used in this prompt + +"backtick" + + The character ÂĢ`Âģ + Unicode U+0060 (GRAVE ACCENT) + +"single backtick" + + A single backtick – ÂĢ`Âģ + +"triple backticks" + + Three backticks in a row – ÂĢ```Âģ + +"neutral double quote" + + The character ÂĢ"Âģ + Unicode U+0022 (QUOTATION MARK) + +"neutral single quote" + + The character ÂĢ'Âģ + Unicode U+0027 (APOSTROPHE) + +"English double typographic quotes" + + The characters ÂĢ“Âģ and ÂĢ”Âģ + Unicode U+201C (LEFT DOUBLE QUOTATION MARK) and Unicode U+201D (RIGHT DOUBLE QUOTATION MARK) + +"English single typographic quotes" + + The characters ÂĢ‘Âģ and ÂĢ’Âģ + Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and Unicode U+2019 (RIGHT SINGLE QUOTATION MARK) + +"code snippet" + + Also called "inline code". Text in a Markdown document which is surrounded by single backticks. A paragraph in a Markdown document can have a more than one code snippet. + + Example: + + ÂĢÂĢÂĢ + `i am a code snippet` + ÂģÂģÂģ + + Example: + + ÂĢÂĢÂĢ + `first code snippet` `second code snippet` `third code snippet` + ÂģÂģÂģ + +"code block" + + Text in a Markdown document which is surrounded by triple backticks. Spreads multiple lines. + + Example: + + ÂĢÂĢÂĢ + ``` + Hello + World + ``` + ÂģÂģÂģ + + Example: + + ÂĢÂĢÂĢ + ```python + print("hello World") + ``` + ÂģÂģÂģ + +"HTML element" + + a HTML opening tag – e.g. ÂĢ
Âģ – and a HTML closing tag – e.g. ÂĢ
Âģ – surrounding text or other HTML elements. + + +### Your task + +Translate an English text – the original content – to a target language. + +The original content is written in Markdown, write the translation in Markdown as well. + +The original content will be surrounded by triple percentage signs (ÂĢ%%%Âģ). Do not include the triple percentage signs in the translation. + + +### Technical terms in English + +For technical terms in English that don't have a common translation term, use the original term in English. + + +### Content of code snippets + +Do not translate the content of code snippets, keep the original in English. For example, ÂĢ`list`Âģ, ÂĢ`dict`Âģ, keep them as is. + + +### Content of code blocks + +Do not translate the content of code blocks, except for comments in the language which the code block uses. + +Examples: + + Source (English) – The code block is a bash code example with one comment: + + ÂĢÂĢÂĢ + ```bash + # Print greeting + echo "Hello, World!" + ``` + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + ```bash + # Gruß ausgeben + echo "Hello, World!" + ``` + ÂģÂģÂģ + + Source (English) – The code block is a console example containing HTML tags. No comments, so nothing to change here: + + ÂĢÂĢÂĢ + ```console + $ fastapi run main.py + FastAPI Starting server + Searching for package file structure + ``` + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + ```console + $ fastapi run main.py + FastAPI Starting server + Searching for package file structure + ``` + ÂģÂģÂģ + + Source (English) – The code block is a console example containing 5 comments: + + ÂĢÂĢÂĢ + ```console + // Go to the home directory + $ cd + // Create a directory for all your code projects + $ mkdir code + // Enter into that code directory + $ cd code + // Create a directory for this project + $ mkdir awesome-project + // Enter into that project directory + $ cd awesome-project + ``` + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + ```console + // Gehe zum Home-Verzeichnis + $ cd + // Erstelle ein Verzeichnis fÃŧr alle Ihre Code-Projekte + $ mkdir code + // Gehe in dieses Code-Verzeichnis + $ cd code + // Erstelle ein Verzeichnis fÃŧr dieses Projekt + $ mkdir awesome-project + // Gehe in dieses Projektverzeichnis + $ cd awesome-project + ``` + ÂģÂģÂģ + +If there is an existing translation and its Mermaid diagram is in sync with the Mermaid diagram in the English source, except a few translated words, then use the Mermaid diagram of the existing translation. The human editor of the translation translated these words in the Mermaid diagram. Keep these translations, do not revert them back to the English source. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + ```mermaid + flowchart LR + subgraph global[global env] + harry-1[harry v1] + end + subgraph stone-project[philosophers-stone project] + stone(philosophers-stone) -->|requires| harry-1 + end + ``` + ÂģÂģÂģ + + Existing translation (German) – has three translations: + + ÂĢÂĢÂĢ + ```mermaid + flowchart LR + subgraph global[globale Umgebung] + harry-1[harry v1] + end + subgraph stone-project[philosophers-stone-Projekt] + stone(philosophers-stone) -->|benÃļtigt| harry-1 + end + ``` + ÂģÂģÂģ + + Result (German) – you change nothing: + + ÂĢÂĢÂĢ + ```mermaid + flowchart LR + subgraph global[globale Umgebung] + harry-1[harry v1] + end + subgraph stone-project[philosophers-stone-Projekt] + stone(philosophers-stone) -->|benÃļtigt| harry-1 + end + ``` + ÂģÂģÂģ + + +### Special blocks + +There are special blocks of notes, tips and others that look like: + + ÂĢÂĢÂĢ + /// note + ÂģÂģÂģ + +To translate it, keep the same line and add the translation after a vertical bar. + +For example, if you were translating to Spanish, you would write: + + ÂĢÂĢÂĢ + /// note | Nota + ÂģÂģÂģ + +Some examples in Spanish: + + Source: + + ÂĢÂĢÂĢ + /// tip + ÂģÂģÂģ + + Result: + + ÂĢÂĢÂĢ + /// tip | Consejo + ÂģÂģÂģ + + Source: + + ÂĢÂĢÂĢ + /// details | Preview + ÂģÂģÂģ + + Result: + + ÂĢÂĢÂĢ + /// details | Vista previa + ÂģÂģÂģ + + +### Tab blocks + +There are special blocks surrounded by four slashes (ÂĢ////Âģ). They mark text, which will be rendered as part of a tab in the final document. The scheme is: + + //// tab | {tab title} + {tab content, may span many lines} + //// + +Keep everything before the vertical bar (ÂĢ|Âģ) as is, including the vertical bar. Translate the tab title. Translate the tab content, applying the rules you know. Keep the four block closing slashes as is. + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + //// tab | Python 3.8+ non-Annotated + Hello + //// + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + //// tab | Python 3.8+ nicht annotiert + Hallo + //// + ÂģÂģÂģ + + Source (English) – Here there is nothing to translate in the tab title: + + ÂĢÂĢÂĢ + //// tab | Linux, macOS, Windows Bash + Hello again + //// + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + //// tab | Linux, macOS, Windows Bash + Hallo wieder + //// + ÂģÂģÂģ + + +### Headings + +Every Markdown heading in the English text (all levels) ends with a part inside curly brackets. This part denotes the hash of this heading, which is used in links to this heading. In translations, translate the heading, but do not translate this hash part, so that links do not break. + +Examples of how to translate a heading: + + Source (English): + + ÂĢÂĢÂĢ + ## Alternative API docs { #alternative-api-docs } + ÂģÂģÂģ + + Result (Spanish): + + ÂĢÂĢÂĢ + ## DocumentaciÃŗn de la API alternativa { #alternative-api-docs } + ÂģÂģÂģ + + Source (English): + + ÂĢÂĢÂĢ + ### Example { #example } + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + ### Beispiel { #example } + ÂģÂģÂģ + + +### Links + +Use the following rules for links (apply both to Markdown-style links ([text](url)) and to HTML-style tags): + +1) For relative URLs, only translate link text. Do not translate the URL or its parts + +Example: + + Source (English): + + ÂĢÂĢÂĢ + [One of the fastest Python frameworks available](#performance) + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + [Eines der schnellsten verfÃŧgbaren Python-Frameworks](#performance) + ÂģÂģÂģ + +2) For absolute URLs which DO NOT start EXACTLY with ÂĢhttps://fastapi.tiangolo.comÂģ, only translate link text and leave the URL unchanged. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + SQLModel docs + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + SQLModel-Dokumentation + ÂģÂģÂģ + +3) For absolute URLs which DO start EXACTLY with ÂĢhttps://fastapi.tiangolo.comÂģ, only translate link text and change the URL by adding language code (ÂĢhttps://fastapi.tiangolo.com/{language_code}[rest part of the url]Âģ). + +Example: + + Source (English): + + ÂĢÂĢÂĢ + Documentation + ÂģÂģÂģ + + Result (Spanish): + + ÂĢÂĢÂĢ + DocumentaciÃŗn + ÂģÂģÂģ + +3.1) Do not add language codes for URLs that point to static assets (e.g., images, CSS, JavaScript). + +Example: + + Source (English): + + ÂĢÂĢÂĢ + Something + ÂģÂģÂģ + + Result (Spanish): + + ÂĢÂĢÂĢ + Algo + ÂģÂģÂģ + +4) For internal links, only translate link text. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + [Create Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + [Pull Requests erzeugen](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} + ÂģÂģÂģ + +5) Do not translate anchor fragments in links (the part after ÂĢ#Âģ), as they must remain the same to work correctly. + +5.1) If an existing translation has a link with an anchor fragment different to the anchor fragment in the English source, then this is an error. Fix this by using the anchor fragment of the English source. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + [Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank} + ÂģÂģÂģ + + Existing wrong translation (German) – notice the wrongly translated anchor fragment: + + ÂĢÂĢÂĢ + [Body – Mehrere Parameter: Einfache Werte im Body](body-multiple-params.md#einzelne-werte-im-body){.internal-link target=_blank}. + ÂģÂģÂģ + + Result (German) – you fix the anchor fragment: + + ÂĢÂĢÂĢ + [Body – Mehrere Parameter: Einfache Werte im Body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}. + ÂģÂģÂģ + +5.2) Do not add anchor fragments at will, even if this makes sense. If the English source has no anchor, don't add one. + +Example: + + Source (English): + + ÂĢÂĢÂĢ + Create a [virtual environment](../virtual-environments.md){.internal-link target=_blank} + ÂģÂģÂģ + + Wrong translation (German) – Anchor added to the URL. + + ÂĢÂĢÂĢ + Erstelle eine [virtuelle Umgebung](../virtual-environments.md#create-a-virtual-environment){.internal-link target=_blank} + ÂģÂģÂģ + + Good translation (German) – URL stays like in the English source. + + ÂĢÂĢÂĢ + Erstelle eine [Virtuelle Umgebung](../virtual-environments.md){.internal-link target=_blank} + ÂģÂģÂģ + + +### HTML abbr elements + +Translate HTML abbr elements (ÂĢtextÂģ) as follows: + +1) If the text surrounded by the abbr element is an abbreviation (the text may be surrounded by further HTML or Markdown markup or quotes, for example ÂĢtextÂģ or ÂĢ`text`Âģ or ÂĢ"text"Âģ, ignore that further markup when deciding if the text is an abbreviation), and if the description (the text inside the title attribute) contains the full phrase for this abbreviation, then append a dash (ÂĢ–Âģ) to the full phrase, followed by the translation of the full phrase. + +Conversion scheme: + + Source (English): + + {abbreviation} + + Result: + + {abbreviation} + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + IoT + CPU + TL;DR: + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + IoT + CPU + TL;DR: + ÂģÂģÂģ + +1.1) If the language to which you translate mostly uses the letters of the ASCII char set (for example Spanish, French, German, but not Russian, Chinese) and if the translation of the full phrase is identical to, or starts with the same letters as the original full phrase, then only give the translation of the full phrase. + +Conversion scheme: + + Source (English): + + {abbreviation} + + Result: + + {abbreviation} + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + JWT + Enum + ASGI + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + JWT + Enum + ASGI + ÂģÂģÂģ + +2) If the description is not a full phrase for an abbreviation which the abbr element surrounds, but some other information, then just translate the description. + +Conversion scheme: + + Source (English): + + {text} + + Result: + + {translation of text} + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + path + linter + parsing + 0.95.0 + at the time of writing this + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + Pfad + Linter + Parsen + 0.95.0 + zum Zeitpunkt als das hier geschrieben wurde + ÂģÂģÂģ + + +3) If the text surrounded by the abbr element is an abbreviation and the description contains both the full phrase for that abbreviation, and other information, separated by a colon (ÂĢ:Âģ), then append a dash (ÂĢ–Âģ) and the translation of the full phrase to the original full phrase and translate the other information. + +Conversion scheme: + + Source (English): + + {abbreviation} + + Result: + + {abbreviation} + +Examples: + + Source (English): + + ÂĢÂĢÂĢ + I/O + CDN + IDE + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + I/O + CDN + IDE + ÂģÂģÂģ + +3.1) Like in rule 2.1, you can leave the original full phrase away, if the translated full phrase is identical or starts with the same letters as the original full phrase. + +Conversion scheme: + + Source (English): + + {abbreviation} + + Result: + + {abbreviation} + +Example: + + Source (English): + + ÂĢÂĢÂĢ + ORM + ÂģÂģÂģ + + Result (German): + + ÂĢÂĢÂĢ + ORM + ÂģÂģÂģ + +4) If there is an existing translation, and it has ADDITIONAL abbr elements in a sentence, and these additional abbr elements do not exist in the related sentence in the English text, then KEEP those additional abbr elements in the translation. Do not remove them. Except when you remove the whole sentence from the translation, because the whole sentence was removed from the English text, then also remove the abbr element. The reasoning for this rule is, that such additional abbr elements are manually added by the human editor of the translation, in order to translate or explain an English word to the human readers of the translation. These additional abbr elements would not make sense in the English text, but they do make sense in the translation. So keep them in the translation, even though they are not part of the English text. This rule only applies to abbr elements. + +5) Apply above rules also when there is an existing translation! Make sure that all title attributes in abbr elements get properly translated or updated, using the schemes given above. However, leave the ADDITIONAL abbr's from rule 4 alone. Do not change their formatting or content. -The original content will be surrounded by triple percentage signs (%) and you should translate it to the target language. Do not include the triple percentage signs in the translation. """ +app = typer.Typer() + @lru_cache def get_langs() -> dict[str, str]: - return yaml.safe_load(Path("docs/language_names.yml").read_text()) + return yaml.safe_load(Path("docs/language_names.yml").read_text(encoding="utf-8")) def generate_lang_path(*, lang: str, path: Path) -> Path: @@ -46,56 +687,87 @@ def generate_lang_path(*, lang: str, path: Path) -> Path: return out_path -def translate_page(*, lang: str, path: Path) -> None: +def generate_en_path(*, lang: str, path: Path) -> Path: + en_docs_path = Path("docs/en/docs") + assert not str(path).startswith(str(en_docs_path)), ( + f"Path must not be inside {en_docs_path}" + ) + lang_docs_path = Path(f"docs/{lang}/docs") + out_path = Path(str(path).replace(str(lang_docs_path), str(en_docs_path))) + return out_path + + +@app.command() +def translate_page( + *, + language: Annotated[str, typer.Option(envvar="LANGUAGE")], + en_path: Annotated[Path, typer.Option(envvar="EN_PATH")], +) -> None: + assert language != "en", ( + "`en` is the source language, choose another language as translation target" + ) langs = get_langs() - language = langs[lang] - lang_path = Path(f"docs/{lang}") + language_name = langs[language] + lang_path = Path(f"docs/{language}") lang_path.mkdir(exist_ok=True) lang_prompt_path = lang_path / "llm-prompt.md" assert lang_prompt_path.exists(), f"Prompt file not found: {lang_prompt_path}" - lang_prompt_content = lang_prompt_path.read_text() + lang_prompt_content = lang_prompt_path.read_text(encoding="utf-8") en_docs_path = Path("docs/en/docs") - assert str(path).startswith(str(en_docs_path)), ( + assert str(en_path).startswith(str(en_docs_path)), ( f"Path must be inside {en_docs_path}" ) - out_path = generate_lang_path(lang=lang, path=path) + out_path = generate_lang_path(lang=language, path=en_path) out_path.parent.mkdir(parents=True, exist_ok=True) - original_content = path.read_text() + original_content = en_path.read_text(encoding="utf-8") old_translation: str | None = None if out_path.exists(): - old_translation = out_path.read_text() - agent = Agent("openai:gpt-4o") + print(f"Found existing translation: {out_path}") + old_translation = out_path.read_text(encoding="utf-8") + print(f"Translating {en_path} to {language} ({language_name})") + agent = Agent("openai:gpt-5") prompt_segments = [ - lang_prompt_content, general_prompt, + lang_prompt_content, ] if old_translation: prompt_segments.extend( [ - "There's an existing previous translation for this content that is probably outdated with old content or old instructions.", - "Update the translation given your current instructions and the original content.", - "If you have instructions to translate specific terms or phrases in a specific way, please follow those instructions instead of keeping the old and outdated content.", + "There is an existing previous translation for the original English content, that may be outdated.", + "Update the translation only where necessary:", + "- If the original English content has added parts, also add these parts to the translation.", + "- If the original English content has removed parts, also remove them from the translation, unless you were instructed earlier to not do that in specific cases.", + "- If parts of the original English content have changed, also change those parts in the translation.", + "- If the previous translation violates current instructions, update it.", + "- Otherwise, preserve the original translation LINE-BY-LINE, AS-IS.", + "Do not:", + "- rephrase or rewrite correct lines just to improve the style.", + "- add or remove line breaks, unless the original English content changed.", + "- change formatting or whitespace unless absolutely required.", + "Only change what must be changed. The goal is to minimize diffs for easier human review.", + "UNLESS you were instructed earlier to behave different, there MUST NOT be whole sentences or partial sentences in the updated translation, which are not in the original English content, and there MUST NOT be whole sentences or partial sentences in the original English content, which are not in the updated translation. Remember: the updated translation shall be IN SYNC with the original English content.", "Previous translation:", f"%%%\n{old_translation}%%%", ] ) prompt_segments.extend( [ - f"Translate to {language} ({lang}).", + f"Translate to {language} ({language_name}).", "Original content:", f"%%%\n{original_content}%%%", ] ) prompt = "\n\n".join(prompt_segments) - + print(f"Running agent for {out_path}") result = agent.run_sync(prompt) - out_content = f"{result.data.strip()}\n" - out_path.write_text(out_content) + out_content = f"{result.output.strip()}\n" + print(f"Saving translation to {out_path}") + out_path.write_text(out_content, encoding="utf-8", newline="\n") -def iter_paths_to_translate() -> Iterable[Path]: +def iter_all_en_paths() -> Iterable[Path]: """ Iterate on the markdown files to translate in order of priority. """ @@ -119,12 +791,17 @@ def iter_paths_to_translate() -> Iterable[Path]: yield path -def translate_all(lang: str) -> None: - paths_to_process: list[Path] = [] - for path in iter_paths_to_translate(): - if str(path).replace("docs/en/docs/", "").startswith(non_translated_sections): - continue - paths_to_process.append(path) +def iter_en_paths_to_translate() -> Iterable[Path]: + en_docs_root = Path("docs/en/docs/") + for path in iter_all_en_paths(): + relpath = path.relative_to(en_docs_root) + if not str(relpath).startswith(non_translated_sections): + yield path + + +@app.command() +def translate_lang(language: Annotated[str, typer.Option(envvar="LANGUAGE")]) -> None: + paths_to_process = list(iter_en_paths_to_translate()) print("Original paths:") for p in paths_to_process: print(f" - {p}") @@ -132,7 +809,7 @@ def translate_all(lang: str) -> None: missing_paths: list[Path] = [] skipped_paths: list[Path] = [] for p in paths_to_process: - lang_path = generate_lang_path(lang=lang, path=p) + lang_path = generate_lang_path(lang=language, path=p) if lang_path.exists(): skipped_paths.append(p) continue @@ -147,16 +824,158 @@ def translate_all(lang: str) -> None: print(f"Total paths to process: {len(missing_paths)}") for p in missing_paths: print(f"Translating: {p}") - translate_page(lang="es", path=p) + translate_page(language="es", en_path=p) print(f"Done translating: {p}") -def main(*, lang: str, path: Path = None) -> None: - if path: - translate_page(lang=lang, path=path) - else: - translate_all(lang=lang) +@app.command() +def list_removable(language: str) -> list[Path]: + removable_paths: list[Path] = [] + lang_paths = Path(f"docs/{language}").rglob("*.md") + for path in lang_paths: + en_path = generate_en_path(lang=language, path=path) + if not en_path.exists(): + removable_paths.append(path) + print(removable_paths) + return removable_paths + + +@app.command() +def list_all_removable() -> list[Path]: + all_removable_paths: list[Path] = [] + langs = get_langs() + for lang in langs: + if lang == "en": + continue + removable_paths = list_removable(lang) + all_removable_paths.extend(removable_paths) + print(all_removable_paths) + return all_removable_paths + + +@app.command() +def remove_removable(language: str) -> None: + removable_paths = list_removable(language) + for path in removable_paths: + path.unlink() + print(f"Removed: {path}") + print("Done removing all removable paths") + + +@app.command() +def remove_all_removable() -> None: + all_removable = list_all_removable() + for removable_path in all_removable: + removable_path.unlink() + print(f"Removed: {removable_path}") + print("Done removing all removable paths") + + +@app.command() +def list_missing(language: str) -> list[Path]: + missing_paths: list[Path] = [] + en_lang_paths = list(iter_en_paths_to_translate()) + for path in en_lang_paths: + lang_path = generate_lang_path(lang=language, path=path) + if not lang_path.exists(): + missing_paths.append(path) + print(missing_paths) + return missing_paths + + +@app.command() +def list_outdated(language: str) -> list[Path]: + dir_path = Path(__file__).absolute().parent.parent + repo = git.Repo(dir_path) + + outdated_paths: list[Path] = [] + en_lang_paths = list(iter_en_paths_to_translate()) + for path in en_lang_paths: + lang_path = generate_lang_path(lang=language, path=path) + if not lang_path.exists(): + continue + en_commit_datetime = list(repo.iter_commits(paths=path, max_count=1))[ + 0 + ].committed_datetime + lang_commit_datetime = list(repo.iter_commits(paths=lang_path, max_count=1))[ + 0 + ].committed_datetime + if lang_commit_datetime < en_commit_datetime: + outdated_paths.append(path) + print(outdated_paths) + return outdated_paths + + +@app.command() +def update_outdated(language: Annotated[str, typer.Option(envvar="LANGUAGE")]) -> None: + outdated_paths = list_outdated(language) + for path in outdated_paths: + print(f"Updating lang: {language} path: {path}") + translate_page(language=language, en_path=path) + print(f"Done updating: {path}") + print("Done updating all outdated paths") + + +@app.command() +def add_missing(language: Annotated[str, typer.Option(envvar="LANGUAGE")]) -> None: + missing_paths = list_missing(language) + for path in missing_paths: + print(f"Adding lang: {language} path: {path}") + translate_page(language=language, en_path=path) + print(f"Done adding: {path}") + print("Done adding all missing paths") + + +@app.command() +def update_and_add(language: Annotated[str, typer.Option(envvar="LANGUAGE")]) -> None: + print(f"Updating outdated translations for {language}") + update_outdated(language=language) + print(f"Adding missing translations for {language}") + add_missing(language=language) + print(f"Done updating and adding for {language}") + + +@app.command() +def make_pr( + *, + language: Annotated[str | None, typer.Option(envvar="LANGUAGE")] = None, + github_token: Annotated[str, typer.Option(envvar="GITHUB_TOKEN")], + github_repository: Annotated[str, typer.Option(envvar="GITHUB_REPOSITORY")], +) -> None: + print("Setting up GitHub Actions git user") + repo = git.Repo(Path(__file__).absolute().parent.parent) + if not repo.is_dirty(untracked_files=True): + print("Repository is clean, no changes to commit") + return + subprocess.run(["git", "config", "user.name", "github-actions"], check=True) + subprocess.run( + ["git", "config", "user.email", "github-actions@github.com"], check=True + ) + branch_name = "translate" + if language: + branch_name += f"-{language}" + branch_name += f"-{secrets.token_hex(4)}" + print(f"Creating a new branch {branch_name}") + subprocess.run(["git", "checkout", "-b", branch_name], check=True) + print("Adding updated files") + git_path = Path("docs") + subprocess.run(["git", "add", str(git_path)], check=True) + print("Committing updated file") + message = "🌐 Update translations" + if language: + message += f" for {language}" + subprocess.run(["git", "commit", "-m", message], check=True) + print("Pushing branch") + subprocess.run(["git", "push", "origin", branch_name], check=True) + print("Creating PR") + g = Github(github_token) + gh_repo = g.get_repo(github_repository) + pr = gh_repo.create_pull( + title=message, body=message, base="master", head=branch_name + ) + print(f"Created PR: {pr.number}") + print("Finished") if __name__ == "__main__": - typer.run(main) + app() diff --git a/tests/main.py b/tests/main.py index 6927eab61..2f1d61711 100644 --- a/tests/main.py +++ b/tests/main.py @@ -3,7 +3,12 @@ from typing import FrozenSet, List, Optional from fastapi import FastAPI, Path, Query -app = FastAPI() +external_docs = { + "description": "External API documentation.", + "url": "https://docs.example.com/api-general", +} + +app = FastAPI(openapi_external_docs=external_docs) @app.api_route("/api_route") diff --git a/tests/test_application.py b/tests/test_application.py index a7d50ea72..8f1b0a18d 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -58,6 +58,10 @@ def test_openapi_schema(): assert response.json() == { "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, + "externalDocs": { + "description": "External API documentation.", + "url": "https://docs.example.com/api-general", + }, "paths": { "/api_route": { "get": { diff --git a/tests/test_compat.py b/tests/test_compat.py index f4a3093c5..43c686489 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -80,6 +80,51 @@ def test_complex(): assert response2.json() == [1, 2] +@needs_pydanticv2 +def test_propagates_pydantic2_model_config(): + app = FastAPI() + + class Missing: + def __bool__(self): + return False + + class EmbeddedModel(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + value: Union[str, Missing] = Missing() + + class Model(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + ) + value: Union[str, Missing] = Missing() + embedded_model: EmbeddedModel = EmbeddedModel() + + @app.post("/") + def foo(req: Model) -> Dict[str, Union[str, None]]: + return { + "value": req.value or None, + "embedded_value": req.embedded_model.value or None, + } + + client = TestClient(app) + + response = client.post("/", json={}) + assert response.status_code == 200, response.text + assert response.json() == { + "value": None, + "embedded_value": None, + } + + response2 = client.post( + "/", json={"value": "foo", "embedded_model": {"value": "bar"}} + ) + assert response2.status_code == 200, response2.text + assert response2.json() == { + "value": "foo", + "embedded_value": "bar", + } + + def test_is_bytes_sequence_annotation_union(): # For coverage # TODO: in theory this would allow declaring types that could be lists of bytes diff --git a/tests/test_custom_schema_fields.py b/tests/test_custom_schema_fields.py index ee51fc7ff..d890291b1 100644 --- a/tests/test_custom_schema_fields.py +++ b/tests/test_custom_schema_fields.py @@ -1,7 +1,13 @@ +from typing import Optional + from fastapi import FastAPI from fastapi._compat import PYDANTIC_V2 from fastapi.testclient import TestClient from pydantic import BaseModel +from typing_extensions import Annotated + +if PYDANTIC_V2: + from pydantic import WithJsonSchema app = FastAPI() @@ -10,12 +16,17 @@ class Item(BaseModel): name: str if PYDANTIC_V2: + description: Annotated[ + Optional[str], WithJsonSchema({"type": ["string", "null"]}) + ] = None + model_config = { "json_schema_extra": { "x-something-internal": {"level": 4}, } } else: + description: Optional[str] = None # type: ignore[no-redef] class Config: schema_extra = { @@ -42,7 +53,11 @@ item_schema = { "name": { "title": "Name", "type": "string", - } + }, + "description": { + "title": "Description", + "type": ["string", "null"] if PYDANTIC_V2 else "string", + }, }, } @@ -57,4 +72,4 @@ def test_response(): # For coverage response = client.get("/foo") assert response.status_code == 200, response.text - assert response.json() == {"name": "Foo item"} + assert response.json() == {"name": "Foo item", "description": None} diff --git a/tests/test_dependency_after_yield_raise.py b/tests/test_dependency_after_yield_raise.py new file mode 100644 index 000000000..b560dc36f --- /dev/null +++ b/tests/test_dependency_after_yield_raise.py @@ -0,0 +1,69 @@ +from typing import Any + +import pytest +from fastapi import Depends, FastAPI, HTTPException +from fastapi.testclient import TestClient +from typing_extensions import Annotated + + +class CustomError(Exception): + pass + + +def catching_dep() -> Any: + try: + yield "s" + except CustomError as err: + raise HTTPException(status_code=418, detail="Session error") from err + + +def broken_dep() -> Any: + yield "s" + raise ValueError("Broken after yield") + + +app = FastAPI() + + +@app.get("/catching") +def catching(d: Annotated[str, Depends(catching_dep)]) -> Any: + raise CustomError("Simulated error during streaming") + + +@app.get("/broken") +def broken(d: Annotated[str, Depends(broken_dep)]) -> Any: + return {"message": "all good?"} + + +client = TestClient(app) + + +def test_catching(): + response = client.get("/catching") + assert response.status_code == 418 + assert response.json() == {"detail": "Session error"} + + +def test_broken_raise(): + with pytest.raises(ValueError, match="Broken after yield"): + client.get("/broken") + + +def test_broken_no_raise(): + """ + When a dependency with yield raises after the yield (not in an except), the + response is already "successfully" sent back to the client, but there's still + an error in the server afterwards, an exception is raised and captured or shown + in the server logs. + """ + with TestClient(app, raise_server_exceptions=False) as client: + response = client.get("/broken") + assert response.status_code == 200 + assert response.json() == {"message": "all good?"} + + +def test_broken_return_finishes(): + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/broken") + assert response.status_code == 200 + assert response.json() == {"message": "all good?"} diff --git a/tests/test_dependency_after_yield_streaming.py b/tests/test_dependency_after_yield_streaming.py new file mode 100644 index 000000000..7e1c8822b --- /dev/null +++ b/tests/test_dependency_after_yield_streaming.py @@ -0,0 +1,130 @@ +from contextlib import contextmanager +from typing import Any, Generator + +import pytest +from fastapi import Depends, FastAPI +from fastapi.responses import StreamingResponse +from fastapi.testclient import TestClient +from typing_extensions import Annotated + + +class Session: + def __init__(self) -> None: + self.data = ["foo", "bar", "baz"] + self.open = True + + def __iter__(self) -> Generator[str, None, None]: + for item in self.data: + if self.open: + yield item + else: + raise ValueError("Session closed") + + +@contextmanager +def acquire_session() -> Generator[Session, None, None]: + session = Session() + try: + yield session + finally: + session.open = False + + +def dep_session() -> Any: + with acquire_session() as s: + yield s + + +def broken_dep_session() -> Any: + with acquire_session() as s: + s.open = False + yield s + + +SessionDep = Annotated[Session, Depends(dep_session)] +BrokenSessionDep = Annotated[Session, Depends(broken_dep_session)] + +app = FastAPI() + + +@app.get("/data") +def get_data(session: SessionDep) -> Any: + data = list(session) + return data + + +@app.get("/stream-simple") +def get_stream_simple(session: SessionDep) -> Any: + def iter_data(): + yield from ["x", "y", "z"] + + return StreamingResponse(iter_data()) + + +@app.get("/stream-session") +def get_stream_session(session: SessionDep) -> Any: + def iter_data(): + yield from session + + return StreamingResponse(iter_data()) + + +@app.get("/broken-session-data") +def get_broken_session_data(session: BrokenSessionDep) -> Any: + return list(session) + + +@app.get("/broken-session-stream") +def get_broken_session_stream(session: BrokenSessionDep) -> Any: + def iter_data(): + yield from session + + return StreamingResponse(iter_data()) + + +client = TestClient(app) + + +def test_regular_no_stream(): + response = client.get("/data") + assert response.json() == ["foo", "bar", "baz"] + + +def test_stream_simple(): + response = client.get("/stream-simple") + assert response.text == "xyz" + + +def test_stream_session(): + response = client.get("/stream-session") + assert response.text == "foobarbaz" + + +def test_broken_session_data(): + with pytest.raises(ValueError, match="Session closed"): + client.get("/broken-session-data") + + +def test_broken_session_data_no_raise(): + client = TestClient(app, raise_server_exceptions=False) + response = client.get("/broken-session-data") + assert response.status_code == 500 + assert response.text == "Internal Server Error" + + +def test_broken_session_stream_raise(): + # Can raise ValueError on Pydantic v2 and ExceptionGroup on Pydantic v1 + with pytest.raises((ValueError, Exception)): + client.get("/broken-session-stream") + + +def test_broken_session_stream_no_raise(): + """ + When a dependency with yield raises after the streaming response already started + the 200 status code is already sent, but there's still an error in the server + afterwards, an exception is raised and captured or shown in the server logs. + """ + with TestClient(app, raise_server_exceptions=False) as client: + response = client.get("/broken-session-stream") + assert response.status_code == 200 + assert response.text == "" diff --git a/tests/test_dependency_after_yield_websockets.py b/tests/test_dependency_after_yield_websockets.py new file mode 100644 index 000000000..7c323c338 --- /dev/null +++ b/tests/test_dependency_after_yield_websockets.py @@ -0,0 +1,79 @@ +from contextlib import contextmanager +from typing import Any, Generator + +import pytest +from fastapi import Depends, FastAPI, WebSocket +from fastapi.testclient import TestClient +from typing_extensions import Annotated + + +class Session: + def __init__(self) -> None: + self.data = ["foo", "bar", "baz"] + self.open = True + + def __iter__(self) -> Generator[str, None, None]: + for item in self.data: + if self.open: + yield item + else: + raise ValueError("Session closed") + + +@contextmanager +def acquire_session() -> Generator[Session, None, None]: + session = Session() + try: + yield session + finally: + session.open = False + + +def dep_session() -> Any: + with acquire_session() as s: + yield s + + +def broken_dep_session() -> Any: + with acquire_session() as s: + s.open = False + yield s + + +SessionDep = Annotated[Session, Depends(dep_session)] +BrokenSessionDep = Annotated[Session, Depends(broken_dep_session)] + +app = FastAPI() + + +@app.websocket("/ws") +async def websocket_endpoint(websocket: WebSocket, session: SessionDep): + await websocket.accept() + for item in session: + await websocket.send_text(f"{item}") + + +@app.websocket("/ws-broken") +async def websocket_endpoint_broken(websocket: WebSocket, session: BrokenSessionDep): + await websocket.accept() + for item in session: + await websocket.send_text(f"{item}") # pragma no cover + + +client = TestClient(app) + + +def test_websocket_dependency_after_yield(): + with client.websocket_connect("/ws") as websocket: + data = websocket.receive_text() + assert data == "foo" + data = websocket.receive_text() + assert data == "bar" + data = websocket.receive_text() + assert data == "baz" + + +def test_websocket_dependency_after_yield_broken(): + with pytest.raises(ValueError, match="Session closed"): + with client.websocket_connect("/ws-broken"): + pass # pragma no cover diff --git a/tests/test_dependency_contextmanager.py b/tests/test_dependency_contextmanager.py index 039c423b9..02c10458c 100644 --- a/tests/test_dependency_contextmanager.py +++ b/tests/test_dependency_contextmanager.py @@ -286,12 +286,12 @@ def test_background_tasks(): assert data["context_a"] == "started a" assert data["bg"] == "not set" middleware_state = json.loads(response.headers["x-state"]) - assert middleware_state["context_b"] == "finished b with a: started a" - assert middleware_state["context_a"] == "finished a" + assert middleware_state["context_b"] == "started b" + assert middleware_state["context_a"] == "started a" assert middleware_state["bg"] == "not set" assert state["context_b"] == "finished b with a: started a" assert state["context_a"] == "finished a" - assert state["bg"] == "bg set - b: finished b with a: started a - a: finished a" + assert state["bg"] == "bg set - b: started b - a: started a" def test_sync_raise_raises(): @@ -397,7 +397,4 @@ def test_sync_background_tasks(): assert data["sync_bg"] == "not set" assert state["context_b"] == "finished b with a: started a" assert state["context_a"] == "finished a" - assert ( - state["sync_bg"] - == "sync_bg set - b: finished b with a: started a - a: finished a" - ) + assert state["sync_bg"] == "sync_bg set - b: started b - a: started a" diff --git a/tests/test_dependency_normal_exceptions.py b/tests/test_dependency_yield_except_httpexception.py similarity index 100% rename from tests/test_dependency_normal_exceptions.py rename to tests/test_dependency_yield_except_httpexception.py diff --git a/tests/test_enforce_once_required_parameter.py b/tests/test_enforce_once_required_parameter.py index 30329282f..2e5ac6c06 100644 --- a/tests/test_enforce_once_required_parameter.py +++ b/tests/test_enforce_once_required_parameter.py @@ -102,7 +102,7 @@ def test_schema(): def test_get_invalid(): response = client.get("/foo") - assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY + assert response.status_code == 422 def test_get_valid(): diff --git a/tests/test_file_and_form_order_issue_9116.py b/tests/test_file_and_form_order_issue_9116.py new file mode 100644 index 000000000..cb9a31d31 --- /dev/null +++ b/tests/test_file_and_form_order_issue_9116.py @@ -0,0 +1,90 @@ +""" +Regression test, Error 422 if Form is declared before File +See https://github.com/tiangolo/fastapi/discussions/9116 +""" + +from pathlib import Path +from typing import List + +import pytest +from fastapi import FastAPI, File, Form +from fastapi.testclient import TestClient +from typing_extensions import Annotated + +app = FastAPI() + + +@app.post("/file_before_form") +def file_before_form( + file: bytes = File(), + city: str = Form(), +): + return {"file_content": file, "city": city} + + +@app.post("/file_after_form") +def file_after_form( + city: str = Form(), + file: bytes = File(), +): + return {"file_content": file, "city": city} + + +@app.post("/file_list_before_form") +def file_list_before_form( + files: Annotated[List[bytes], File()], + city: Annotated[str, Form()], +): + return {"file_contents": files, "city": city} + + +@app.post("/file_list_after_form") +def file_list_after_form( + city: Annotated[str, Form()], + files: Annotated[List[bytes], File()], +): + return {"file_contents": files, "city": city} + + +client = TestClient(app) + + +@pytest.fixture +def tmp_file_1(tmp_path: Path) -> Path: + f = tmp_path / "example1.txt" + f.write_text("foo") + return f + + +@pytest.fixture +def tmp_file_2(tmp_path: Path) -> Path: + f = tmp_path / "example2.txt" + f.write_text("bar") + return f + + +@pytest.mark.parametrize("endpoint_path", ("/file_before_form", "/file_after_form")) +def test_file_form_order(endpoint_path: str, tmp_file_1: Path): + response = client.post( + url=endpoint_path, + data={"city": "Thimphou"}, + files={"file": (tmp_file_1.name, tmp_file_1.read_bytes())}, + ) + assert response.status_code == 200, response.text + assert response.json() == {"file_content": "foo", "city": "Thimphou"} + + +@pytest.mark.parametrize( + "endpoint_path", ("/file_list_before_form", "/file_list_after_form") +) +def test_file_list_form_order(endpoint_path: str, tmp_file_1: Path, tmp_file_2: Path): + response = client.post( + url=endpoint_path, + data={"city": "Thimphou"}, + files=( + ("files", (tmp_file_1.name, tmp_file_1.read_bytes())), + ("files", (tmp_file_2.name, tmp_file_2.read_bytes())), + ), + ) + assert response.status_code == 200, response.text + assert response.json() == {"file_contents": ["foo", "bar"], "city": "Thimphou"} diff --git a/tests/test_get_model_definitions_formfeed_escape.py b/tests/test_get_model_definitions_formfeed_escape.py new file mode 100644 index 000000000..f77195dc5 --- /dev/null +++ b/tests/test_get_model_definitions_formfeed_escape.py @@ -0,0 +1,180 @@ +from typing import Any, Iterator, Set, Type + +import fastapi._compat +import fastapi.openapi.utils +import pydantic.schema +import pytest +from fastapi import FastAPI +from pydantic import BaseModel +from starlette.testclient import TestClient + +from .utils import needs_pydanticv1 + + +class Address(BaseModel): + """ + This is a public description of an Address + \f + You can't see this part of the docstring, it's private! + """ + + line_1: str + city: str + state_province: str + + +class Facility(BaseModel): + id: str + address: Address + + +app = FastAPI() + +client = TestClient(app) + + +@app.get("/facilities/{facility_id}") +def get_facility(facility_id: str) -> Facility: ... + + +openapi_schema = { + "components": { + "schemas": { + "Address": { + # NOTE: the description of this model shows only the public-facing text, before the `\f` in docstring + "description": "This is a public description of an Address\n", + "properties": { + "city": {"title": "City", "type": "string"}, + "line_1": {"title": "Line 1", "type": "string"}, + "state_province": {"title": "State Province", "type": "string"}, + }, + "required": ["line_1", "city", "state_province"], + "title": "Address", + "type": "object", + }, + "Facility": { + "properties": { + "address": {"$ref": "#/components/schemas/Address"}, + "id": {"title": "Id", "type": "string"}, + }, + "required": ["id", "address"], + "title": "Facility", + "type": "object", + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": {"$ref": "#/components/schemas/ValidationError"}, + "title": "Detail", + "type": "array", + } + }, + "title": "HTTPValidationError", + "type": "object", + }, + "ValidationError": { + "properties": { + "loc": { + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, + "title": "Location", + "type": "array", + }, + "msg": {"title": "Message", "type": "string"}, + "type": {"title": "Error Type", "type": "string"}, + }, + "required": ["loc", "msg", "type"], + "title": "ValidationError", + "type": "object", + }, + } + }, + "info": {"title": "FastAPI", "version": "0.1.0"}, + "openapi": "3.1.0", + "paths": { + "/facilities/{facility_id}": { + "get": { + "operationId": "get_facility_facilities__facility_id__get", + "parameters": [ + { + "in": "path", + "name": "facility_id", + "required": True, + "schema": {"title": "Facility Id", "type": "string"}, + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {"$ref": "#/components/schemas/Facility"} + } + }, + "description": "Successful Response", + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error", + }, + }, + "summary": "Get Facility", + } + } + }, +} + + +def test_openapi_schema(): + """ + Sanity check to ensure our app's openapi schema renders as we expect + """ + response = client.get("/openapi.json") + assert response.status_code == 200, response.text + assert response.json() == openapi_schema + + +class SortedTypeSet(set): + """ + Set of Types whose `__iter__()` method yields results sorted by the type names + """ + + def __init__(self, seq: Set[Type[Any]], *, sort_reversed: bool): + super().__init__(seq) + self.sort_reversed = sort_reversed + + def __iter__(self) -> Iterator[Type[Any]]: + members_sorted = sorted( + super().__iter__(), + key=lambda type_: type_.__name__, + reverse=self.sort_reversed, + ) + yield from members_sorted + + +@needs_pydanticv1 +@pytest.mark.parametrize("sort_reversed", [True, False]) +def test_model_description_escaped_with_formfeed(sort_reversed: bool): + """ + Regression test for bug fixed by https://github.com/fastapi/fastapi/pull/6039. + + Test `get_model_definitions` with models passed in different order. + """ + all_fields = fastapi.openapi.utils.get_fields_from_routes(app.routes) + + flat_models = fastapi._compat.get_flat_models_from_fields( + all_fields, known_models=set() + ) + model_name_map = pydantic.schema.get_model_name_map(flat_models) + + expected_address_description = "This is a public description of an Address\n" + + models = fastapi._compat.get_model_definitions( + flat_models=SortedTypeSet(flat_models, sort_reversed=sort_reversed), + model_name_map=model_name_map, + ) + assert models["Address"]["description"] == expected_address_description diff --git a/tests/test_jsonable_encoder.py b/tests/test_jsonable_encoder.py index 1906d6bf1..447c5b4d6 100644 --- a/tests/test_jsonable_encoder.py +++ b/tests/test_jsonable_encoder.py @@ -216,9 +216,12 @@ def test_custom_encoders(): instance = MyModel(dt_field=safe_datetime.now()) encoded_instance = jsonable_encoder( - instance, custom_encoder={safe_datetime: lambda o: o.isoformat()} + instance, custom_encoder={safe_datetime: lambda o: o.strftime("%H:%M:%S")} ) - assert encoded_instance["dt_field"] == instance.dt_field.isoformat() + assert encoded_instance["dt_field"] == instance.dt_field.strftime("%H:%M:%S") + + encoded_instance2 = jsonable_encoder(instance) + assert encoded_instance2["dt_field"] == instance.dt_field.isoformat() def test_custom_enum_encoders(): diff --git a/tests/test_openapi_schema_type.py b/tests/test_openapi_schema_type.py new file mode 100644 index 000000000..a45ea20c8 --- /dev/null +++ b/tests/test_openapi_schema_type.py @@ -0,0 +1,26 @@ +from typing import List, Optional, Union + +import pytest +from fastapi.openapi.models import Schema, SchemaType + + +@pytest.mark.parametrize( + "type_value", + [ + "array", + ["string", "null"], + None, + ], +) +def test_allowed_schema_type( + type_value: Optional[Union[SchemaType, List[SchemaType]]], +) -> None: + """Test that Schema accepts SchemaType, List[SchemaType] and None for type field.""" + schema = Schema(type=type_value) + assert schema.type == type_value + + +def test_invalid_type_value() -> None: + """Test that Schema raises ValueError for invalid type values.""" + with pytest.raises(ValueError, match="2 validation errors for Schema"): + Schema(type=True) # type: ignore[arg-type] diff --git a/tests/test_response_model_default_factory.py b/tests/test_response_model_default_factory.py new file mode 100644 index 000000000..13c1f442b --- /dev/null +++ b/tests/test_response_model_default_factory.py @@ -0,0 +1,47 @@ +from fastapi import FastAPI +from fastapi.testclient import TestClient +from pydantic import BaseModel, Field + +app = FastAPI() + + +class ResponseModel(BaseModel): + code: int = 200 + message: str = Field(default_factory=lambda: "Successful operation.") + + +@app.get( + "/response_model_has_default_factory_return_dict", + response_model=ResponseModel, +) +async def response_model_has_default_factory_return_dict(): + return {"code": 200} + + +@app.get( + "/response_model_has_default_factory_return_model", + response_model=ResponseModel, +) +async def response_model_has_default_factory_return_model(): + return ResponseModel() + + +client = TestClient(app) + + +def test_response_model_has_default_factory_return_dict(): + response = client.get("/response_model_has_default_factory_return_dict") + + assert response.status_code == 200, response.text + + assert response.json()["code"] == 200 + assert response.json()["message"] == "Successful operation." + + +def test_response_model_has_default_factory_return_model(): + response = client.get("/response_model_has_default_factory_return_model") + + assert response.status_code == 200, response.text + + assert response.json()["code"] == 200 + assert response.json()["message"] == "Successful operation." diff --git a/tests/test_return_none_stringified_annotations.py b/tests/test_return_none_stringified_annotations.py new file mode 100644 index 000000000..be052d532 --- /dev/null +++ b/tests/test_return_none_stringified_annotations.py @@ -0,0 +1,17 @@ +import http + +from fastapi import FastAPI +from fastapi.testclient import TestClient + + +def test_no_content(): + app = FastAPI() + + @app.get("/no-content", status_code=http.HTTPStatus.NO_CONTENT) + def return_no_content() -> "None": + return + + client = TestClient(app) + response = client.get("/no-content") + assert response.status_code == http.HTTPStatus.NO_CONTENT, response.text + assert not response.content diff --git a/tests/test_route_scope.py b/tests/test_route_scope.py index 2021c828f..792ea66c3 100644 --- a/tests/test_route_scope.py +++ b/tests/test_route_scope.py @@ -47,4 +47,4 @@ def test_websocket(): def test_websocket_invalid_path_doesnt_match(): with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/itemsx/portal-gun"): - pass + pass # pragma: no cover diff --git a/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py b/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py new file mode 100644 index 000000000..f13046e01 --- /dev/null +++ b/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py @@ -0,0 +1,21 @@ +from fastapi.testclient import TestClient + +from docs_src.behind_a_proxy.tutorial001_01 import app + +client = TestClient( + app, + base_url="https://example.com", + follow_redirects=False, +) + + +def test_redirect() -> None: + response = client.get("/items") + assert response.status_code == 307 + assert response.headers["location"] == "https://example.com/items/" + + +def test_no_redirect() -> None: + response = client.get("/items/") + assert response.status_code == 200 + assert response.json() == ["plumbus", "portal gun"] diff --git a/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py b/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py index 6f7355aaa..647f1c5dd 100644 --- a/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py +++ b/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py @@ -1,4 +1,4 @@ -from dirty_equals import IsDict +from dirty_equals import IsDict, IsOneOf from fastapi.testclient import TestClient from docs_src.custom_request_and_route.tutorial002 import app @@ -24,14 +24,16 @@ def test_exception_handler_body_access(): "input": {"numbers": [1, 2, 3]}, } ], - "body": '{"numbers": [1, 2, 3]}', + # httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363 + "body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'), } } ) | IsDict( # TODO: remove when deprecating Pydantic v1 { "detail": { - "body": '{"numbers": [1, 2, 3]}', + # httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363 + "body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'), "errors": [ { "loc": ["body"], diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008c.py b/tests/test_tutorial/test_dependencies/test_tutorial008c.py index 11e96bf46..369b0a221 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008c.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008c.py @@ -40,7 +40,7 @@ def test_fastapi_error(mod: ModuleType): client = TestClient(mod.app) with pytest.raises(FastAPIError) as exc_info: client.get("/items/portal-gun") - assert "No response object was returned" in exc_info.value.args[0] + assert "raising an exception and a dependency with yield" in exc_info.value.args[0] def test_internal_server_error(mod: ModuleType): diff --git a/tests/test_tutorial/test_header_params/test_tutorial003.py b/tests/test_tutorial/test_header_params/test_tutorial003.py index 0b58227f6..473b96123 100644 --- a/tests/test_tutorial/test_header_params/test_tutorial003.py +++ b/tests/test_tutorial/test_header_params/test_tutorial003.py @@ -29,8 +29,12 @@ def get_client(request: pytest.FixtureRequest): [ ("/items", None, 200, {"X-Token values": None}), ("/items", {"x-token": "foo"}, 200, {"X-Token values": ["foo"]}), - # TODO: fix this, is it a bug? - # ("/items", [("x-token", "foo"), ("x-token", "bar")], 200, {"X-Token values": ["foo", "bar"]}), + ( + "/items", + [("x-token", "foo"), ("x-token", "bar")], + 200, + {"X-Token values": ["foo", "bar"]}, + ), ], ) def test(path, headers, expected_status, expected_response, client: TestClient): diff --git a/tests/test_tutorial/test_response_model/test_tutorial003.py b/tests/test_tutorial/test_response_model/test_tutorial003.py index 384c8e0f1..70cfd6e4c 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003.py @@ -1,12 +1,27 @@ +import importlib + +import pytest from dirty_equals import IsDict, IsOneOf from fastapi.testclient import TestClient -from docs_src.response_model.tutorial003 import app - -client = TestClient(app) +from ...utils import needs_py310 -def test_post_user(): +@pytest.fixture( + name="client", + params=[ + "tutorial003", + pytest.param("tutorial003_py310", marks=needs_py310), + ], +) +def get_client(request: pytest.FixtureRequest): + mod = importlib.import_module(f"docs_src.response_model.{request.param}") + + client = TestClient(mod.app) + return client + + +def test_post_user(client: TestClient): response = client.post( "/user/", json={ @@ -24,7 +39,7 @@ def test_post_user(): } -def test_openapi_schema(): +def test_openapi_schema(client: TestClient): response = client.get("/openapi.json") assert response.status_code == 200, response.text assert response.json() == { diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_04.py b/tests/test_tutorial/test_response_model/test_tutorial003_04.py index 4aa80145a..f32e93ddc 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003_04.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003_04.py @@ -1,9 +1,18 @@ +import importlib + import pytest from fastapi.exceptions import FastAPIError +from ...utils import needs_py310 -def test_invalid_response_model(): + +@pytest.mark.parametrize( + "module_name", + [ + "tutorial003_04", + pytest.param("tutorial003_04_py310", marks=needs_py310), + ], +) +def test_invalid_response_model(module_name: str) -> None: with pytest.raises(FastAPIError): - from docs_src.response_model.tutorial003_04 import app - - assert app # pragma: no cover + importlib.import_module(f"docs_src.response_model.{module_name}") diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_04_py310.py b/tests/test_tutorial/test_response_model/test_tutorial003_04_py310.py deleted file mode 100644 index b876facc8..000000000 --- a/tests/test_tutorial/test_response_model/test_tutorial003_04_py310.py +++ /dev/null @@ -1,12 +0,0 @@ -import pytest -from fastapi.exceptions import FastAPIError - -from ...utils import needs_py310 - - -@needs_py310 -def test_invalid_response_model(): - with pytest.raises(FastAPIError): - from docs_src.response_model.tutorial003_04_py310 import app - - assert app # pragma: no cover diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_py310.py b/tests/test_tutorial/test_response_model/test_tutorial003_py310.py deleted file mode 100644 index 3a3aee38a..000000000 --- a/tests/test_tutorial/test_response_model/test_tutorial003_py310.py +++ /dev/null @@ -1,160 +0,0 @@ -import pytest -from dirty_equals import IsDict, IsOneOf -from fastapi.testclient import TestClient - -from ...utils import needs_py310 - - -@pytest.fixture(name="client") -def get_client(): - from docs_src.response_model.tutorial003_py310 import app - - client = TestClient(app) - return client - - -@needs_py310 -def test_post_user(client: TestClient): - response = client.post( - "/user/", - json={ - "username": "foo", - "password": "fighter", - "email": "foo@example.com", - "full_name": "Grave Dohl", - }, - ) - assert response.status_code == 200, response.text - assert response.json() == { - "username": "foo", - "email": "foo@example.com", - "full_name": "Grave Dohl", - } - - -@needs_py310 -def test_openapi_schema(client: TestClient): - response = client.get("/openapi.json") - assert response.status_code == 200, response.text - assert response.json() == { - "openapi": "3.1.0", - "info": {"title": "FastAPI", "version": "0.1.0"}, - "paths": { - "/user/": { - "post": { - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/UserOut"} - } - }, - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - }, - }, - }, - "summary": "Create User", - "operationId": "create_user_user__post", - "requestBody": { - "content": { - "application/json": { - "schema": {"$ref": "#/components/schemas/UserIn"} - } - }, - "required": True, - }, - } - } - }, - "components": { - "schemas": { - "UserOut": { - "title": "UserOut", - "required": IsOneOf( - ["username", "email", "full_name"], - # TODO: remove when deprecating Pydantic v1 - ["username", "email"], - ), - "type": "object", - "properties": { - "username": {"title": "Username", "type": "string"}, - "email": { - "title": "Email", - "type": "string", - "format": "email", - }, - "full_name": IsDict( - { - "title": "Full Name", - "anyOf": [{"type": "string"}, {"type": "null"}], - } - ) - | IsDict( - # TODO: remove when deprecating Pydantic v1 - {"title": "Full Name", "type": "string"} - ), - }, - }, - "UserIn": { - "title": "UserIn", - "required": ["username", "password", "email"], - "type": "object", - "properties": { - "username": {"title": "Username", "type": "string"}, - "password": {"title": "Password", "type": "string"}, - "email": { - "title": "Email", - "type": "string", - "format": "email", - }, - "full_name": IsDict( - { - "title": "Full Name", - "anyOf": [{"type": "string"}, {"type": "null"}], - } - ) - | IsDict( - # TODO: remove when deprecating Pydantic v1 - {"title": "Full Name", "type": "string"} - ), - }, - }, - "ValidationError": { - "title": "ValidationError", - "required": ["loc", "msg", "type"], - "type": "object", - "properties": { - "loc": { - "title": "Location", - "type": "array", - "items": { - "anyOf": [{"type": "string"}, {"type": "integer"}] - }, - }, - "msg": {"title": "Message", "type": "string"}, - "type": {"title": "Error Type", "type": "string"}, - }, - }, - "HTTPValidationError": { - "title": "HTTPValidationError", - "type": "object", - "properties": { - "detail": { - "title": "Detail", - "type": "array", - "items": {"$ref": "#/components/schemas/ValidationError"}, - } - }, - }, - } - }, - } diff --git a/tests/test_tutorial/test_testing/test_tutorial004.py b/tests/test_tutorial/test_testing/test_tutorial004.py new file mode 100644 index 000000000..812ee44c1 --- /dev/null +++ b/tests/test_tutorial/test_testing/test_tutorial004.py @@ -0,0 +1,5 @@ +from docs_src.app_testing.tutorial004 import test_read_items + + +def test_main(): + test_read_items()