diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 52c34a49e..dd11727c7 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -7,6 +7,10 @@ on:
types:
- opened
- synchronize
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
changes:
runs-on: ubuntu-latest
@@ -48,18 +52,20 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.11"
- - uses: actions/cache@v4
- id: cache
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt', 'requirements-docs-insiders.txt', 'requirements-docs-tests.txt') }}-v08
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install docs extras
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-docs.txt
+ run: uv pip install -r requirements-docs.txt
# Install MkDocs Material Insiders here just to put it in the cache for the rest of the steps
- name: Install Material for MkDocs Insiders
- if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-docs-insiders.txt
+ if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
+ run: uv pip install -r requirements-docs-insiders.txt
env:
TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
- name: Verify Docs
@@ -88,17 +94,19 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.11"
- - uses: actions/cache@v4
- id: cache
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt', 'requirements-docs-insiders.txt', 'requirements-docs-tests.txt') }}-v08
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install docs extras
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-docs.txt
+ run: uv pip install -r requirements-docs.txt
- name: Install Material for MkDocs Insiders
- if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-docs-insiders.txt
+ if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
+ run: uv pip install -r requirements-docs-insiders.txt
env:
TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
- name: Update Languages
diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
index d2953f284..387063f12 100644
--- a/.github/workflows/deploy-docs.yml
+++ b/.github/workflows/deploy-docs.yml
@@ -12,6 +12,9 @@ permissions:
pull-requests: write
statuses: write
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
deploy-docs:
runs-on: ubuntu-latest
@@ -25,21 +28,22 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.11"
- - uses: actions/cache@v4
- id: cache
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-github-actions-${{ env.pythonLocation }}-${{ hashFiles('requirements-github-actions.txt') }}-v01
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install GitHub Actions dependencies
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-github-actions.txt
+ run: uv pip install -r requirements-github-actions.txt
- name: Deploy Docs Status Pending
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 }}
-
- name: Clean site
run: |
rm -rf ./site
@@ -55,19 +59,22 @@ jobs:
# hashFiles returns an empty string if there are no files
if: hashFiles('./site/*')
id: deploy
- uses: cloudflare/pages-action@v1
+ env:
+ PROJECT_NAME: fastapitiangolo
+ BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
+ # TODO: Use v3 when it's fixed, probably in v3.11
+ # https://github.com/cloudflare/wrangler-action/issues/307
+ uses: cloudflare/wrangler-action@v3.12
+ # uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- projectName: fastapitiangolo
- directory: './site'
- gitHubToken: ${{ secrets.GITHUB_TOKEN }}
- branch: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
+ command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
- name: Comment Deploy
run: python ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- DEPLOY_URL: ${{ steps.deploy.outputs.url }}
+ DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
RUN_ID: ${{ github.run_id }}
IS_DONE: "true"
diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml
index d5b947a9c..6a7e6143e 100644
--- a/.github/workflows/issue-manager.yml
+++ b/.github/workflows/issue-manager.yml
@@ -2,7 +2,7 @@ name: Issue Manager
on:
schedule:
- - cron: "10 3 * * *"
+ - cron: "13 22 * * *"
issue_comment:
types:
- created
@@ -16,6 +16,7 @@ on:
permissions:
issues: write
+ pull-requests: write
jobs:
issue-manager:
@@ -26,7 +27,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: tiangolo/issue-manager@0.5.0
+ - uses: tiangolo/issue-manager@0.5.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
@@ -35,8 +36,12 @@ jobs:
"delay": 864000,
"message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
},
- "changes-requested": {
+ "waiting": {
"delay": 2628000,
- "message": "As this PR had requested changes to be applied but has been inactive for a while, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
+ "message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
+ },
+ "invalid": {
+ "delay": 0,
+ "message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
}
}
diff --git a/.github/workflows/label-approved.yml b/.github/workflows/label-approved.yml
index 0470fb606..11176bed8 100644
--- a/.github/workflows/label-approved.yml
+++ b/.github/workflows/label-approved.yml
@@ -8,6 +8,9 @@ on:
permissions:
pull-requests: write
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
label-approved:
if: github.repository_owner == 'fastapi'
@@ -17,10 +20,26 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: docker://tiangolo/label-approved:0.0.4
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
with:
- token: ${{ secrets.GITHUB_TOKEN }}
- config: >
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install GitHub Actions dependencies
+ run: uv pip install -r requirements-github-actions.txt
+ - name: Label Approved
+ run: python ./scripts/label_approved.py
+ env:
+ TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CONFIG: >
{
"approved-1":
{
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index c3bb83f9a..e8e58015a 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -17,6 +17,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
+ if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
+ - run: echo "Done adding labels"
# Run this after labeler applied labels
check-labels:
needs:
diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml
index 16da3bc63..b8b5c42ee 100644
--- a/.github/workflows/latest-changes.yml
+++ b/.github/workflows/latest-changes.yml
@@ -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.1
+ - uses: tiangolo/latest-changes@0.3.2
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 4787f3ddd..98aa41e5a 100644
--- a/.github/workflows/notify-translations.yml
+++ b/.github/workflows/notify-translations.yml
@@ -18,6 +18,9 @@ on:
permissions:
discussions: write
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
notify-translations:
runs-on: ubuntu-latest
@@ -27,6 +30,19 @@ jobs:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 5004b94dd..fc61c3fca 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -35,7 +35,7 @@ jobs:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
run: python -m build
- name: Publish
- uses: pypa/gh-action-pypi-publish@v1.10.1
+ uses: pypa/gh-action-pypi-publish@v1.12.2
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml
index d3a975df5..daff8e244 100644
--- a/.github/workflows/smokeshow.yml
+++ b/.github/workflows/smokeshow.yml
@@ -8,6 +8,9 @@ on:
permissions:
statuses: write
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
smokeshow:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
@@ -18,19 +21,25 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
-
- - run: pip install smokeshow
-
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - run: uv pip install -r requirements-github-actions.txt
- uses: actions/download-artifact@v4
with:
name: coverage-html
path: htmlcov
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
-
- run: smokeshow upload htmlcov
env:
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index e9db49b51..643037a12 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,6 +12,9 @@ on:
# cron every week on monday
- cron: "0 0 * * 1"
+env:
+ UV_SYSTEM_PYTHON: 1
+
jobs:
lint:
runs-on: ubuntu-latest
@@ -25,19 +28,18 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.11"
- # Issue ref: https://github.com/actions/setup-python/issues/436
- # cache: "pip"
- # cache-dependency-path: pyproject.toml
- - uses: actions/cache@v4
- id: cache
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt', 'requirements-docs-tests.txt') }}-test-v08
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install Dependencies
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-tests.txt
+ run: uv pip install -r requirements-tests.txt
- name: Install Pydantic v2
- run: pip install "pydantic>=2.0.2,<3.0.0"
+ run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
- name: Lint
run: bash scripts/lint.sh
@@ -63,23 +65,22 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- # Issue ref: https://github.com/actions/setup-python/issues/436
- # cache: "pip"
- # cache-dependency-path: pyproject.toml
- - uses: actions/cache@v4
- id: cache
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
with:
- path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt', 'requirements-docs-tests.txt') }}-test-v08
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
- name: Install Dependencies
- if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -r requirements-tests.txt
+ run: uv pip install -r requirements-tests.txt
- name: Install Pydantic v1
if: matrix.pydantic-version == 'pydantic-v1'
- run: pip install "pydantic>=1.10.0,<2.0.0"
+ run: uv pip install "pydantic>=1.10.0,<2.0.0"
- name: Install Pydantic v2
if: matrix.pydantic-version == 'pydantic-v2'
- run: pip install "pydantic>=2.0.2,<3.0.0"
+ run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
- run: mkdir coverage
- name: Test
run: bash scripts/test.sh
@@ -105,16 +106,22 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.8'
- # Issue ref: https://github.com/actions/setup-python/issues/436
- # cache: "pip"
- # cache-dependency-path: pyproject.toml
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v3
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-tests.txt
- name: Get coverage files
uses: actions/download-artifact@v4
with:
pattern: coverage-*
path: coverage
merge-multiple: true
- - run: pip install coverage[toml]
- run: ls -la coverage
- run: coverage combine coverage
- run: coverage report
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 317514062..d90e7281e 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: v4.6.0
+ rev: v5.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.6.2
+ rev: v0.7.2
hooks:
- id: ruff
args:
diff --git a/README.md b/README.md
index 5554f71d4..62eeda03b 100644
--- a/README.md
+++ b/README.md
@@ -52,11 +52,11 @@ The key features are:
-
+
-
+
@@ -96,7 +96,7 @@ The key features are:
"_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._"
-
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie die automatische Vervollständigung für `name` und `price`, welche in der FastAPI-Anwendung im `Item`-Modell definiert wurden.
@@ -150,7 +150,7 @@ Beispielsweise könnten Sie einen Abschnitt für **Items (Artikel)** und einen w
//// tab | Python 3.9+
```Python hl_lines="21 26 34"
-{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial002_py39.py!}
```
////
@@ -158,7 +158,7 @@ Beispielsweise könnten Sie einen Abschnitt für **Items (Artikel)** und einen w
//// tab | Python 3.8+
```Python hl_lines="23 28 36"
-{!> ../../../docs_src/generate_clients/tutorial002.py!}
+{!> ../../docs_src/generate_clients/tutorial002.py!}
```
////
@@ -211,7 +211,7 @@ Anschließend können Sie diese benutzerdefinierte Funktion als Parameter `gener
//// tab | Python 3.9+
```Python hl_lines="6-7 10"
-{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial003_py39.py!}
```
////
@@ -219,7 +219,7 @@ Anschließend können Sie diese benutzerdefinierte Funktion als Parameter `gener
//// tab | Python 3.8+
```Python hl_lines="8-9 12"
-{!> ../../../docs_src/generate_clients/tutorial003.py!}
+{!> ../../docs_src/generate_clients/tutorial003.py!}
```
////
@@ -247,7 +247,7 @@ Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dan
//// tab | Python
```Python
-{!> ../../../docs_src/generate_clients/tutorial004.py!}
+{!> ../../docs_src/generate_clients/tutorial004.py!}
```
////
@@ -255,7 +255,7 @@ Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dan
//// tab | Node.js
```Javascript
-{!> ../../../docs_src/generate_clients/tutorial004.js!}
+{!> ../../docs_src/generate_clients/tutorial004.js!}
```
////
diff --git a/docs/de/docs/advanced/index.md b/docs/de/docs/advanced/index.md
index 953ad317d..d93cd5fe8 100644
--- a/docs/de/docs/advanced/index.md
+++ b/docs/de/docs/advanced/index.md
@@ -6,7 +6,7 @@ Das Haupt-[Tutorial – Benutzerhandbuch](../tutorial/index.md){.internal-link t
In den nächsten Abschnitten sehen Sie weitere Optionen, Konfigurationen und zusätzliche Funktionen.
-/// tip | "Tipp"
+/// tip | Tipp
Die nächsten Abschnitte sind **nicht unbedingt „fortgeschritten“**.
diff --git a/docs/de/docs/advanced/middleware.md b/docs/de/docs/advanced/middleware.md
index 8912225fb..d2130c9b7 100644
--- a/docs/de/docs/advanced/middleware.md
+++ b/docs/de/docs/advanced/middleware.md
@@ -43,7 +43,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
**FastAPI** enthält mehrere Middlewares für gängige Anwendungsfälle. Wir werden als Nächstes sehen, wie man sie verwendet.
-/// note | "Technische Details"
+/// note | Technische Details
Für die nächsten Beispiele könnten Sie auch `from starlette.middleware.something import SomethingMiddleware` verwenden.
@@ -58,7 +58,7 @@ Erzwingt, dass alle eingehenden Requests entweder `https` oder `wss` sein müsse
Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial001.py!}
+{!../../docs_src/advanced_middleware/tutorial001.py!}
```
## `TrustedHostMiddleware`
@@ -66,7 +66,7 @@ Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere
Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
```Python hl_lines="2 6-8"
-{!../../../docs_src/advanced_middleware/tutorial002.py!}
+{!../../docs_src/advanced_middleware/tutorial002.py!}
```
Die folgenden Argumente werden unterstützt:
@@ -82,7 +82,7 @@ Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`
Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial003.py!}
+{!../../docs_src/advanced_middleware/tutorial003.py!}
```
Die folgenden Argumente werden unterstützt:
diff --git a/docs/de/docs/advanced/openapi-callbacks.md b/docs/de/docs/advanced/openapi-callbacks.md
index d7b5bc885..4ee2874a3 100644
--- a/docs/de/docs/advanced/openapi-callbacks.md
+++ b/docs/de/docs/advanced/openapi-callbacks.md
@@ -32,10 +32,10 @@ Sie verfügt über eine *Pfadoperation*, die einen `Invoice`-Body empfängt, und
Dieser Teil ist ziemlich normal, der größte Teil des Codes ist Ihnen wahrscheinlich bereits bekannt:
```Python hl_lines="9-13 36-53"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Der Query-Parameter `callback_url` verwendet einen Pydantic-Url-Typ.
@@ -64,7 +64,7 @@ Diese Dokumentation wird in der Swagger-Oberfläche unter `/docs` in Ihrer API a
In diesem Beispiel wird nicht der Callback selbst implementiert (das könnte nur eine Codezeile sein), sondern nur der Dokumentationsteil.
-/// tip | "Tipp"
+/// tip | Tipp
Der eigentliche Callback ist nur ein HTTP-Request.
@@ -80,7 +80,7 @@ Sie wissen jedoch bereits, wie Sie mit **FastAPI** ganz einfach eine automatisch
Daher werden wir dasselbe Wissen nutzen, um zu dokumentieren, wie die *externe API* aussehen sollte ... indem wir die *Pfadoperation(en)* erstellen, welche die externe API implementieren soll (die, welche Ihre API aufruft).
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie den Code zum Dokumentieren eines Callbacks schreiben, kann es hilfreich sein, sich vorzustellen, dass Sie dieser *externe Entwickler* sind. Und dass Sie derzeit die *externe API* implementieren, nicht *Ihre API*.
@@ -93,7 +93,7 @@ Wenn Sie diese Sichtweise (des *externen Entwicklers*) vorübergehend übernehme
Erstellen Sie zunächst einen neuen `APIRouter`, der einen oder mehrere Callbacks enthält.
```Python hl_lines="3 25"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
### Die Callback-*Pfadoperation* erstellen
@@ -106,7 +106,7 @@ Sie sollte wie eine normale FastAPI-*Pfadoperation* aussehen:
* Und sie könnte auch eine Deklaration der Response enthalten, die zurückgegeben werden soll, z. B. `response_model=InvoiceEventReceived`.
```Python hl_lines="16-18 21-22 28-32"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
@@ -163,7 +163,7 @@ und sie würde eine Response von dieser *externen API* mit einem JSON-Body wie d
}
```
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass die verwendete Callback-URL die URL enthält, die als Query-Parameter in `callback_url` (`https://www.external.org/events`) empfangen wurde, und auch die Rechnungs-`id` aus dem JSON-Body (`2expen51ve`).
@@ -176,10 +176,10 @@ An diesem Punkt haben Sie die benötigte(n) *Callback-Pfadoperation(en)* (diejen
Verwenden Sie nun den Parameter `callbacks` im *Pfadoperation-Dekorator Ihrer API*, um das Attribut `.routes` (das ist eigentlich nur eine `list`e von Routen/*Pfadoperationen*) dieses Callback-Routers zu übergeben:
```Python hl_lines="35"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass Sie nicht den Router selbst (`invoices_callback_router`) an `callback=` übergeben, sondern das Attribut `.routes`, wie in `invoices_callback_router.routes`.
diff --git a/docs/de/docs/advanced/openapi-webhooks.md b/docs/de/docs/advanced/openapi-webhooks.md
index fb0daa908..9f1bb6959 100644
--- a/docs/de/docs/advanced/openapi-webhooks.md
+++ b/docs/de/docs/advanced/openapi-webhooks.md
@@ -33,7 +33,7 @@ Webhooks sind in OpenAPI 3.1.0 und höher verfügbar und werden von FastAPI `0.9
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()`.
```Python hl_lines="9-13 36-53"
-{!../../../docs_src/openapi_webhooks/tutorial001.py!}
+{!../../docs_src/openapi_webhooks/tutorial001.py!}
```
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
diff --git a/docs/de/docs/advanced/path-operation-advanced-configuration.md b/docs/de/docs/advanced/path-operation-advanced-configuration.md
index c9cb82fe3..53d395724 100644
--- a/docs/de/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/de/docs/advanced/path-operation-advanced-configuration.md
@@ -2,7 +2,7 @@
## OpenAPI operationId
-/// warning | "Achtung"
+/// warning | Achtung
Wenn Sie kein „Experte“ für OpenAPI sind, brauchen Sie dies wahrscheinlich nicht.
@@ -13,7 +13,7 @@ Mit dem Parameter `operation_id` können Sie die OpenAPI `operationId` festlegen
Sie müssten sicherstellen, dass sie für jede Operation eindeutig ist.
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId
@@ -23,16 +23,16 @@ Wenn Sie die Funktionsnamen Ihrer API als `operationId`s verwenden möchten, kö
Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefügt haben.
```Python hl_lines="2 12-21 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie `app.openapi()` manuell aufrufen, sollten Sie vorher die `operationId`s aktualisiert haben.
///
-/// warning | "Achtung"
+/// warning | Achtung
Wenn Sie dies tun, müssen Sie sicherstellen, dass jede Ihrer *Pfadoperation-Funktionen* einen eindeutigen Namen hat.
@@ -45,7 +45,7 @@ Auch wenn diese sich in unterschiedlichen Modulen (Python-Dateien) befinden.
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`:
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## Fortgeschrittene Beschreibung mittels Docstring
@@ -57,7 +57,7 @@ Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu,
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) können den Rest verwenden.
```Python hl_lines="19-29"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```
## Zusätzliche Responses
@@ -74,7 +74,7 @@ Es gibt hier in der Dokumentation ein ganzes Kapitel darüber, Sie können es un
Wenn Sie in Ihrer Anwendung eine *Pfadoperation* deklarieren, generiert **FastAPI** automatisch die relevanten Metadaten dieser *Pfadoperation*, die in das OpenAPI-Schema aufgenommen werden sollen.
-/// note | "Technische Details"
+/// note | Technische Details
In der OpenAPI-Spezifikation wird das Operationsobjekt genannt.
@@ -86,7 +86,7 @@ Es enthält `tags`, `parameters`, `requestBody`, `responses`, usw.
Dieses *Pfadoperation*-spezifische OpenAPI-Schema wird normalerweise automatisch von **FastAPI** generiert, Sie können es aber auch erweitern.
-/// tip | "Tipp"
+/// tip | Tipp
Dies ist ein Low-Level Erweiterungspunkt.
@@ -101,7 +101,7 @@ Sie können das OpenAPI-Schema für eine *Pfadoperation* erweitern, indem Sie de
Dieses `openapi_extra` kann beispielsweise hilfreich sein, um OpenAPI-Erweiterungen zu deklarieren:
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
```
Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
@@ -150,7 +150,7 @@ Sie könnten sich beispielsweise dafür entscheiden, den Request mit Ihrem eigen
Das könnte man mit `openapi_extra` machen:
```Python hl_lines="20-37 39-40"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
```
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.
@@ -168,7 +168,7 @@ In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Fu
//// tab | Pydantic v2
```Python hl_lines="17-22 24"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
////
@@ -176,7 +176,7 @@ In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Fu
//// tab | Pydantic v1
```Python hl_lines="17-22 24"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
```
////
@@ -196,7 +196,7 @@ Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann
//// tab | Pydantic v2
```Python hl_lines="26-33"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
////
@@ -204,7 +204,7 @@ Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann
//// tab | Pydantic v1
```Python hl_lines="26-33"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
```
////
@@ -215,7 +215,7 @@ In Pydantic Version 1 war die Methode zum Parsen und Validieren eines Objekts `I
///
-/// tip | "Tipp"
+/// tip | Tipp
Hier verwenden wir dasselbe Pydantic-Modell wieder.
diff --git a/docs/de/docs/advanced/response-change-status-code.md b/docs/de/docs/advanced/response-change-status-code.md
index bba908a3e..202df0d87 100644
--- a/docs/de/docs/advanced/response-change-status-code.md
+++ b/docs/de/docs/advanced/response-change-status-code.md
@@ -21,7 +21,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
Anschließend können Sie den `status_code` in diesem *vorübergehenden* Response-Objekt festlegen.
```Python hl_lines="1 9 12"
-{!../../../docs_src/response_change_status_code/tutorial001.py!}
+{!../../docs_src/response_change_status_code/tutorial001.py!}
```
Und dann können Sie wie gewohnt jedes benötigte Objekt zurückgeben (ein `dict`, ein Datenbankmodell usw.).
diff --git a/docs/de/docs/advanced/response-cookies.md b/docs/de/docs/advanced/response-cookies.md
index 3d2043565..6f9d66e07 100644
--- a/docs/de/docs/advanced/response-cookies.md
+++ b/docs/de/docs/advanced/response-cookies.md
@@ -7,7 +7,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
Und dann können Sie Cookies in diesem *vorübergehenden* Response-Objekt setzen.
```Python hl_lines="1 8-9"
-{!../../../docs_src/response_cookies/tutorial002.py!}
+{!../../docs_src/response_cookies/tutorial002.py!}
```
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
@@ -27,10 +27,10 @@ Dazu können Sie eine Response erstellen, wie unter [Eine Response direkt zurüc
Setzen Sie dann Cookies darin und geben Sie sie dann zurück:
```Python hl_lines="10-12"
-{!../../../docs_src/response_cookies/tutorial001.py!}
+{!../../docs_src/response_cookies/tutorial001.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass, wenn Sie eine Response direkt zurückgeben, anstatt den `Response`-Parameter zu verwenden, FastAPI diese direkt zurückgibt.
@@ -42,7 +42,7 @@ Und auch, dass Sie keine Daten senden, die durch ein `response_model` hätten ge
### Mehr Informationen
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.responses import Response` oder `from starlette.responses import JSONResponse` verwenden.
diff --git a/docs/de/docs/advanced/response-directly.md b/docs/de/docs/advanced/response-directly.md
index 377490b56..fab2e3965 100644
--- a/docs/de/docs/advanced/response-directly.md
+++ b/docs/de/docs/advanced/response-directly.md
@@ -14,7 +14,7 @@ Das kann beispielsweise nützlich sein, um benutzerdefinierte Header oder Cookie
Tatsächlich können Sie jede `Response` oder jede Unterklasse davon zurückgeben.
-/// tip | "Tipp"
+/// tip | Tipp
`JSONResponse` selbst ist eine Unterklasse von `Response`.
@@ -35,10 +35,10 @@ Sie können beispielsweise kein Pydantic-Modell in eine `JSONResponse` einfügen
In diesen Fällen können Sie den `jsonable_encoder` verwenden, um Ihre Daten zu konvertieren, bevor Sie sie an eine Response übergeben:
```Python hl_lines="6-7 21-22"
-{!../../../docs_src/response_directly/tutorial001.py!}
+{!../../docs_src/response_directly/tutorial001.py!}
```
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.responses import JSONResponse` verwenden.
@@ -57,7 +57,7 @@ Nehmen wir an, Sie möchten eine ../../../docs_src/security/tutorial006_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="2 7 11"
-{!> ../../../docs_src/security/tutorial006_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="2 6 10"
-{!> ../../../docs_src/security/tutorial006.py!}
-```
-
-////
-
+{* ../../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:
@@ -68,35 +39,7 @@ Um dies zu lösen, konvertieren wir zunächst den `username` und das `password`
Dann können wir `secrets.compare_digest()` verwenden, um sicherzustellen, dass `credentials.username` `"stanleyjobson"` und `credentials.password` `"swordfish"` ist.
-//// tab | Python 3.9+
-
-```Python hl_lines="1 12-24"
-{!> ../../../docs_src/security/tutorial007_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1 12-24"
-{!> ../../../docs_src/security/tutorial007_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="1 11-21"
-{!> ../../../docs_src/security/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
Dies wäre das gleiche wie:
@@ -160,32 +103,4 @@ So ist Ihr Anwendungscode, dank der Verwendung von `secrets.compare_digest()`, v
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:
-//// tab | Python 3.9+
-
-```Python hl_lines="26-30"
-{!> ../../../docs_src/security/tutorial007_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="26-30"
-{!> ../../../docs_src/security/tutorial007_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="23-27"
-{!> ../../../docs_src/security/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
diff --git a/docs/de/docs/advanced/security/index.md b/docs/de/docs/advanced/security/index.md
index 380e48bbf..25eeb25b5 100644
--- a/docs/de/docs/advanced/security/index.md
+++ b/docs/de/docs/advanced/security/index.md
@@ -4,7 +4,7 @@
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.
-/// tip | "Tipp"
+/// tip | Tipp
Die nächsten Abschnitte sind **nicht unbedingt „fortgeschritten“**.
diff --git a/docs/de/docs/advanced/security/oauth2-scopes.md b/docs/de/docs/advanced/security/oauth2-scopes.md
index f02707698..85175a895 100644
--- a/docs/de/docs/advanced/security/oauth2-scopes.md
+++ b/docs/de/docs/advanced/security/oauth2-scopes.md
@@ -10,7 +10,7 @@ Jedes Mal, wenn Sie sich mit Facebook, Google, GitHub, Microsoft oder Twitter an
In diesem Abschnitt erfahren Sie, wie Sie Authentifizierung und Autorisierung mit demselben OAuth2, mit Scopes in Ihrer **FastAPI**-Anwendung verwalten.
-/// warning | "Achtung"
+/// warning | Achtung
Dies ist ein mehr oder weniger fortgeschrittener Abschnitt. Wenn Sie gerade erst anfangen, können Sie ihn überspringen.
@@ -65,7 +65,7 @@ Sehen wir uns zunächst kurz die Teile an, die sich gegenüber den Beispielen im
//// tab | Python 3.10+
```Python hl_lines="4 8 12 46 64 105 107-115 121-124 128-134 139 155"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -73,7 +73,7 @@ Sehen wir uns zunächst kurz die Teile an, die sich gegenüber den Beispielen im
//// tab | Python 3.9+
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -81,49 +81,49 @@ Sehen wir uns zunächst kurz die Teile an, die sich gegenüber den Beispielen im
//// tab | Python 3.8+
```Python hl_lines="2 4 8 12 47 65 106 108-116 122-125 129-135 140 156"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="3 7 11 45 63 104 106-114 120-123 127-133 138 154"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -139,7 +139,7 @@ Der `scopes`-Parameter erhält ein `dict` mit jedem Scope als Schlüssel und des
//// tab | Python 3.10+
```Python hl_lines="62-65"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -147,7 +147,7 @@ Der `scopes`-Parameter erhält ein `dict` mit jedem Scope als Schlüssel und des
//// tab | Python 3.9+
```Python hl_lines="62-65"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -155,49 +155,49 @@ Der `scopes`-Parameter erhält ein `dict` mit jedem Scope als Schlüssel und des
//// tab | Python 3.8+
```Python hl_lines="63-66"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="61-64"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="62-65"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="62-65"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -218,7 +218,7 @@ Wir verwenden immer noch dasselbe `OAuth2PasswordRequestForm`. Es enthält eine
Und wir geben die Scopes als Teil des JWT-Tokens zurück.
-/// danger | "Gefahr"
+/// danger | Gefahr
Der Einfachheit halber fügen wir hier die empfangenen Scopes direkt zum Token hinzu.
@@ -229,7 +229,7 @@ Aus Sicherheitsgründen sollten Sie jedoch sicherstellen, dass Sie in Ihrer Anwe
//// tab | Python 3.10+
```Python hl_lines="155"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -237,7 +237,7 @@ Aus Sicherheitsgründen sollten Sie jedoch sicherstellen, dass Sie in Ihrer Anwe
//// tab | Python 3.9+
```Python hl_lines="155"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -245,49 +245,49 @@ Aus Sicherheitsgründen sollten Sie jedoch sicherstellen, dass Sie in Ihrer Anwe
//// tab | Python 3.8+
```Python hl_lines="156"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="154"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="155"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="155"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -308,7 +308,7 @@ Und die Abhängigkeitsfunktion `get_current_active_user` kann auch Unterabhängi
In diesem Fall erfordert sie den Scope `me` (sie könnte mehr als einen Scope erfordern).
-/// note | "Hinweis"
+/// note | Hinweis
Sie müssen nicht unbedingt an verschiedenen Stellen verschiedene Scopes hinzufügen.
@@ -319,7 +319,7 @@ Wir tun dies hier, um zu demonstrieren, wie **FastAPI** auf verschiedenen Ebenen
//// tab | Python 3.10+
```Python hl_lines="4 139 170"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -327,7 +327,7 @@ Wir tun dies hier, um zu demonstrieren, wie **FastAPI** auf verschiedenen Ebenen
//// tab | Python 3.9+
```Python hl_lines="4 139 170"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -335,54 +335,54 @@ Wir tun dies hier, um zu demonstrieren, wie **FastAPI** auf verschiedenen Ebenen
//// tab | Python 3.8+
```Python hl_lines="4 140 171"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="3 138 167"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="4 139 168"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="4 139 168"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
-/// info | "Technische Details"
+/// info | Technische Details
`Security` ist tatsächlich eine Unterklasse von `Depends` und hat nur noch einen zusätzlichen Parameter, den wir später kennenlernen werden.
@@ -409,7 +409,7 @@ Diese `SecurityScopes`-Klasse ähnelt `Request` (`Request` wurde verwendet, um d
//// tab | Python 3.10+
```Python hl_lines="8 105"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -417,7 +417,7 @@ Diese `SecurityScopes`-Klasse ähnelt `Request` (`Request` wurde verwendet, um d
//// tab | Python 3.9+
```Python hl_lines="8 105"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -425,49 +425,49 @@ Diese `SecurityScopes`-Klasse ähnelt `Request` (`Request` wurde verwendet, um d
//// tab | Python 3.8+
```Python hl_lines="8 106"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7 104"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8 105"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8 105"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -487,7 +487,7 @@ In diese Exception fügen wir (falls vorhanden) die erforderlichen Scopes als du
//// tab | Python 3.10+
```Python hl_lines="105 107-115"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -495,7 +495,7 @@ In diese Exception fügen wir (falls vorhanden) die erforderlichen Scopes als du
//// tab | Python 3.9+
```Python hl_lines="105 107-115"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -503,49 +503,49 @@ In diese Exception fügen wir (falls vorhanden) die erforderlichen Scopes als du
//// tab | Python 3.8+
```Python hl_lines="106 108-116"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="104 106-114"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="105 107-115"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="105 107-115"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -567,7 +567,7 @@ Wir verifizieren auch, dass wir einen Benutzer mit diesem Benutzernamen haben, u
//// tab | Python 3.10+
```Python hl_lines="46 116-127"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -575,7 +575,7 @@ Wir verifizieren auch, dass wir einen Benutzer mit diesem Benutzernamen haben, u
//// tab | Python 3.9+
```Python hl_lines="46 116-127"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -583,49 +583,49 @@ Wir verifizieren auch, dass wir einen Benutzer mit diesem Benutzernamen haben, u
//// tab | Python 3.8+
```Python hl_lines="47 117-128"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="45 115-126"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="46 116-127"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="46 116-127"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -639,7 +639,7 @@ Hierzu verwenden wir `security_scopes.scopes`, das eine `list`e mit allen diesen
//// tab | Python 3.10+
```Python hl_lines="128-134"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
```
////
@@ -647,7 +647,7 @@ Hierzu verwenden wir `security_scopes.scopes`, das eine `list`e mit allen diesen
//// tab | Python 3.9+
```Python hl_lines="128-134"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
```
////
@@ -655,49 +655,49 @@ Hierzu verwenden wir `security_scopes.scopes`, das eine `list`e mit allen diesen
//// tab | Python 3.8+
```Python hl_lines="129-135"
-{!> ../../../docs_src/security/tutorial005_an.py!}
+{!> ../../docs_src/security/tutorial005_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="127-133"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
+{!> ../../docs_src/security/tutorial005_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="128-134"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
+{!> ../../docs_src/security/tutorial005_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="128-134"
-{!> ../../../docs_src/security/tutorial005.py!}
+{!> ../../docs_src/security/tutorial005.py!}
```
////
@@ -727,7 +727,7 @@ So sieht die Hierarchie der Abhängigkeiten und Scopes aus:
* `security_scopes.scopes` enthält `["me"]` für die *Pfadoperation* `read_users_me`, da das in der Abhängigkeit `get_current_active_user` deklariert ist.
* `security_scopes.scopes` wird `[]` (nichts) für die *Pfadoperation* `read_system_status` enthalten, da diese keine `Security` mit `scopes` deklariert hat, und deren Abhängigkeit `get_current_user` ebenfalls keinerlei `scopes` deklariert.
-/// tip | "Tipp"
+/// tip | Tipp
Das Wichtige und „Magische“ hier ist, dass `get_current_user` für jede *Pfadoperation* eine andere Liste von `scopes` hat, die überprüft werden.
@@ -771,7 +771,7 @@ Am häufigsten ist der „Implicit“-Flow.
Am sichersten ist der „Code“-Flow, die Implementierung ist jedoch komplexer, da mehr Schritte erforderlich sind. Da er komplexer ist, schlagen viele Anbieter letztendlich den „Implicit“-Flow vor.
-/// note | "Hinweis"
+/// note | Hinweis
Es ist üblich, dass jeder Authentifizierungsanbieter seine Flows anders benennt, um sie zu einem Teil seiner Marke zu machen.
diff --git a/docs/de/docs/advanced/settings.md b/docs/de/docs/advanced/settings.md
index 3cd4c6c7d..c90f74844 100644
--- a/docs/de/docs/advanced/settings.md
+++ b/docs/de/docs/advanced/settings.md
@@ -8,7 +8,7 @@ Aus diesem Grund werden diese üblicherweise in Umgebungsvariablen bereitgestell
## Umgebungsvariablen
-/// tip | "Tipp"
+/// 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.
@@ -67,7 +67,7 @@ name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
-/// tip | "Tipp"
+/// tip | Tipp
Das zweite Argument für `os.getenv()` ist der zurückzugebende Defaultwert.
@@ -124,7 +124,7 @@ Hello World from Python
-/// tip | "Tipp"
+/// tip | Tipp
Weitere Informationen dazu finden Sie unter The Twelve-Factor App: Config.
@@ -181,7 +181,7 @@ Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für
//// tab | Pydantic v2
```Python hl_lines="2 5-8 11"
-{!> ../../../docs_src/settings/tutorial001.py!}
+{!> ../../docs_src/settings/tutorial001.py!}
```
////
@@ -195,12 +195,12 @@ In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydan
///
```Python hl_lines="2 5-8 11"
-{!> ../../../docs_src/settings/tutorial001_pv1.py!}
+{!> ../../docs_src/settings/tutorial001_pv1.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
Für ein schnelles Copy-and-paste verwenden Sie nicht dieses Beispiel, sondern das letzte unten.
@@ -215,7 +215,7 @@ Als Nächstes werden die Daten konvertiert und validiert. Wenn Sie also dieses `
Dann können Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden:
```Python hl_lines="18-20"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
### Den Server ausführen
@@ -232,7 +232,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
-/// tip | "Tipp"
+/// tip | Tipp
Um mehrere Umgebungsvariablen für einen einzelnen Befehl festzulegen, trennen Sie diese einfach durch ein Leerzeichen und fügen Sie alle vor dem Befehl ein.
@@ -251,16 +251,16 @@ Sie könnten diese Einstellungen in eine andere Moduldatei einfügen, wie Sie in
Sie könnten beispielsweise eine Datei `config.py` haben mit:
```Python
-{!../../../docs_src/settings/app01/config.py!}
+{!../../docs_src/settings/app01/config.py!}
```
Und dann verwenden Sie diese in einer Datei `main.py`:
```Python hl_lines="3 11-13"
-{!../../../docs_src/settings/app01/main.py!}
+{!../../docs_src/settings/app01/main.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Sie benötigen außerdem eine Datei `__init__.py`, wie in [Größere Anwendungen – mehrere Dateien](../tutorial/bigger-applications.md){.internal-link target=_blank} gesehen.
@@ -277,7 +277,7 @@ Dies könnte besonders beim Testen nützlich sein, da es sehr einfach ist, eine
Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
```Python hl_lines="10"
-{!../../../docs_src/settings/app02/config.py!}
+{!../../docs_src/settings/app02/config.py!}
```
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
@@ -289,7 +289,7 @@ Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurüc
//// tab | Python 3.9+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -297,26 +297,26 @@ Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurüc
//// tab | Python 3.8+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="5 11-12"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
Wir werden das `@lru_cache` in Kürze besprechen.
@@ -329,7 +329,7 @@ Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einf
//// tab | Python 3.9+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -337,21 +337,21 @@ Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einf
//// tab | Python 3.8+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="16 18-20"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -361,7 +361,7 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
```Python hl_lines="9-10 13 21"
-{!../../../docs_src/settings/app02/test_main.py!}
+{!../../docs_src/settings/app02/test_main.py!}
```
Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_email` fest, wenn wir das neue `Settings`-Objekt erstellen, und geben dann dieses neue Objekt zurück.
@@ -374,7 +374,7 @@ Wenn Sie viele Einstellungen haben, die sich möglicherweise oft ändern, vielle
Diese Praxis ist so weit verbreitet, dass sie einen Namen hat. Diese Umgebungsvariablen werden üblicherweise in einer Datei `.env` abgelegt und die Datei wird „dotenv“ genannt.
-/// tip | "Tipp"
+/// tip | Tipp
Eine Datei, die mit einem Punkt (`.`) beginnt, ist eine versteckte Datei in Unix-ähnlichen Systemen wie Linux und macOS.
@@ -384,7 +384,7 @@ Aber eine dotenv-Datei muss nicht unbedingt genau diesen Dateinamen haben.
Pydantic unterstützt das Lesen dieser Dateitypen mithilfe einer externen Bibliothek. Weitere Informationen finden Sie unter Pydantic Settings: Dotenv (.env) support.
-/// tip | "Tipp"
+/// tip | Tipp
Damit das funktioniert, müssen Sie `pip install python-dotenv` ausführen.
@@ -406,10 +406,10 @@ Und dann aktualisieren Sie Ihre `config.py` mit:
//// tab | Pydantic v2
```Python hl_lines="9"
-{!> ../../../docs_src/settings/app03_an/config.py!}
+{!> ../../docs_src/settings/app03_an/config.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter Pydantic: Configuration.
@@ -420,10 +420,10 @@ Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet.
//// tab | Pydantic v1
```Python hl_lines="9-10"
-{!> ../../../docs_src/settings/app03_an/config_pv1.py!}
+{!> ../../docs_src/settings/app03_an/config_pv1.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Die Klasse `Config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter Pydantic Model Config.
@@ -465,7 +465,7 @@ Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Obj
//// tab | Python 3.9+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an_py39/main.py!}
+{!> ../../docs_src/settings/app03_an_py39/main.py!}
```
////
@@ -473,21 +473,21 @@ Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Obj
//// tab | Python 3.8+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an/main.py!}
+{!> ../../docs_src/settings/app03_an/main.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1 10"
-{!> ../../../docs_src/settings/app03/main.py!}
+{!> ../../docs_src/settings/app03/main.py!}
```
////
diff --git a/docs/de/docs/advanced/sub-applications.md b/docs/de/docs/advanced/sub-applications.md
index 7dfaaa0cd..172b8d3c1 100644
--- a/docs/de/docs/advanced/sub-applications.md
+++ b/docs/de/docs/advanced/sub-applications.md
@@ -11,7 +11,7 @@ Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen O
Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
```Python hl_lines="3 6-8"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### Unteranwendung
@@ -21,7 +21,7 @@ Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*.
Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
```Python hl_lines="11 14-16"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### Die Unteranwendung mounten
@@ -31,7 +31,7 @@ Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`.
In diesem Fall wird sie im Pfad `/subapi` gemountet:
```Python hl_lines="11 19"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### Es in der automatischen API-Dokumentation betrachten
diff --git a/docs/de/docs/advanced/templates.md b/docs/de/docs/advanced/templates.md
index abc7624f1..658a2592e 100644
--- a/docs/de/docs/advanced/templates.md
+++ b/docs/de/docs/advanced/templates.md
@@ -28,10 +28,10 @@ $ pip install jinja2
* 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.
```Python hl_lines="4 11 15-18"
-{!../../../docs_src/templates/tutorial001.py!}
+{!../../docs_src/templates/tutorial001.py!}
```
-/// note | "Hinweis"
+/// note | Hinweis
Vor FastAPI 0.108.0 und Starlette 0.29.0 war `name` der erste Parameter.
@@ -39,13 +39,13 @@ Außerdem wurde in früheren Versionen das `request`-Objekt als Teil der Schlüs
///
-/// tip | "Tipp"
+/// tip | Tipp
Durch die Deklaration von `response_class=HTMLResponse` kann die Dokumentationsoberfläche erkennen, dass die Response HTML sein wird.
///
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.templating import Jinja2Templates` verwenden.
@@ -58,7 +58,7 @@ Sie können auch `from starlette.templating import Jinja2Templates` verwenden.
Dann können Sie unter `templates/item.html` ein Template erstellen, mit z. B. folgendem Inhalt:
```jinja hl_lines="7"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
### Template-Kontextwerte
@@ -112,13 +112,13 @@ Mit beispielsweise der ID `42` würde dies Folgendes ergeben:
Sie können `url_for()` innerhalb des Templates auch beispielsweise mit den `StaticFiles` verwenden, die Sie mit `name="static"` gemountet haben.
```jinja hl_lines="4"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
In diesem Beispiel würde das zu einer CSS-Datei unter `static/styles.css` verlinken, mit folgendem Inhalt:
```CSS hl_lines="4"
-{!../../../docs_src/templates/static/styles.css!}
+{!../../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.
diff --git a/docs/de/docs/advanced/testing-dependencies.md b/docs/de/docs/advanced/testing-dependencies.md
index f131d27cd..3b4604da3 100644
--- a/docs/de/docs/advanced/testing-dependencies.md
+++ b/docs/de/docs/advanced/testing-dependencies.md
@@ -31,7 +31,7 @@ Und dann ruft **FastAPI** diese Überschreibung anstelle der ursprünglichen Abh
//// tab | Python 3.10+
```Python hl_lines="26-27 30"
-{!> ../../../docs_src/dependency_testing/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an_py310.py!}
```
////
@@ -39,7 +39,7 @@ Und dann ruft **FastAPI** diese Überschreibung anstelle der ursprünglichen Abh
//// tab | Python 3.9+
```Python hl_lines="28-29 32"
-{!> ../../../docs_src/dependency_testing/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an_py39.py!}
```
////
@@ -47,40 +47,40 @@ Und dann ruft **FastAPI** diese Überschreibung anstelle der ursprünglichen Abh
//// tab | Python 3.8+
```Python hl_lines="29-30 33"
-{!> ../../../docs_src/dependency_testing/tutorial001_an.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="24-25 28"
-{!> ../../../docs_src/dependency_testing/tutorial001_py310.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="28-29 32"
-{!> ../../../docs_src/dependency_testing/tutorial001.py!}
+{!> ../../docs_src/dependency_testing/tutorial001.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
Sie können eine Überschreibung für eine Abhängigkeit festlegen, die an einer beliebigen Stelle in Ihrer **FastAPI**-Anwendung verwendet wird.
@@ -96,7 +96,7 @@ Anschließend können Sie Ihre Überschreibungen zurücksetzen (entfernen), inde
app.dependency_overrides = {}
```
-/// tip | "Tipp"
+/// 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 f50093548..3e63791c6 100644
--- a/docs/de/docs/advanced/testing-events.md
+++ b/docs/de/docs/advanced/testing-events.md
@@ -3,5 +3,5 @@
Wenn Sie in Ihren Tests Ihre Event-Handler (`startup` und `shutdown`) ausführen wollen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
```Python hl_lines="9-12 20-24"
-{!../../../docs_src/app_testing/tutorial003.py!}
+{!../../docs_src/app_testing/tutorial003.py!}
```
diff --git a/docs/de/docs/advanced/testing-websockets.md b/docs/de/docs/advanced/testing-websockets.md
index 4cbc45c17..5122e1f33 100644
--- a/docs/de/docs/advanced/testing-websockets.md
+++ b/docs/de/docs/advanced/testing-websockets.md
@@ -5,10 +5,10 @@ Sie können den schon bekannten `TestClient` zum Testen von WebSockets verwenden
Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung zum WebSocket herstellend:
```Python hl_lines="27-31"
-{!../../../docs_src/app_testing/tutorial002.py!}
+{!../../docs_src/app_testing/tutorial002.py!}
```
-/// note | "Hinweis"
+/// note | Hinweis
Weitere Informationen finden Sie in der Starlette-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 1d575a7cb..1c2a6f852 100644
--- a/docs/de/docs/advanced/using-request-directly.md
+++ b/docs/de/docs/advanced/using-request-directly.md
@@ -30,12 +30,12 @@ Angenommen, Sie möchten auf die IP-Adresse/den Host des Clients in Ihrer *Pfado
Dazu müssen Sie direkt auf den Request zugreifen.
```Python hl_lines="1 7-8"
-{!../../../docs_src/using_request_directly/tutorial001.py!}
+{!../../docs_src/using_request_directly/tutorial001.py!}
```
Durch die Deklaration eines *Pfadoperation-Funktionsparameters*, dessen Typ der `Request` ist, weiß **FastAPI**, dass es den `Request` diesem Parameter übergeben soll.
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass wir in diesem Fall einen Pfad-Parameter zusätzlich zum Request-Parameter deklarieren.
@@ -49,7 +49,7 @@ Auf die gleiche Weise können Sie wie gewohnt jeden anderen Parameter deklariere
Weitere Details zum `Request`-Objekt finden Sie in der offiziellen Starlette-Dokumentation.
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.requests import Request` verwenden.
diff --git a/docs/de/docs/advanced/websockets.md b/docs/de/docs/advanced/websockets.md
index 6d772b6c9..5bc5f6902 100644
--- a/docs/de/docs/advanced/websockets.md
+++ b/docs/de/docs/advanced/websockets.md
@@ -39,7 +39,7 @@ 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:
```Python hl_lines="2 6-38 41-43"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
## Einen `websocket` erstellen
@@ -47,10 +47,10 @@ Aber es ist die einfachste Möglichkeit, sich auf die Serverseite von WebSockets
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
```Python hl_lines="1 46-47"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.websockets import WebSocket` verwenden.
@@ -63,7 +63,7 @@ Sie können auch `from starlette.websockets import WebSocket` verwenden.
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
```Python hl_lines="48-52"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
Sie können Binär-, Text- und JSON-Daten empfangen und senden.
@@ -118,7 +118,7 @@ Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfa
//// tab | Python 3.10+
```Python hl_lines="68-69 82"
-{!> ../../../docs_src/websockets/tutorial002_an_py310.py!}
+{!> ../../docs_src/websockets/tutorial002_an_py310.py!}
```
////
@@ -126,7 +126,7 @@ Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfa
//// tab | Python 3.9+
```Python hl_lines="68-69 82"
-{!> ../../../docs_src/websockets/tutorial002_an_py39.py!}
+{!> ../../docs_src/websockets/tutorial002_an_py39.py!}
```
////
@@ -134,35 +134,35 @@ Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfa
//// tab | Python 3.8+
```Python hl_lines="69-70 83"
-{!> ../../../docs_src/websockets/tutorial002_an.py!}
+{!> ../../docs_src/websockets/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="66-67 79"
-{!> ../../../docs_src/websockets/tutorial002_py310.py!}
+{!> ../../docs_src/websockets/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="68-69 81"
-{!> ../../../docs_src/websockets/tutorial002.py!}
+{!> ../../docs_src/websockets/tutorial002.py!}
```
////
@@ -196,7 +196,7 @@ Dort können Sie einstellen:
* Die „Item ID“, die im Pfad verwendet wird.
* Das „Token“, das als Query-Parameter verwendet wird.
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass der Query-„Token“ von einer Abhängigkeit verarbeitet wird.
@@ -213,7 +213,7 @@ Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_
//// tab | Python 3.9+
```Python hl_lines="79-81"
-{!> ../../../docs_src/websockets/tutorial003_py39.py!}
+{!> ../../docs_src/websockets/tutorial003_py39.py!}
```
////
@@ -221,7 +221,7 @@ Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_
//// tab | Python 3.8+
```Python hl_lines="81-83"
-{!> ../../../docs_src/websockets/tutorial003.py!}
+{!> ../../docs_src/websockets/tutorial003.py!}
```
////
@@ -238,7 +238,7 @@ Das wird die Ausnahme `WebSocketDisconnect` auslösen und alle anderen Clients e
Client #1596980209979 left the chat
```
-/// tip | "Tipp"
+/// tip | Tipp
Die obige Anwendung ist ein minimales und einfaches Beispiel, das zeigt, wie Nachrichten verarbeitet und an mehrere WebSocket-Verbindungen gesendet werden.
diff --git a/docs/de/docs/advanced/wsgi.md b/docs/de/docs/advanced/wsgi.md
index 19ff90a90..50abc84d1 100644
--- a/docs/de/docs/advanced/wsgi.md
+++ b/docs/de/docs/advanced/wsgi.md
@@ -13,7 +13,7 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
Und dann mounten Sie das auf einem Pfad.
```Python hl_lines="2-3 23"
-{!../../../docs_src/wsgi/tutorial001.py!}
+{!../../docs_src/wsgi/tutorial001.py!}
```
## Es ansehen
diff --git a/docs/de/docs/alternatives.md b/docs/de/docs/alternatives.md
index 286ef1723..611315501 100644
--- a/docs/de/docs/alternatives.md
+++ b/docs/de/docs/alternatives.md
@@ -30,13 +30,13 @@ Es wird von vielen Unternehmen verwendet, darunter Mozilla, Red Hat und Eventbri
Es war eines der ersten Beispiele für **automatische API-Dokumentation**, und dies war insbesondere eine der ersten Ideen, welche „die Suche nach“ **FastAPI** inspirierten.
-/// note | "Hinweis"
+/// note | Hinweis
Das Django REST Framework wurde von Tom Christie erstellt. Derselbe Schöpfer von Starlette und Uvicorn, auf denen **FastAPI** basiert.
///
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Eine automatische API-Dokumentationsoberfläche zu haben.
@@ -56,7 +56,7 @@ Diese Entkopplung der Teile und die Tatsache, dass es sich um ein „Mikroframew
Angesichts der Einfachheit von Flask schien es eine gute Ergänzung zum Erstellen von APIs zu sein. Als Nächstes musste ein „Django REST Framework“ für Flask gefunden werden.
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Ein Mikroframework zu sein. Es einfach zu machen, die benötigten Tools und Teile zu kombinieren.
@@ -98,7 +98,7 @@ def read_url():
Sehen Sie sich die Ähnlichkeiten in `requests.get(...)` und `@app.get(...)` an.
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
* Über eine einfache und intuitive API zu verfügen.
* HTTP-Methodennamen (Operationen) direkt, auf einfache und intuitive Weise zu verwenden.
@@ -118,7 +118,7 @@ Irgendwann wurde Swagger an die Linux Foundation übergeben und in OpenAPI umben
Aus diesem Grund spricht man bei Version 2.0 häufig von „Swagger“ und ab Version 3 von „OpenAPI“.
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Einen offenen Standard für API-Spezifikationen zu übernehmen und zu verwenden, anstelle eines benutzerdefinierten Schemas.
@@ -147,7 +147,7 @@ Für diese Funktionen wurde Marshmallow entwickelt. Es ist eine großartige Bibl
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**"
+/// check | Inspirierte **FastAPI**
Code zu verwenden, um „Schemas“ zu definieren, welche Datentypen und Validierung automatisch bereitstellen.
@@ -169,7 +169,7 @@ Webargs wurde von denselben Marshmallow-Entwicklern erstellt.
///
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Eingehende Requestdaten automatisch zu validieren.
@@ -199,7 +199,7 @@ APISpec wurde von denselben Marshmallow-Entwicklern erstellt.
///
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Den offenen Standard für APIs, OpenAPI, zu unterstützen.
@@ -231,7 +231,7 @@ Flask-apispec wurde von denselben Marshmallow-Entwicklern erstellt.
///
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Das OpenAPI-Schema automatisch zu generieren, aus demselben Code, welcher die Serialisierung und Validierung definiert.
@@ -251,7 +251,7 @@ Da TypeScript-Daten jedoch nach der Kompilierung nach JavaScript nicht erhalten
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.
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Python-Typen zu verwenden, um eine hervorragende Editorunterstützung zu erhalten.
@@ -263,7 +263,7 @@ Python-Typen zu verwenden, um eine hervorragende Editorunterstützung zu erhalte
Es war eines der ersten extrem schnellen Python-Frameworks, welches auf `asyncio` basierte. Es wurde so gestaltet, dass es Flask sehr ähnlich ist.
-/// note | "Technische Details"
+/// note | Technische Details
Es verwendete `uvloop` anstelle der standardmäßigen Python-`asyncio`-Schleife. Das hat es so schnell gemacht.
@@ -271,7 +271,7 @@ Hat eindeutig Uvicorn und Starlette inspiriert, welche derzeit in offenen Benchm
///
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Einen Weg zu finden, eine hervorragende Performanz zu haben.
@@ -287,7 +287,7 @@ Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter e
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.
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Wege zu finden, eine großartige Performanz zu erzielen.
@@ -313,7 +313,7 @@ Das Dependency Injection System erfordert eine Vorab-Registrierung der Abhängig
Routen werden an einer einzigen Stelle deklariert, indem Funktionen verwendet werden, die an anderen Stellen deklariert wurden (anstatt Dekoratoren zu verwenden, welche direkt über der Funktion platziert werden können, welche den Endpunkt verarbeitet). Dies ähnelt eher der Vorgehensweise von Django als der Vorgehensweise von Flask (und Starlette). Es trennt im Code Dinge, die relativ eng miteinander gekoppelt sind.
-/// check | "Inspirierte **FastAPI**"
+/// check | Inspirierte **FastAPI**
Zusätzliche Validierungen für Datentypen zu definieren, mithilfe des „Default“-Werts von Modellattributen. Dies verbessert die Editorunterstützung und war zuvor in Pydantic nicht verfügbar.
@@ -321,7 +321,7 @@ Das hat tatsächlich dazu geführt, dass Teile von Pydantic aktualisiert wurden,
///
-### 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.
@@ -341,7 +341,7 @@ Hug wurde von Timothy Crosley erstellt, dem gleichen Schöpfer von
-/// tip | "Tipp"
+/// tip | Tipp
Aktivieren Sie jedes Mal, wenn Sie ein neues Package mit `pip` in dieser Umgebung installieren, die Umgebung erneut.
@@ -138,7 +138,7 @@ Und wenn Sie diesen lokalen FastAPI-Quellcode aktualisieren und dann die Python-
Auf diese Weise müssen Sie Ihre lokale Version nicht „installieren“, um jede Änderung testen zu können.
-/// note | "Technische Details"
+/// note | Technische Details
Das geschieht nur, wenn Sie die Installation mit der enthaltenen `requirements.txt` durchführen, anstatt `pip install fastapi` direkt auszuführen.
@@ -186,7 +186,7 @@ Das stellt die Dokumentation unter `http://127.0.0.1:8008` bereit.
Auf diese Weise können Sie die Dokumentation/Quelldateien bearbeiten und die Änderungen live sehen.
-/// tip | "Tipp"
+/// tip | Tipp
Alternativ können Sie die Schritte des Skripts auch manuell ausführen.
@@ -229,7 +229,7 @@ Die Dokumentation verwendet Kommentare mit Änderungsvorschlägen zu vorhandenen Pull Requests hinzufügen.
@@ -303,7 +303,7 @@ Angenommen, Sie möchten eine Seite für eine Sprache übersetzen, die bereits
Im Spanischen lautet der Zwei-Buchstaben-Code `es`. Das Verzeichnis für spanische Übersetzungen befindet sich also unter `docs/es/`.
-/// tip | "Tipp"
+/// tip | Tipp
Die Haupt („offizielle“) Sprache ist Englisch und befindet sich unter `docs/en/`.
@@ -324,7 +324,7 @@ $ python ./scripts/docs.py live es
-/// tip | "Tipp"
+/// tip | Tipp
Alternativ können Sie die Schritte des Skripts auch manuell ausführen.
@@ -360,7 +360,7 @@ docs/en/docs/features.md
docs/es/docs/features.md
```
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass die einzige Änderung in Pfad und Dateiname der Sprachcode ist, von `en` zu `es`.
@@ -399,7 +399,7 @@ Obiges Kommando hat eine Datei `docs/ht/mkdocs.yml` mit einer Minimal-Konfigurat
INHERIT: ../en/mkdocs.yml
```
-/// tip | "Tipp"
+/// tip | Tipp
Sie können diese Datei mit diesem Inhalt auch einfach manuell erstellen.
diff --git a/docs/de/docs/deployment/concepts.md b/docs/de/docs/deployment/concepts.md
index 3c1c0cfce..97ad854e2 100644
--- a/docs/de/docs/deployment/concepts.md
+++ b/docs/de/docs/deployment/concepts.md
@@ -151,7 +151,7 @@ Und dennoch möchten Sie wahrscheinlich nicht, dass die Anwendung tot bleibt, we
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 ...
-/// tip | "Tipp"
+/// tip | Tipp
... Obwohl es wahrscheinlich keinen Sinn macht, sie immer wieder neu zu starten, wenn die gesamte Anwendung einfach **sofort abstürzt**. Aber in diesen Fällen werden Sie es wahrscheinlich während der Entwicklung oder zumindest direkt nach dem Deployment bemerken.
@@ -241,7 +241,7 @@ Hier sind einige mögliche Kombinationen und Strategien:
* **Cloud-Dienste**, welche das für Sie erledigen
* Der Cloud-Dienst wird wahrscheinlich **die Replikation für Sie übernehmen**. Er würde Sie möglicherweise **einen auszuführenden Prozess** oder ein **zu verwendendes Container-Image** definieren lassen, in jedem Fall wäre es höchstwahrscheinlich **ein einzelner Uvicorn-Prozess**, und der Cloud-Dienst wäre auch verantwortlich für die Replikation.
-/// tip | "Tipp"
+/// tip | Tipp
Machen Sie sich keine Sorgen, wenn einige dieser Punkte zu **Containern**, Docker oder Kubernetes noch nicht viel Sinn ergeben.
@@ -263,7 +263,7 @@ Und Sie müssen sicherstellen, dass es sich um einen einzelnen Prozess handelt,
Natürlich gibt es Fälle, in denen es kein Problem darstellt, die Vorab-Schritte mehrmals auszuführen. In diesem Fall ist die Handhabung viel einfacher.
-/// tip | "Tipp"
+/// tip | Tipp
Bedenken Sie außerdem, dass Sie, abhängig von Ihrer Einrichtung, in manchen Fällen **gar keine Vorab-Schritte** benötigen, bevor Sie die Anwendung starten.
@@ -281,7 +281,7 @@ Hier sind einige mögliche Ideen:
* Ein Bash-Skript, das die Vorab-Schritte ausführt und dann Ihre Anwendung startet
* Sie benötigen immer noch eine Möglichkeit, *dieses* Bash-Skript zu starten/neu zu starten, Fehler zu erkennen, usw.
-/// tip | "Tipp"
+/// tip | Tipp
Konkretere Beispiele hierfür mit Containern gebe ich Ihnen in einem späteren Kapitel: [FastAPI in Containern – Docker](docker.md){.internal-link target=_blank}.
diff --git a/docs/de/docs/deployment/docker.md b/docs/de/docs/deployment/docker.md
index c11dc4127..a2734e068 100644
--- a/docs/de/docs/deployment/docker.md
+++ b/docs/de/docs/deployment/docker.md
@@ -4,7 +4,7 @@ Beim Deployment von FastAPI-Anwendungen besteht ein gängiger Ansatz darin, ein
Die Verwendung von Linux-Containern bietet mehrere Vorteile, darunter **Sicherheit**, **Replizierbarkeit**, **Einfachheit** und andere.
-/// tip | "Tipp"
+/// tip | Tipp
Sie haben es eilig und kennen sich bereits aus? Springen Sie zum [`Dockerfile` unten 👇](#ein-docker-image-fur-fastapi-erstellen).
@@ -231,7 +231,7 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
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"
+/// tip | Tipp
Lernen Sie, was jede Zeile bewirkt, indem Sie auf die Zahlenblasen im Code klicken. 👆
@@ -305,7 +305,7 @@ $ docker build -t myimage .
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie das `.` am Ende, es entspricht `./` und teilt Docker mit, welches Verzeichnis zum Erstellen des Containerimages verwendet werden soll.
@@ -409,7 +409,7 @@ Wenn wir uns nur auf das **Containerimage** für eine FastAPI-Anwendung (und sp
Es könnte sich um einen anderen Container handeln, zum Beispiel mit Traefik, welcher **HTTPS** und **automatischen** Erwerb von **Zertifikaten** handhabt.
-/// tip | "Tipp"
+/// tip | Tipp
Traefik verfügt über Integrationen mit Docker, Kubernetes und anderen, sodass Sie damit ganz einfach HTTPS für Ihre Container einrichten und konfigurieren können.
@@ -441,7 +441,7 @@ Bei der Verwendung von Containern ist normalerweise eine Komponente vorhanden, *
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.
-/// tip | "Tipp"
+/// tip | Tipp
Die gleiche **TLS-Terminierungsproxy**-Komponente, die für HTTPS verwendet wird, wäre wahrscheinlich auch ein **Load Balancer**.
@@ -544,7 +544,7 @@ Dieses Image wäre vor allem in den oben beschriebenen Situationen nützlich: [C
* tiangolo/uvicorn-gunicorn-fastapi.
-/// warning | "Achtung"
+/// warning | Achtung
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).
@@ -556,7 +556,7 @@ Es verfügt über **vernünftige Standardeinstellungen**, aber Sie können trotz
Es unterstützt auch die Ausführung von **Vorab-Schritten vor dem Start** mit einem Skript.
-/// tip | "Tipp"
+/// tip | Tipp
Um alle Konfigurationen und Optionen anzuzeigen, gehen Sie zur Docker-Image-Seite: tiangolo/uvicorn-gunicorn-fastapi.
@@ -687,7 +687,7 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
11. Führe den Befehl `uvicorn` aus und weise ihn an, das aus `app.main` importierte `app`-Objekt zu verwenden.
-/// tip | "Tipp"
+/// tip | Tipp
Klicken Sie auf die Zahlenblasen, um zu sehen, was jede Zeile bewirkt.
diff --git a/docs/de/docs/deployment/https.md b/docs/de/docs/deployment/https.md
index b1f0aca77..630582995 100644
--- a/docs/de/docs/deployment/https.md
+++ b/docs/de/docs/deployment/https.md
@@ -4,7 +4,7 @@ Es ist leicht anzunehmen, dass HTTPS etwas ist, was einfach nur „aktiviert“
Aber es ist viel komplexer als das.
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie es eilig haben oder es Ihnen egal ist, fahren Sie mit den nächsten Abschnitten fort, um Schritt-für-Schritt-Anleitungen für die Einrichtung der verschiedenen Technologien zu erhalten.
@@ -71,7 +71,7 @@ In dem oder den DNS-Server(n) würden Sie einen Eintrag (einen „`A record`“)
Sie würden dies wahrscheinlich nur einmal tun, beim ersten Mal, wenn Sie alles einrichten.
-/// tip | "Tipp"
+/// tip | Tipp
Dieser Domainnamen-Aspekt liegt weit vor HTTPS, aber da alles von der Domain und der IP-Adresse abhängt, lohnt es sich, das hier zu erwähnen.
@@ -121,7 +121,7 @@ Danach verfügen der Client und der Server über eine **verschlüsselte TCP-Verb
Und genau das ist **HTTPS**, es ist einfach **HTTP** innerhalb einer **sicheren TLS-Verbindung**, statt einer puren (unverschlüsselten) TCP-Verbindung.
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass die Verschlüsselung der Kommunikation auf der **TCP-Ebene** und nicht auf der HTTP-Ebene erfolgt.
diff --git a/docs/de/docs/deployment/manually.md b/docs/de/docs/deployment/manually.md
index 2b4ed3fad..fdb33f7fe 100644
--- a/docs/de/docs/deployment/manually.md
+++ b/docs/de/docs/deployment/manually.md
@@ -36,7 +36,7 @@ $ pip install "uvicorn[standard]"
-/// tip | "Tipp"
+/// tip | Tipp
Durch das Hinzufügen von `standard` installiert und verwendet Uvicorn einige empfohlene zusätzliche Abhängigkeiten.
@@ -96,7 +96,7 @@ Running on 0.0.0.0:8080 over http (CTRL + C to quit)
////
-/// warning | "Achtung"
+/// warning | Achtung
Denken Sie daran, die Option `--reload` zu entfernen, wenn Sie diese verwendet haben.
diff --git a/docs/de/docs/deployment/versions.md b/docs/de/docs/deployment/versions.md
index 2d10ac4b6..5b8c69754 100644
--- a/docs/de/docs/deployment/versions.md
+++ b/docs/de/docs/deployment/versions.md
@@ -42,7 +42,7 @@ Gemäß den Konventionen zur semantischen Versionierung könnte jede Version unt
FastAPI folgt auch der Konvention, dass jede „PATCH“-Versionsänderung für Bugfixes und abwärtskompatible Änderungen gedacht ist.
-/// tip | "Tipp"
+/// tip | Tipp
Der „PATCH“ ist die letzte Zahl, zum Beispiel ist in `0.2.3` die PATCH-Version `3`.
@@ -56,7 +56,7 @@ fastapi>=0.45.0,<0.46.0
Nicht abwärtskompatible Änderungen und neue Funktionen werden in „MINOR“-Versionen hinzugefügt.
-/// tip | "Tipp"
+/// tip | Tipp
„MINOR“ ist die Zahl in der Mitte, zum Beispiel ist in `0.2.3` die MINOR-Version `2`.
diff --git a/docs/de/docs/help-fastapi.md b/docs/de/docs/help-fastapi.md
index 2c84a5e5b..0b9c52316 100644
--- a/docs/de/docs/help-fastapi.md
+++ b/docs/de/docs/help-fastapi.md
@@ -228,7 +228,7 @@ Wenn Sie mir dabei helfen können, **helfen Sie mir, FastAPI am Laufen zu erhalt
Treten Sie dem 👥 Discord-Chatserver 👥 bei und treffen Sie sich mit anderen Mitgliedern der FastAPI-Community.
-/// tip | "Tipp"
+/// 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.
diff --git a/docs/de/docs/how-to/conditional-openapi.md b/docs/de/docs/how-to/conditional-openapi.md
index 7f277bb88..a0a4983bb 100644
--- a/docs/de/docs/how-to/conditional-openapi.md
+++ b/docs/de/docs/how-to/conditional-openapi.md
@@ -30,7 +30,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener
Zum Beispiel:
```Python hl_lines="6 11"
-{!../../../docs_src/conditional_openapi/tutorial001.py!}
+{!../../docs_src/conditional_openapi/tutorial001.py!}
```
Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.
diff --git a/docs/de/docs/how-to/configure-swagger-ui.md b/docs/de/docs/how-to/configure-swagger-ui.md
index c18091efd..1ee72d205 100644
--- a/docs/de/docs/how-to/configure-swagger-ui.md
+++ b/docs/de/docs/how-to/configure-swagger-ui.md
@@ -1,6 +1,6 @@
# Swagger-Oberfläche konfigurieren
-Sie können einige zusätzliche Parameter der Swagger-Oberfläche konfigurieren.
+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()`.
@@ -18,9 +18,7 @@ Ohne Änderung der Einstellungen ist die Syntaxhervorhebung standardmäßig akti
Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` setzen:
-```Python hl_lines="3"
-{!../../../docs_src/configure_swagger_ui/tutorial001.py!}
-```
+{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
... und dann zeigt die Swagger-Oberfläche die Syntaxhervorhebung nicht mehr an:
@@ -30,9 +28,7 @@ Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` set
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):
-```Python hl_lines="3"
-{!../../../docs_src/configure_swagger_ui/tutorial002.py!}
-```
+{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern:
@@ -44,21 +40,17 @@ FastAPI enthält einige Defaultkonfigurationsparameter, die für die meisten Anw
Es umfasst die folgenden Defaultkonfigurationen:
-```Python
-{!../../../fastapi/openapi/docs.py[ln:7-23]!}
-```
+{* ../../fastapi/openapi/docs.py ln[7:23] *}
Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_parameters` einen anderen Wert festlegen.
Um beispielsweise `deepLinking` zu deaktivieren, könnten Sie folgende Einstellungen an `swagger_ui_parameters` übergeben:
-```Python hl_lines="3"
-{!../../../docs_src/configure_swagger_ui/tutorial003.py!}
-```
+{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
## Andere Parameter der Swagger-Oberfläche
-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.
+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
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 e8750f7c2..a292be69b 100644
--- a/docs/de/docs/how-to/custom-docs-ui-assets.md
+++ b/docs/de/docs/how-to/custom-docs-ui-assets.md
@@ -19,7 +19,7 @@ Der erste Schritt besteht darin, die automatischen Dokumentationen zu deaktivier
Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
```Python hl_lines="8"
-{!../../../docs_src/custom_docs_ui/tutorial001.py!}
+{!../../docs_src/custom_docs_ui/tutorial001.py!}
```
### Die benutzerdefinierten Dokumentationen hinzufügen
@@ -37,10 +37,10 @@ Sie können die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei
Und genau so für ReDoc ...
```Python hl_lines="2-6 11-19 22-24 27-33"
-{!../../../docs_src/custom_docs_ui/tutorial001.py!}
+{!../../docs_src/custom_docs_ui/tutorial001.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Die *Pfadoperation* für `swagger_ui_redirect` ist ein Hilfsmittel bei der Verwendung von OAuth2.
@@ -55,7 +55,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
```Python hl_lines="36-38"
-{!../../../docs_src/custom_docs_ui/tutorial001.py!}
+{!../../docs_src/custom_docs_ui/tutorial001.py!}
```
### Es ausprobieren
@@ -125,7 +125,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen:
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
```Python hl_lines="7 11"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
```
### Die statischen Dateien testen
@@ -159,7 +159,7 @@ Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt d
Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
```Python hl_lines="9"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
```
### Die benutzerdefinierten Dokumentationen, mit statischen Dateien, hinzufügen
@@ -177,10 +177,10 @@ Auch hier können Sie die internen Funktionen von FastAPI wiederverwenden, um di
Und genau so für ReDoc ...
```Python hl_lines="2-6 14-22 25-27 30-36"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Die *Pfadoperation* für `swagger_ui_redirect` ist ein Hilfsmittel bei der Verwendung von OAuth2.
@@ -195,7 +195,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
```Python hl_lines="39-41"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
```
### Benutzeroberfläche, mit statischen Dateien, testen
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 a0c4a0e0c..ef71d96dc 100644
--- a/docs/de/docs/how-to/custom-request-and-route.md
+++ b/docs/de/docs/how-to/custom-request-and-route.md
@@ -6,7 +6,7 @@ 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.
-/// danger | "Gefahr"
+/// danger | Gefahr
Dies ist eine „fortgeschrittene“ Funktion.
@@ -30,7 +30,7 @@ Und eine `APIRoute`-Unterklasse zur Verwendung dieser benutzerdefinierten Reques
### Eine benutzerdefinierte `GzipRequest`-Klasse erstellen
-/// tip | "Tipp"
+/// tip | Tipp
Dies ist nur ein einfaches Beispiel, um zu demonstrieren, wie es funktioniert. Wenn Sie Gzip-Unterstützung benötigen, können Sie die bereitgestellte [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank} verwenden.
@@ -43,7 +43,7 @@ Wenn der Header kein `gzip` enthält, wird nicht versucht, den Body zu dekomprim
Auf diese Weise kann dieselbe Routenklasse gzip-komprimierte oder unkomprimierte Requests verarbeiten.
```Python hl_lines="8-15"
-{!../../../docs_src/custom_request_and_route/tutorial001.py!}
+{!../../docs_src/custom_request_and_route/tutorial001.py!}
```
### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen
@@ -57,10 +57,10 @@ Diese Methode gibt eine Funktion zurück. Und diese Funktion empfängt einen Req
Hier verwenden wir sie, um aus dem ursprünglichen Request einen `GzipRequest` zu erstellen.
```Python hl_lines="18-26"
-{!../../../docs_src/custom_request_and_route/tutorial001.py!}
+{!../../docs_src/custom_request_and_route/tutorial001.py!}
```
-/// note | "Technische Details"
+/// 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.
@@ -84,7 +84,7 @@ Aufgrund unserer Änderungen in `GzipRequest.body` wird der Requestbody jedoch b
## Zugriff auf den Requestbody in einem Exceptionhandler
-/// tip | "Tipp"
+/// 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}).
@@ -97,13 +97,13 @@ Wir können denselben Ansatz auch verwenden, um in einem Exceptionhandler auf de
Alles, was wir tun müssen, ist, den Request innerhalb eines `try`/`except`-Blocks zu handhaben:
```Python hl_lines="13 15"
-{!../../../docs_src/custom_request_and_route/tutorial002.py!}
+{!../../docs_src/custom_request_and_route/tutorial002.py!}
```
Wenn eine Exception auftritt, befindet sich die `Request`-Instanz weiterhin im Gültigkeitsbereich, sodass wir den Requestbody lesen und bei der Fehlerbehandlung verwenden können:
```Python hl_lines="16-18"
-{!../../../docs_src/custom_request_and_route/tutorial002.py!}
+{!../../docs_src/custom_request_and_route/tutorial002.py!}
```
## Benutzerdefinierte `APIRoute`-Klasse in einem Router
@@ -111,11 +111,11 @@ Wenn eine Exception auftritt, befindet sich die `Request`-Instanz weiterhin im G
Sie können auch den Parameter `route_class` eines `APIRouter` festlegen:
```Python hl_lines="26"
-{!../../../docs_src/custom_request_and_route/tutorial003.py!}
+{!../../docs_src/custom_request_and_route/tutorial003.py!}
```
In diesem Beispiel verwenden die *Pfadoperationen* unter dem `router` die benutzerdefinierte `TimedRoute`-Klasse und haben in der Response einen zusätzlichen `X-Response-Time`-Header mit der Zeit, die zum Generieren der Response benötigt wurde:
```Python hl_lines="13-20"
-{!../../../docs_src/custom_request_and_route/tutorial003.py!}
+{!../../docs_src/custom_request_and_route/tutorial003.py!}
```
diff --git a/docs/de/docs/how-to/extending-openapi.md b/docs/de/docs/how-to/extending-openapi.md
index 347c5bed3..c895fb860 100644
--- a/docs/de/docs/how-to/extending-openapi.md
+++ b/docs/de/docs/how-to/extending-openapi.md
@@ -44,7 +44,7 @@ Fügen wir beispielsweise Strawberry-Dokumentation.
@@ -49,7 +49,7 @@ Frühere Versionen von Starlette enthielten eine `GraphQLApp`-Klasse zur Integra
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.
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie GraphQL benötigen, würde ich Ihnen trotzdem empfehlen, sich Strawberry anzuschauen, da es auf Typannotationen basiert, statt auf benutzerdefinierten Klassen und Typen.
diff --git a/docs/de/docs/how-to/index.md b/docs/de/docs/how-to/index.md
index 75779a01c..84a178fc8 100644
--- a/docs/de/docs/how-to/index.md
+++ b/docs/de/docs/how-to/index.md
@@ -6,7 +6,7 @@ Die meisten dieser Ideen sind mehr oder weniger **unabhängig**, und in den meis
Wenn etwas für Ihr Projekt interessant und nützlich erscheint, lesen Sie es, andernfalls überspringen Sie es einfach.
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie strukturiert **FastAPI lernen** möchten (empfohlen), lesen Sie stattdessen Kapitel für Kapitel das [Tutorial – Benutzerhandbuch](../tutorial/index.md){.internal-link target=_blank}.
diff --git a/docs/de/docs/how-to/separate-openapi-schemas.md b/docs/de/docs/how-to/separate-openapi-schemas.md
index eaecb27de..974341dd2 100644
--- a/docs/de/docs/how-to/separate-openapi-schemas.md
+++ b/docs/de/docs/how-to/separate-openapi-schemas.md
@@ -13,7 +13,7 @@ Nehmen wir an, Sie haben ein Pydantic-Modell mit Defaultwerten wie dieses:
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
+{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
# Code unterhalb weggelassen 👇
```
@@ -22,7 +22,7 @@ Nehmen wir an, Sie haben ein Pydantic-Modell mit Defaultwerten wie dieses:
get-Operation gehen
-/// info | "`@decorator` Information"
+/// info | `@decorator` Information
Diese `@something`-Syntax wird in Python „Dekorator“ genannt.
@@ -286,7 +286,7 @@ Oder die exotischeren:
* `@app.patch()`
* `@app.trace()`
-/// tip | "Tipp"
+/// tip | Tipp
Es steht Ihnen frei, jede Operation (HTTP-Methode) so zu verwenden, wie Sie es möchten.
@@ -307,7 +307,7 @@ Das ist unsere „**Pfadoperation-Funktion**“:
* **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`).
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Dies ist eine Python-Funktion.
@@ -321,10 +321,10 @@ In diesem Fall handelt es sich um eine `async`-Funktion.
Sie könnten sie auch als normale Funktion anstelle von `async def` definieren:
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
+{!../../docs_src/first_steps/tutorial003.py!}
```
-/// note | "Hinweis"
+/// note | Hinweis
Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../async.md#in-eile){.internal-link target=_blank}.
@@ -333,7 +333,7 @@ Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../as
### Schritt 5: den Inhalt zurückgeben
```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben.
diff --git a/docs/de/docs/tutorial/handling-errors.md b/docs/de/docs/tutorial/handling-errors.md
index 6ee47948c..85de76ef1 100644
--- a/docs/de/docs/tutorial/handling-errors.md
+++ b/docs/de/docs/tutorial/handling-errors.md
@@ -26,7 +26,7 @@ Um HTTP-Responses mit Fehlern zum Client zurückzugeben, verwenden Sie `HTTPExce
### `HTTPException` importieren
```Python hl_lines="1"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### Eine `HTTPException` in Ihrem Code auslösen
@@ -42,7 +42,7 @@ Der Vorteil, eine Exception auszulösen (`raise`), statt sie zurückzugeben (`re
Im folgenden Beispiel lösen wir, wenn der Client eine ID anfragt, die nicht existiert, eine Exception mit dem Statuscode `404` aus.
```Python hl_lines="11"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### Die resultierende Response
@@ -63,7 +63,7 @@ Aber wenn der Client `http://example.com/items/bar` anfragt (ein nicht-existiere
}
```
-/// tip | "Tipp"
+/// 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`.
@@ -82,7 +82,7 @@ Sie müssen das wahrscheinlich nicht direkt in ihrem Code verwenden.
Aber falls es in einem fortgeschrittenen Szenario notwendig ist, können Sie benutzerdefinierte Header wie folgt hinzufügen:
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial002.py!}
+{!../../docs_src/handling_errors/tutorial002.py!}
```
## Benutzerdefinierte Exceptionhandler definieren
@@ -96,7 +96,7 @@ Und Sie möchten diese Exception global mit FastAPI handhaben.
Sie könnten einen benutzerdefinierten Exceptionhandler mittels `@app.exception_handler()` hinzufügen:
```Python hl_lines="5-7 13-18 24"
-{!../../../docs_src/handling_errors/tutorial003.py!}
+{!../../docs_src/handling_errors/tutorial003.py!}
```
Wenn Sie nun `/unicorns/yolo` anfragen, `raise`d die *Pfadoperation* eine `UnicornException`.
@@ -109,7 +109,7 @@ Sie erhalten also einen sauberen Error mit einem Statuscode `418` und dem JSON-I
{"message": "Oops! yolo did something. There goes a rainbow..."}
```
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.requests import Request` und `from starlette.responses import JSONResponse` verwenden.
@@ -136,7 +136,7 @@ Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und ve
Der Exceptionhandler wird einen `Request` und die Exception entgegennehmen.
```Python hl_lines="2 14-16"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
Wenn Sie nun `/items/foo` besuchen, erhalten Sie statt des Default-JSON-Errors:
@@ -166,7 +166,7 @@ path -> item_id
#### `RequestValidationError` vs. `ValidationError`
-/// warning | "Achtung"
+/// warning | Achtung
Das folgende sind technische Details, die Sie überspringen können, wenn sie für Sie nicht wichtig sind.
@@ -189,10 +189,10 @@ Genauso können Sie den `HTTPException`-Handler überschreiben.
Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
```Python hl_lines="3-4 9-11 22"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.responses import PlainTextResponse` verwenden.
@@ -207,7 +207,7 @@ Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen
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.
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial005.py!}
+{!../../docs_src/handling_errors/tutorial005.py!}
```
Jetzt versuchen Sie, einen ungültigen Artikel zu senden:
@@ -265,7 +265,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
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:
```Python hl_lines="2-5 15 21"
-{!../../../docs_src/handling_errors/tutorial006.py!}
+{!../../docs_src/handling_errors/tutorial006.py!}
```
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.
diff --git a/docs/de/docs/tutorial/header-params.md b/docs/de/docs/tutorial/header-params.md
index c8c3a4c57..40a773f50 100644
--- a/docs/de/docs/tutorial/header-params.md
+++ b/docs/de/docs/tutorial/header-params.md
@@ -9,7 +9,7 @@ Importieren Sie zuerst `Header`:
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@ Importieren Sie zuerst `Header`:
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@ Importieren Sie zuerst `Header`:
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001_an.py!}
+{!> ../../docs_src/header_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1"
-{!> ../../../docs_src/header_params/tutorial001_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001.py!}
+{!> ../../docs_src/header_params/tutorial001.py!}
```
////
@@ -67,7 +67,7 @@ Der erste Wert ist der Typ. Sie können `Header` die gehabten Extra Validierungs
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py310.py!}
```
////
@@ -75,7 +75,7 @@ Der erste Wert ist der Typ. Sie können `Header` die gehabten Extra Validierungs
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py39.py!}
```
////
@@ -83,40 +83,40 @@ Der erste Wert ist der Typ. Sie können `Header` die gehabten Extra Validierungs
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial001_an.py!}
+{!> ../../docs_src/header_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/header_params/tutorial001_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001.py!}
+{!> ../../docs_src/header_params/tutorial001.py!}
```
////
-/// note | "Technische Details"
+/// note | Technische Details
`Header` ist eine Schwesterklasse von `Path`, `Query` und `Cookie`. Sie erbt von derselben gemeinsamen `Param`-Elternklasse.
@@ -149,7 +149,7 @@ Wenn Sie aus irgendeinem Grund das automatische Konvertieren von Unterstrichen z
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial002_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial002_an_py310.py!}
```
////
@@ -157,7 +157,7 @@ Wenn Sie aus irgendeinem Grund das automatische Konvertieren von Unterstrichen z
//// tab | Python 3.9+
```Python hl_lines="11"
-{!> ../../../docs_src/header_params/tutorial002_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial002_an_py39.py!}
```
////
@@ -165,40 +165,40 @@ Wenn Sie aus irgendeinem Grund das automatische Konvertieren von Unterstrichen z
//// tab | Python 3.8+
```Python hl_lines="12"
-{!> ../../../docs_src/header_params/tutorial002_an.py!}
+{!> ../../docs_src/header_params/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8"
-{!> ../../../docs_src/header_params/tutorial002_py310.py!}
+{!> ../../docs_src/header_params/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial002.py!}
+{!> ../../docs_src/header_params/tutorial002.py!}
```
////
-/// warning | "Achtung"
+/// warning | Achtung
Bevor Sie `convert_underscores` auf `False` setzen, bedenken Sie, dass manche HTTP-Proxys und Server die Verwendung von Headern mit Unterstrichen nicht erlauben.
@@ -217,7 +217,7 @@ Um zum Beispiel einen Header `X-Token` zu deklarieren, der mehrmals vorkommen ka
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial003_an_py310.py!}
```
////
@@ -225,7 +225,7 @@ Um zum Beispiel einen Header `X-Token` zu deklarieren, der mehrmals vorkommen ka
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial003_an_py39.py!}
```
////
@@ -233,49 +233,49 @@ Um zum Beispiel einen Header `X-Token` zu deklarieren, der mehrmals vorkommen ka
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial003_an.py!}
+{!> ../../docs_src/header_params/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/header_params/tutorial003_py310.py!}
+{!> ../../docs_src/header_params/tutorial003_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_py39.py!}
+{!> ../../docs_src/header_params/tutorial003_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003.py!}
+{!> ../../docs_src/header_params/tutorial003.py!}
```
////
diff --git a/docs/de/docs/tutorial/index.md b/docs/de/docs/tutorial/index.md
index c15d0b0bd..3cbfe37f4 100644
--- a/docs/de/docs/tutorial/index.md
+++ b/docs/de/docs/tutorial/index.md
@@ -52,7 +52,7 @@ $ pip install "fastapi[all]"
... das beinhaltet auch `uvicorn`, welchen Sie als Server verwenden können, der ihren Code ausführt.
-/// note | "Hinweis"
+/// note | Hinweis
Sie können die einzelnen Teile auch separat installieren.
diff --git a/docs/de/docs/tutorial/metadata.md b/docs/de/docs/tutorial/metadata.md
index 3ab56ff3e..5a0b723c5 100644
--- a/docs/de/docs/tutorial/metadata.md
+++ b/docs/de/docs/tutorial/metadata.md
@@ -19,10 +19,10 @@ Sie können die folgenden Felder festlegen, welche in der OpenAPI-Spezifikation
Sie können diese wie folgt setzen:
```Python hl_lines="3-16 19-32"
-{!../../../docs_src/metadata/tutorial001.py!}
+{!../../docs_src/metadata/tutorial001.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Sie können Markdown in das Feld `description` schreiben und es wird in der Ausgabe gerendert.
@@ -39,7 +39,7 @@ Seit OpenAPI 3.1.0 und FastAPI 0.99.0 können Sie die `license_info` auch mit ei
Zum Beispiel:
```Python hl_lines="31"
-{!../../../docs_src/metadata/tutorial001_1.py!}
+{!../../docs_src/metadata/tutorial001_1.py!}
```
## Metadaten für Tags
@@ -63,12 +63,12 @@ Versuchen wir das an 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`:
```Python hl_lines="3-16 18"
-{!../../../docs_src/metadata/tutorial004.py!}
+{!../../docs_src/metadata/tutorial004.py!}
```
Beachten Sie, dass Sie Markdown in den Beschreibungen verwenden können. Beispielsweise wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt.
-/// tip | "Tipp"
+/// tip | Tipp
Sie müssen nicht für alle von Ihnen verwendeten Tags Metadaten hinzufügen.
@@ -79,7 +79,7 @@ Sie müssen nicht für alle von Ihnen verwendeten Tags Metadaten hinzufügen.
Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n), um diese verschiedenen Tags zuzuweisen:
```Python hl_lines="21 26"
-{!../../../docs_src/metadata/tutorial004.py!}
+{!../../docs_src/metadata/tutorial004.py!}
```
/// info
@@ -109,7 +109,7 @@ Sie können das aber mit dem Parameter `openapi_url` konfigurieren.
Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestellt wird:
```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial002.py!}
+{!../../docs_src/metadata/tutorial002.py!}
```
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.
@@ -128,5 +128,5 @@ Sie können die beiden enthaltenen Dokumentationsbenutzeroberflächen konfigurie
Um beispielsweise Swagger UI so einzustellen, dass sie unter `/documentation` bereitgestellt wird, und ReDoc zu deaktivieren:
```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial003.py!}
+{!../../docs_src/metadata/tutorial003.py!}
```
diff --git a/docs/de/docs/tutorial/middleware.md b/docs/de/docs/tutorial/middleware.md
index 62a0d1613..d3699be1b 100644
--- a/docs/de/docs/tutorial/middleware.md
+++ b/docs/de/docs/tutorial/middleware.md
@@ -11,7 +11,7 @@ Eine „Middleware“ ist eine Funktion, die mit jedem **Request** arbeitet, bev
* Sie kann etwas mit dieser **Response** tun oder beliebigen Code ausführen.
* Dann gibt sie die **Response** zurück.
-/// note | "Technische Details"
+/// note | Technische Details
Wenn Sie Abhängigkeiten mit `yield` haben, wird der Exit-Code *nach* der Middleware ausgeführt.
@@ -31,11 +31,9 @@ Die Middleware-Funktion erhält:
* Dann gibt es die von der entsprechenden *Pfadoperation* generierte `response` zurück.
* Sie können die `response` dann weiter modifizieren, bevor Sie sie zurückgeben.
-```Python hl_lines="8-9 11 14"
-{!../../../docs_src/middleware/tutorial001.py!}
-```
+{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass benutzerdefinierte proprietäre Header hinzugefügt werden können. Verwenden Sie dafür das Präfix 'X-'.
@@ -43,7 +41,7 @@ Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser
///
-/// note | "Technische Details"
+/// note | Technische Details
Sie könnten auch `from starlette.requests import Request` verwenden.
@@ -59,9 +57,7 @@ Und auch nachdem die `response` generiert wurde, bevor sie zurückgegeben wird.
Sie könnten beispielsweise einen benutzerdefinierten Header `X-Process-Time` hinzufügen, der die Zeit in Sekunden enthält, die benötigt wurde, um den Request zu verarbeiten und eine Response zu generieren:
-```Python hl_lines="10 12-13"
-{!../../../docs_src/middleware/tutorial001.py!}
-```
+{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
## Andere Middlewares
diff --git a/docs/de/docs/tutorial/path-operation-configuration.md b/docs/de/docs/tutorial/path-operation-configuration.md
index 03980b7dd..55d0f2a91 100644
--- a/docs/de/docs/tutorial/path-operation-configuration.md
+++ b/docs/de/docs/tutorial/path-operation-configuration.md
@@ -2,7 +2,7 @@
Es gibt mehrere Konfigurations-Parameter, die Sie Ihrem *Pfadoperation-Dekorator* übergeben können.
-/// warning | "Achtung"
+/// warning | Achtung
Beachten Sie, dass diese Parameter direkt dem *Pfadoperation-Dekorator* übergeben werden, nicht der *Pfadoperation-Funktion*.
@@ -19,7 +19,7 @@ Aber falls Sie sich nicht mehr erinnern, wofür jede Nummer steht, können Sie d
//// tab | Python 3.10+
```Python hl_lines="1 15"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py310.py!}
```
////
@@ -27,7 +27,7 @@ Aber falls Sie sich nicht mehr erinnern, wofür jede Nummer steht, können Sie d
//// tab | Python 3.9+
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py39.py!}
```
////
@@ -35,14 +35,14 @@ Aber falls Sie sich nicht mehr erinnern, wofür jede Nummer steht, können Sie d
//// tab | Python 3.8+
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001.py!}
```
////
Dieser Statuscode wird in der Response verwendet und zum OpenAPI-Schema hinzugefügt.
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette import status` verwenden.
@@ -57,7 +57,7 @@ Sie können Ihrer *Pfadoperation* Tags hinzufügen, mittels des Parameters `tags
//// tab | Python 3.10+
```Python hl_lines="15 20 25"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py310.py!}
```
////
@@ -65,7 +65,7 @@ Sie können Ihrer *Pfadoperation* Tags hinzufügen, mittels des Parameters `tags
//// tab | Python 3.9+
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py39.py!}
```
////
@@ -73,7 +73,7 @@ Sie können Ihrer *Pfadoperation* Tags hinzufügen, mittels des Parameters `tags
//// tab | Python 3.8+
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002.py!}
```
////
@@ -91,7 +91,7 @@ In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
**FastAPI** unterstützt diese genauso wie einfache Strings:
```Python hl_lines="1 8-10 13 18"
-{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
+{!../../docs_src/path_operation_configuration/tutorial002b.py!}
```
## Zusammenfassung und Beschreibung
@@ -101,7 +101,7 @@ Sie können eine Zusammenfassung (`summary`) und eine Beschreibung (`description
//// tab | Python 3.10+
```Python hl_lines="18-19"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py310.py!}
```
////
@@ -109,7 +109,7 @@ Sie können eine Zusammenfassung (`summary`) und eine Beschreibung (`description
//// tab | Python 3.9+
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py39.py!}
```
////
@@ -117,7 +117,7 @@ Sie können eine Zusammenfassung (`summary`) und eine Beschreibung (`description
//// tab | Python 3.8+
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003.py!}
```
////
@@ -131,7 +131,7 @@ Sie können im Docstring ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py310.py!}
```
////
@@ -139,7 +139,7 @@ Sie können im Docstring ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py39.py!}
```
////
@@ -147,7 +147,7 @@ Sie können im Docstring ../../../docs_src/path_operation_configuration/tutorial004.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004.py!}
```
////
@@ -163,7 +163,7 @@ Die Response können Sie mit dem Parameter `response_description` beschreiben:
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py310.py!}
```
////
@@ -171,7 +171,7 @@ Die Response können Sie mit dem Parameter `response_description` beschreiben:
//// tab | Python 3.9+
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py39.py!}
```
////
@@ -179,7 +179,7 @@ Die Response können Sie mit dem Parameter `response_description` beschreiben:
//// tab | Python 3.8+
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005.py!}
```
////
@@ -205,7 +205,7 @@ Daher, wenn Sie keine vergeben, wird **FastAPI** automatisch eine für „Erfolg
Wenn Sie eine *Pfadoperation* als deprecated kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_configuration/tutorial006.py!}
```
Sie wird in der interaktiven Dokumentation gut sichtbar als deprecated markiert werden:
diff --git a/docs/de/docs/tutorial/path-params-numeric-validations.md b/docs/de/docs/tutorial/path-params-numeric-validations.md
index 3908a0b2d..b74fc8a04 100644
--- a/docs/de/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/de/docs/tutorial/path-params-numeric-validations.md
@@ -9,7 +9,7 @@ Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`.
//// tab | Python 3.10+
```Python hl_lines="1 3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@ Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`.
//// tab | Python 3.9+
```Python hl_lines="1 3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@ Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`.
//// tab | Python 3.8+
```Python hl_lines="3-4"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
@@ -77,7 +77,7 @@ Um zum Beispiel einen `title`-Metadaten-Wert für den Pfad-Parameter `item_id` z
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
```
////
@@ -85,7 +85,7 @@ Um zum Beispiel einen `title`-Metadaten-Wert für den Pfad-Parameter `item_id` z
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
////
@@ -93,40 +93,40 @@ Um zum Beispiel einen `title`-Metadaten-Wert für den Pfad-Parameter `item_id` z
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
-/// note | "Hinweis"
+/// note | Hinweis
Ein Pfad-Parameter ist immer erforderlich, weil er Teil des Pfads sein muss.
@@ -138,7 +138,7 @@ Doch selbst wenn Sie ihn mit `None` deklarieren, oder einen Defaultwert setzen,
## Sortieren Sie die Parameter, wie Sie möchten
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie `Annotated` verwenden, ist das folgende nicht so wichtig / nicht notwendig.
@@ -160,14 +160,14 @@ Sie können Ihre Funktion also so deklarieren:
//// tab | Python 3.8 nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
////
@@ -177,7 +177,7 @@ Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` ver
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
```
////
@@ -185,14 +185,14 @@ Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` ver
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
```
////
## Sortieren Sie die Parameter wie Sie möchten: Tricks
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie `Annotated` verwenden, ist das folgende nicht so wichtig / nicht notwendig.
@@ -214,7 +214,7 @@ Wenn Sie eines der folgenden Dinge tun möchten:
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 hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
### Besser mit `Annotated`
@@ -224,7 +224,7 @@ Bedenken Sie, dass Sie, wenn Sie `Annotated` verwenden, dieses Problem nicht hab
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
```
////
@@ -232,7 +232,7 @@ Bedenken Sie, dass Sie, wenn Sie `Annotated` verwenden, dieses Problem nicht hab
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
```
////
@@ -245,7 +245,7 @@ Hier, mit `ge=1`, wird festgelegt, dass `item_id` eine Ganzzahl benötigt, die g
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
```
////
@@ -253,21 +253,21 @@ Hier, mit `ge=1`, wird festgelegt, dass `item_id` eine Ganzzahl benötigt, die g
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
////
@@ -282,7 +282,7 @@ Das Gleiche trifft zu auf:
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
```
////
@@ -290,21 +290,21 @@ Das Gleiche trifft zu auf:
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
////
@@ -322,7 +322,7 @@ Das gleiche gilt für lt ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
```
////
@@ -330,21 +330,21 @@ Das gleiche gilt für lt ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
////
@@ -368,7 +368,7 @@ Sie alle teilen die gleichen Parameter für zusätzliche Validierung und Metadat
///
-/// note | "Technische Details"
+/// note | Technische Details
`Query`, `Path` und andere, die Sie von `fastapi` importieren, sind tatsächlich Funktionen.
diff --git a/docs/de/docs/tutorial/path-params.md b/docs/de/docs/tutorial/path-params.md
index 2c1b691a8..e91c3db51 100644
--- a/docs/de/docs/tutorial/path-params.md
+++ b/docs/de/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-Format-Strings verwendet wird:
```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
@@ -19,7 +19,7 @@ Wenn Sie dieses Beispiel ausführen und auf Modellen für maschinelles Lernen.
@@ -170,7 +170,7 @@ Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das
Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`):
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### Testen Sie es in der API-Dokumentation
@@ -188,7 +188,7 @@ Der *Pfad-Parameter* wird ein * ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial001_py310.py!}
```
////
@@ -15,14 +15,14 @@ Nehmen wir als Beispiel die folgende Anwendung:
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial001.py!}
```
////
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.
-/// note | "Hinweis"
+/// note | Hinweis
FastAPI weiß nur dank des definierten Defaultwertes `=None`, dass der Wert von `q` nicht erforderlich ist
@@ -46,7 +46,7 @@ Importieren Sie zuerst:
In Python 3.9 oder darüber, ist `Annotated` Teil der Standardbibliothek, also können Sie es von `typing` importieren.
```Python hl_lines="1 3"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
////
@@ -58,7 +58,7 @@ 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!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
```
////
@@ -126,7 +126,7 @@ Jetzt, da wir `Annotated` für unsere Metadaten deklariert haben, fügen Sie `Qu
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
////
@@ -134,7 +134,7 @@ Jetzt, da wir `Annotated` für unsere Metadaten deklariert haben, fügen Sie `Qu
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
```
////
@@ -153,7 +153,7 @@ FastAPI wird nun:
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.
-/// tip | "Tipp"
+/// 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. 🍰
@@ -164,7 +164,7 @@ So würden Sie `Query()` als Defaultwert Ihres Funktionsparameters verwenden, de
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
////
@@ -172,7 +172,7 @@ So würden Sie `Query()` als Defaultwert Ihres Funktionsparameters verwenden, de
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002.py!}
```
////
@@ -278,7 +278,7 @@ Sie können auch einen Parameter `min_length` hinzufügen:
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_an_py310.py!}
```
////
@@ -286,7 +286,7 @@ Sie können auch einen Parameter `min_length` hinzufügen:
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_an_py39.py!}
```
////
@@ -294,35 +294,35 @@ Sie können auch einen Parameter `min_length` hinzufügen:
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003.py!}
```
////
@@ -334,7 +334,7 @@ Sie können einen ../../../docs_src/query_params_str_validations/tutorial004_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an_py310.py!}
```
////
@@ -342,7 +342,7 @@ Sie können einen ../../../docs_src/query_params_str_validations/tutorial004_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an_py39.py!}
```
////
@@ -350,35 +350,35 @@ Sie können einen ../../../docs_src/query_params_str_validations/tutorial004_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial004.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004.py!}
```
////
@@ -402,7 +402,7 @@ Sie könnten immer noch Code sehen, der den alten Namen verwendet:
//// tab | Python 3.10+ Pydantic v1
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_an_py310_regex.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an_py310_regex.py!}
```
////
@@ -418,7 +418,7 @@ Beispielsweise könnten Sie den `q` Query-Parameter so deklarieren, dass er eine
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial005_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial005_an_py39.py!}
```
////
@@ -426,26 +426,26 @@ Beispielsweise könnten Sie den `q` Query-Parameter so deklarieren, dass er eine
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial005_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial005_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial005.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial005.py!}
```
////
-/// note | "Hinweis"
+/// note | Hinweis
Ein Parameter ist optional (nicht erforderlich), wenn er irgendeinen Defaultwert, auch `None`, hat.
@@ -488,7 +488,7 @@ Wenn Sie einen Parameter erforderlich machen wollen, während Sie `Query` verwen
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006_an_py39.py!}
```
////
@@ -496,24 +496,24 @@ Wenn Sie einen Parameter erforderlich machen wollen, während Sie `Query` verwen
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial006_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass, obwohl in diesem Fall `Query()` der Funktionsparameter-Defaultwert ist, wir nicht `default=None` zu `Query()` hinzufügen.
@@ -530,7 +530,7 @@ Es gibt eine Alternative, die explizit deklariert, dass ein Wert erforderlich is
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006b_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py!}
```
////
@@ -538,21 +538,21 @@ Es gibt eine Alternative, die explizit deklariert, dass ein Wert erforderlich is
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial006b_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006b_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006b.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006b.py!}
```
////
@@ -576,7 +576,7 @@ Um das zu machen, deklarieren Sie, dass `None` ein gültiger Typ ist, aber verwe
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py!}
```
////
@@ -584,7 +584,7 @@ Um das zu machen, deklarieren Sie, dass `None` ein gültiger Typ ist, aber verwe
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_an_py39.py!}
```
////
@@ -592,46 +592,46 @@ Um das zu machen, deklarieren Sie, dass `None` ein gültiger Typ ist, aber verwe
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
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.
///
-/// tip | "Tipp"
+/// 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.
@@ -646,7 +646,7 @@ Um zum Beispiel einen Query-Parameter `q` zu deklarieren, der mehrere Male in de
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_an_py310.py!}
```
////
@@ -654,7 +654,7 @@ Um zum Beispiel einen Query-Parameter `q` zu deklarieren, der mehrere Male in de
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_an_py39.py!}
```
////
@@ -662,49 +662,49 @@ Um zum Beispiel einen Query-Parameter `q` zu deklarieren, der mehrere Male in de
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_py310.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011.py!}
```
////
@@ -728,7 +728,7 @@ Die Response für diese URL wäre also:
}
```
-/// tip | "Tipp"
+/// 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.
@@ -745,7 +745,7 @@ Und Sie können auch eine Default-`list`e von Werten definieren, wenn keine übe
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_an_py39.py!}
```
////
@@ -753,35 +753,35 @@ Und Sie können auch eine Default-`list`e von Werten definieren, wenn keine übe
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_an.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial012.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012.py!}
```
////
@@ -810,7 +810,7 @@ Sie können auch `list` direkt verwenden, anstelle von `List[str]` (oder `list[s
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial013_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial013_an_py39.py!}
```
////
@@ -818,26 +818,26 @@ Sie können auch `list` direkt verwenden, anstelle von `List[str]` (oder `list[s
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial013_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial013_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial013.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial013.py!}
```
////
-/// note | "Hinweis"
+/// note | Hinweis
Beachten Sie, dass FastAPI in diesem Fall den Inhalt der Liste nicht überprüft.
@@ -851,7 +851,7 @@ Sie können mehr Informationen zum Parameter hinzufügen.
Diese Informationen werden zur generierten OpenAPI hinzugefügt, und von den Dokumentations-Oberflächen und von externen Tools verwendet.
-/// note | "Hinweis"
+/// note | Hinweis
Beachten Sie, dass verschiedene Tools OpenAPI möglicherweise unterschiedlich gut unterstützen.
@@ -864,7 +864,7 @@ Sie können einen Titel hinzufügen – `title`:
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_an_py310.py!}
```
////
@@ -872,7 +872,7 @@ Sie können einen Titel hinzufügen – `title`:
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_an_py39.py!}
```
////
@@ -880,35 +880,35 @@ Sie können einen Titel hinzufügen – `title`:
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007.py!}
```
////
@@ -918,7 +918,7 @@ Und eine Beschreibung – `description`:
//// tab | Python 3.10+
```Python hl_lines="14"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_an_py310.py!}
```
////
@@ -926,7 +926,7 @@ Und eine Beschreibung – `description`:
//// tab | Python 3.9+
```Python hl_lines="14"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_an_py39.py!}
```
////
@@ -934,35 +934,35 @@ Und eine Beschreibung – `description`:
//// tab | Python 3.8+
```Python hl_lines="15"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="13"
-{!> ../../../docs_src/query_params_str_validations/tutorial008.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008.py!}
```
////
@@ -988,7 +988,7 @@ Dann können Sie einen `alias` deklarieren, und dieser Alias wird verwendet, um
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_an_py310.py!}
```
////
@@ -996,7 +996,7 @@ Dann können Sie einen `alias` deklarieren, und dieser Alias wird verwendet, um
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_an_py39.py!}
```
////
@@ -1004,35 +1004,35 @@ Dann können Sie einen `alias` deklarieren, und dieser Alias wird verwendet, um
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009.py!}
```
////
@@ -1048,7 +1048,7 @@ In diesem Fall fügen Sie den Parameter `deprecated=True` zu `Query` hinzu.
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_an_py310.py!}
```
////
@@ -1056,7 +1056,7 @@ In diesem Fall fügen Sie den Parameter `deprecated=True` zu `Query` hinzu.
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_an_py39.py!}
```
////
@@ -1064,35 +1064,35 @@ In diesem Fall fügen Sie den Parameter `deprecated=True` zu `Query` hinzu.
//// tab | Python 3.8+
```Python hl_lines="20"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="16"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="18"
-{!> ../../../docs_src/query_params_str_validations/tutorial010.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010.py!}
```
////
@@ -1108,7 +1108,7 @@ Um einen Query-Parameter vom generierten OpenAPI-Schema auszuschließen (und dah
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_an_py310.py!}
```
////
@@ -1116,7 +1116,7 @@ Um einen Query-Parameter vom generierten OpenAPI-Schema auszuschließen (und dah
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_an_py39.py!}
```
////
@@ -1124,35 +1124,35 @@ Um einen Query-Parameter vom generierten OpenAPI-Schema auszuschließen (und dah
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014.py!}
```
////
diff --git a/docs/de/docs/tutorial/query-params.md b/docs/de/docs/tutorial/query-params.md
index 136852216..e67fef79d 100644
--- a/docs/de/docs/tutorial/query-params.md
+++ b/docs/de/docs/tutorial/query-params.md
@@ -3,7 +3,7 @@
Wenn Sie in ihrer Funktion Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
+{!../../docs_src/query_params/tutorial001.py!}
```
Query-Parameter (Deutsch: Abfrage-Parameter) sind die Schlüssel-Wert-Paare, die nach dem `?` in einer URL aufgelistet sind, getrennt durch `&`-Zeichen.
@@ -66,7 +66,7 @@ Auf die gleiche Weise können Sie optionale Query-Parameter deklarieren, indem S
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial002_py310.py!}
+{!> ../../docs_src/query_params/tutorial002_py310.py!}
```
////
@@ -74,7 +74,7 @@ Auf die gleiche Weise können Sie optionale Query-Parameter deklarieren, indem S
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial002.py!}
+{!> ../../docs_src/query_params/tutorial002.py!}
```
////
@@ -94,7 +94,7 @@ Sie können auch `bool`-Typen deklarieren und sie werden konvertiert:
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial003_py310.py!}
+{!> ../../docs_src/query_params/tutorial003_py310.py!}
```
////
@@ -102,7 +102,7 @@ Sie können auch `bool`-Typen deklarieren und sie werden konvertiert:
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial003.py!}
+{!> ../../docs_src/query_params/tutorial003.py!}
```
////
@@ -150,7 +150,7 @@ Parameter werden anhand ihres Namens erkannt:
//// tab | Python 3.10+
```Python hl_lines="6 8"
-{!> ../../../docs_src/query_params/tutorial004_py310.py!}
+{!> ../../docs_src/query_params/tutorial004_py310.py!}
```
////
@@ -158,7 +158,7 @@ Parameter werden anhand ihres Namens erkannt:
//// tab | Python 3.8+
```Python hl_lines="8 10"
-{!> ../../../docs_src/query_params/tutorial004.py!}
+{!> ../../docs_src/query_params/tutorial004.py!}
```
////
@@ -172,7 +172,7 @@ Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach op
Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert:
```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
+{!../../docs_src/query_params/tutorial005.py!}
```
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.
@@ -222,7 +222,7 @@ Und natürlich können Sie einige Parameter als erforderlich, einige mit Default
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params/tutorial006_py310.py!}
+{!> ../../docs_src/query_params/tutorial006_py310.py!}
```
////
@@ -230,7 +230,7 @@ Und natürlich können Sie einige Parameter als erforderlich, einige mit Default
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params/tutorial006.py!}
+{!> ../../docs_src/query_params/tutorial006.py!}
```
////
@@ -241,7 +241,7 @@ In diesem Fall gibt es drei Query-Parameter:
* `skip`, ein `int` mit einem Defaultwert `0`.
* `limit`, ein optionales `int`.
-/// tip | "Tipp"
+/// 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}.
diff --git a/docs/de/docs/tutorial/request-files.md b/docs/de/docs/tutorial/request-files.md
index cf44df5f0..cbfb4271f 100644
--- a/docs/de/docs/tutorial/request-files.md
+++ b/docs/de/docs/tutorial/request-files.md
@@ -19,7 +19,7 @@ Importieren Sie `File` und `UploadFile` von `fastapi`:
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/request_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
```
////
@@ -27,21 +27,21 @@ Importieren Sie `File` und `UploadFile` von `fastapi`:
//// tab | Python 3.8+
```Python hl_lines="1"
-{!> ../../../docs_src/request_files/tutorial001_an.py!}
+{!> ../../docs_src/request_files/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_files/tutorial001.py!}
+{!> ../../docs_src/request_files/tutorial001.py!}
```
////
@@ -53,7 +53,7 @@ Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` und `Form` machen w
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/request_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
```
////
@@ -61,21 +61,21 @@ Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` und `Form` machen w
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/request_files/tutorial001_an.py!}
+{!> ../../docs_src/request_files/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/request_files/tutorial001.py!}
+{!> ../../docs_src/request_files/tutorial001.py!}
```
////
@@ -88,7 +88,7 @@ Aber erinnern Sie sich, dass, wenn Sie `Query`, `Path`, `File` und andere von `
///
-/// tip | "Tipp"
+/// 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.
@@ -109,7 +109,7 @@ Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`:
//// tab | Python 3.9+
```Python hl_lines="14"
-{!> ../../../docs_src/request_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
```
////
@@ -117,21 +117,21 @@ Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`:
//// tab | Python 3.8+
```Python hl_lines="13"
-{!> ../../../docs_src/request_files/tutorial001_an.py!}
+{!> ../../docs_src/request_files/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="12"
-{!> ../../../docs_src/request_files/tutorial001.py!}
+{!> ../../docs_src/request_files/tutorial001.py!}
```
////
@@ -177,13 +177,13 @@ Wenn Sie sich innerhalb einer normalen `def`-*Pfadoperation-Funktion* befinden,
contents = myfile.file.read()
```
-/// note | "Technische Details zu `async`"
+/// note | Technische Details zu `async`
Wenn Sie die `async`-Methoden verwenden, führt **FastAPI** die Datei-Methoden in einem Threadpool aus und erwartet sie.
///
-/// note | "Technische Details zu Starlette"
+/// note | Technische Details zu Starlette
**FastAPI**s `UploadFile` erbt direkt von **Starlette**s `UploadFile`, fügt aber ein paar notwendige Teile hinzu, um es kompatibel mit **Pydantic** und anderen Teilen von FastAPI zu machen.
@@ -195,7 +195,7 @@ HTML-Formulare (``) senden die Daten in einer „speziellen“ Kodi
**FastAPI** stellt sicher, dass diese Daten korrekt ausgelesen werden, statt JSON zu erwarten.
-/// note | "Technische Details"
+/// note | Technische Details
Daten aus Formularen werden, wenn es keine Dateien sind, normalerweise mit dem „media type“ `application/x-www-form-urlencoded` kodiert.
@@ -205,7 +205,7 @@ Wenn Sie mehr über Formularfelder und ihre Kodierungen lesen möchten, besuchen
///
-/// warning | "Achtung"
+/// 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.
@@ -220,7 +220,7 @@ Sie können eine Datei optional machen, indem Sie Standard-Typannotationen verwe
//// tab | Python 3.10+
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02_an_py310.py!}
+{!> ../../docs_src/request_files/tutorial001_02_an_py310.py!}
```
////
@@ -228,7 +228,7 @@ Sie können eine Datei optional machen, indem Sie Standard-Typannotationen verwe
//// tab | Python 3.9+
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_02_an_py39.py!}
```
////
@@ -236,35 +236,35 @@ Sie können eine Datei optional machen, indem Sie Standard-Typannotationen verwe
//// tab | Python 3.8+
```Python hl_lines="10 18"
-{!> ../../../docs_src/request_files/tutorial001_02_an.py!}
+{!> ../../docs_src/request_files/tutorial001_02_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7 15"
-{!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
+{!> ../../docs_src/request_files/tutorial001_02_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02.py!}
+{!> ../../docs_src/request_files/tutorial001_02.py!}
```
////
@@ -276,7 +276,7 @@ Sie können auch `File()` zusammen mit `UploadFile` verwenden, um zum Beispiel z
//// tab | Python 3.9+
```Python hl_lines="9 15"
-{!> ../../../docs_src/request_files/tutorial001_03_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_03_an_py39.py!}
```
////
@@ -284,21 +284,21 @@ Sie können auch `File()` zusammen mit `UploadFile` verwenden, um zum Beispiel z
//// tab | Python 3.8+
```Python hl_lines="8 14"
-{!> ../../../docs_src/request_files/tutorial001_03_an.py!}
+{!> ../../docs_src/request_files/tutorial001_03_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7 13"
-{!> ../../../docs_src/request_files/tutorial001_03.py!}
+{!> ../../docs_src/request_files/tutorial001_03.py!}
```
////
@@ -314,7 +314,7 @@ Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s:
//// tab | Python 3.9+
```Python hl_lines="10 15"
-{!> ../../../docs_src/request_files/tutorial002_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial002_an_py39.py!}
```
////
@@ -322,42 +322,42 @@ Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s:
//// tab | Python 3.8+
```Python hl_lines="11 16"
-{!> ../../../docs_src/request_files/tutorial002_an.py!}
+{!> ../../docs_src/request_files/tutorial002_an.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8 13"
-{!> ../../../docs_src/request_files/tutorial002_py39.py!}
+{!> ../../docs_src/request_files/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10 15"
-{!> ../../../docs_src/request_files/tutorial002.py!}
+{!> ../../docs_src/request_files/tutorial002.py!}
```
////
Sie erhalten, wie deklariert, eine `list`e von `bytes` oder `UploadFile`s.
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette.responses import HTMLResponse` verwenden.
@@ -372,7 +372,7 @@ Und so wie zuvor können Sie `File()` verwenden, um zusätzliche Parameter zu se
//// tab | Python 3.9+
```Python hl_lines="11 18-20"
-{!> ../../../docs_src/request_files/tutorial003_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial003_an_py39.py!}
```
////
@@ -380,35 +380,35 @@ Und so wie zuvor können Sie `File()` verwenden, um zusätzliche Parameter zu se
//// tab | Python 3.8+
```Python hl_lines="12 19-21"
-{!> ../../../docs_src/request_files/tutorial003_an.py!}
+{!> ../../docs_src/request_files/tutorial003_an.py!}
```
////
//// tab | Python 3.9+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="9 16"
-{!> ../../../docs_src/request_files/tutorial003_py39.py!}
+{!> ../../docs_src/request_files/tutorial003_py39.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="11 18"
-{!> ../../../docs_src/request_files/tutorial003.py!}
+{!> ../../docs_src/request_files/tutorial003.py!}
```
////
diff --git a/docs/de/docs/tutorial/request-forms-and-files.md b/docs/de/docs/tutorial/request-forms-and-files.md
index e109595d1..bdd1e0fac 100644
--- a/docs/de/docs/tutorial/request-forms-and-files.md
+++ b/docs/de/docs/tutorial/request-forms-and-files.md
@@ -15,7 +15,7 @@ Z. B. `pip install python-multipart`.
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
```
////
@@ -23,21 +23,21 @@ Z. B. `pip install python-multipart`.
//// tab | Python 3.8+
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001.py!}
```
////
@@ -49,7 +49,7 @@ Erstellen Sie Datei- und Formularparameter, so wie Sie es auch mit `Body` und `Q
//// tab | Python 3.9+
```Python hl_lines="10-12"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
```
////
@@ -57,21 +57,21 @@ Erstellen Sie Datei- und Formularparameter, so wie Sie es auch mit `Body` und `Q
//// tab | Python 3.8+
```Python hl_lines="9-11"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="8"
-{!> ../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001.py!}
```
////
@@ -80,7 +80,7 @@ Die Datei- und Formularfelder werden als Formulardaten hochgeladen, und Sie erha
Und Sie können einige der Dateien als `bytes` und einige als `UploadFile` deklarieren.
-/// warning | "Achtung"
+/// 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.
diff --git a/docs/de/docs/tutorial/request-forms.md b/docs/de/docs/tutorial/request-forms.md
index 391788aff..2b6aeb41c 100644
--- a/docs/de/docs/tutorial/request-forms.md
+++ b/docs/de/docs/tutorial/request-forms.md
@@ -17,7 +17,7 @@ Importieren Sie `Form` von `fastapi`:
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
```
////
@@ -25,21 +25,21 @@ Importieren Sie `Form` von `fastapi`:
//// tab | Python 3.8+
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms/tutorial001_an.py!}
+{!> ../../docs_src/request_forms/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms/tutorial001.py!}
+{!> ../../docs_src/request_forms/tutorial001.py!}
```
////
@@ -51,7 +51,7 @@ Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` und `Query` mach
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
```
////
@@ -59,21 +59,21 @@ Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` und `Query` mach
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/request_forms/tutorial001_an.py!}
+{!> ../../docs_src/request_forms/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7"
-{!> ../../../docs_src/request_forms/tutorial001.py!}
+{!> ../../docs_src/request_forms/tutorial001.py!}
```
////
@@ -90,7 +90,7 @@ Mit `Form` haben Sie die gleichen Konfigurationsmöglichkeiten wie mit `Body` (u
///
-/// tip | "Tipp"
+/// 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.
@@ -102,7 +102,7 @@ HTML-Formulare (``) senden die Daten in einer „speziellen“ Kodi
**FastAPI** stellt sicher, dass diese Daten korrekt ausgelesen werden, statt JSON zu erwarten.
-/// note | "Technische Details"
+/// note | Technische Details
Daten aus Formularen werden normalerweise mit dem „media type“ `application/x-www-form-urlencoded` kodiert.
@@ -112,7 +112,7 @@ Wenn Sie mehr über Formularfelder und ihre Kodierungen lesen möchten, besuchen
///
-/// warning | "Achtung"
+/// 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.
diff --git a/docs/de/docs/tutorial/response-model.md b/docs/de/docs/tutorial/response-model.md
index b480780bc..aa27e0726 100644
--- a/docs/de/docs/tutorial/response-model.md
+++ b/docs/de/docs/tutorial/response-model.md
@@ -7,7 +7,7 @@ Hierbei können Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten
//// tab | Python 3.10+
```Python hl_lines="16 21"
-{!> ../../../docs_src/response_model/tutorial001_01_py310.py!}
+{!> ../../docs_src/response_model/tutorial001_01_py310.py!}
```
////
@@ -15,7 +15,7 @@ Hierbei können Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten
//// tab | Python 3.9+
```Python hl_lines="18 23"
-{!> ../../../docs_src/response_model/tutorial001_01_py39.py!}
+{!> ../../docs_src/response_model/tutorial001_01_py39.py!}
```
////
@@ -23,7 +23,7 @@ Hierbei können Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten
//// tab | Python 3.8+
```Python hl_lines="18 23"
-{!> ../../../docs_src/response_model/tutorial001_01.py!}
+{!> ../../docs_src/response_model/tutorial001_01.py!}
```
////
@@ -62,7 +62,7 @@ Sie können `response_model` in jeder möglichen *Pfadoperation* verwenden:
//// tab | Python 3.10+
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001_py310.py!}
+{!> ../../docs_src/response_model/tutorial001_py310.py!}
```
////
@@ -70,7 +70,7 @@ Sie können `response_model` in jeder möglichen *Pfadoperation* verwenden:
//// tab | Python 3.9+
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001_py39.py!}
+{!> ../../docs_src/response_model/tutorial001_py39.py!}
```
////
@@ -78,12 +78,12 @@ Sie können `response_model` in jeder möglichen *Pfadoperation* verwenden:
//// tab | Python 3.8+
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001.py!}
+{!> ../../docs_src/response_model/tutorial001.py!}
```
////
-/// note | "Hinweis"
+/// 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.
@@ -93,7 +93,7 @@ Beachten Sie, dass `response_model` ein Parameter der „Dekorator“-Methode is
FastAPI wird dieses `response_model` nehmen, um die Daten zu dokumentieren, validieren, usw. und auch, um **die Ausgabedaten** entsprechend der Typdeklaration **zu konvertieren und filtern**.
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie in Ihrem Editor strikte Typchecks haben, mypy, usw., können Sie den Funktions-Rückgabetyp als `Any` deklarieren.
@@ -116,7 +116,7 @@ Im Folgenden deklarieren wir ein `UserIn`-Modell; es enthält ein Klartext-Passw
//// tab | Python 3.10+
```Python hl_lines="7 9"
-{!> ../../../docs_src/response_model/tutorial002_py310.py!}
+{!> ../../docs_src/response_model/tutorial002_py310.py!}
```
////
@@ -124,7 +124,7 @@ Im Folgenden deklarieren wir ein `UserIn`-Modell; es enthält ein Klartext-Passw
//// tab | Python 3.8+
```Python hl_lines="9 11"
-{!> ../../../docs_src/response_model/tutorial002.py!}
+{!> ../../docs_src/response_model/tutorial002.py!}
```
////
@@ -143,7 +143,7 @@ Wir verwenden dieses Modell, um sowohl unsere Eingabe- als auch Ausgabedaten zu
//// tab | Python 3.10+
```Python hl_lines="16"
-{!> ../../../docs_src/response_model/tutorial002_py310.py!}
+{!> ../../docs_src/response_model/tutorial002_py310.py!}
```
////
@@ -151,7 +151,7 @@ Wir verwenden dieses Modell, um sowohl unsere Eingabe- als auch Ausgabedaten zu
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/response_model/tutorial002.py!}
+{!> ../../docs_src/response_model/tutorial002.py!}
```
////
@@ -162,7 +162,7 @@ Hier ist das möglicherweise kein Problem, da es derselbe Benutzer ist, der das
Aber wenn wir dasselbe Modell für eine andere *Pfadoperation* verwenden, könnten wir das Passwort dieses Benutzers zu jedem Client schicken.
-/// danger | "Gefahr"
+/// danger | Gefahr
Speichern Sie niemals das Klartext-Passwort eines Benutzers, oder versenden Sie es in einer Response wie dieser, wenn Sie sich nicht der resultierenden Gefahren bewusst sind und nicht wissen, was Sie tun.
@@ -175,7 +175,7 @@ Wir können stattdessen ein Eingabemodell mit dem Klartext-Passwort, und ein Aus
//// tab | Python 3.10+
```Python hl_lines="9 11 16"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -183,7 +183,7 @@ Wir können stattdessen ein Eingabemodell mit dem Klartext-Passwort, und ein Aus
//// tab | Python 3.8+
```Python hl_lines="9 11 16"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -193,7 +193,7 @@ Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zur
//// tab | Python 3.10+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -201,7 +201,7 @@ Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zur
//// tab | Python 3.8+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -211,7 +211,7 @@ Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zur
//// tab | Python 3.10+
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -219,7 +219,7 @@ Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zur
//// tab | Python 3.8+
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -249,7 +249,7 @@ Und in solchen Fällen können wir Klassen und Vererbung verwenden, um Vorteil a
//// tab | Python 3.10+
```Python hl_lines="7-10 13-14 18"
-{!> ../../../docs_src/response_model/tutorial003_01_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_01_py310.py!}
```
////
@@ -257,7 +257,7 @@ Und in solchen Fällen können wir Klassen und Vererbung verwenden, um Vorteil a
//// tab | Python 3.8+
```Python hl_lines="9-13 15-16 20"
-{!> ../../../docs_src/response_model/tutorial003_01.py!}
+{!> ../../docs_src/response_model/tutorial003_01.py!}
```
////
@@ -303,7 +303,7 @@ Es kann Fälle geben, bei denen Sie etwas zurückgeben, das kein gültiges Pydan
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}.
```Python hl_lines="8 10-11"
-{!> ../../../docs_src/response_model/tutorial003_02.py!}
+{!> ../../docs_src/response_model/tutorial003_02.py!}
```
Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist.
@@ -315,7 +315,7 @@ Und Tools werden auch glücklich sein, weil sowohl `RedirectResponse` als auch `
Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden.
```Python hl_lines="8-9"
-{!> ../../../docs_src/response_model/tutorial003_03.py!}
+{!> ../../docs_src/response_model/tutorial003_03.py!}
```
Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert.
@@ -329,7 +329,7 @@ Das gleiche wird passieren, wenn Sie eine ../../../docs_src/response_model/tutorial003_04.py!}
+{!> ../../docs_src/response_model/tutorial003_04.py!}
```
////
@@ -355,7 +355,7 @@ In diesem Fall können Sie die Generierung des Responsemodells abschalten, indem
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/response_model/tutorial003_05_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_05_py310.py!}
```
////
@@ -363,7 +363,7 @@ In diesem Fall können Sie die Generierung des Responsemodells abschalten, indem
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/response_model/tutorial003_05.py!}
+{!> ../../docs_src/response_model/tutorial003_05.py!}
```
////
@@ -377,7 +377,7 @@ Ihr Responsemodell könnte Defaultwerte haben, wie:
//// tab | Python 3.10+
```Python hl_lines="9 11-12"
-{!> ../../../docs_src/response_model/tutorial004_py310.py!}
+{!> ../../docs_src/response_model/tutorial004_py310.py!}
```
////
@@ -385,7 +385,7 @@ Ihr Responsemodell könnte Defaultwerte haben, wie:
//// tab | Python 3.9+
```Python hl_lines="11 13-14"
-{!> ../../../docs_src/response_model/tutorial004_py39.py!}
+{!> ../../docs_src/response_model/tutorial004_py39.py!}
```
////
@@ -393,7 +393,7 @@ Ihr Responsemodell könnte Defaultwerte haben, wie:
//// tab | Python 3.8+
```Python hl_lines="11 13-14"
-{!> ../../../docs_src/response_model/tutorial004.py!}
+{!> ../../docs_src/response_model/tutorial004.py!}
```
////
@@ -413,7 +413,7 @@ Sie können den *Pfadoperation-Dekorator*-Parameter `response_model_exclude_unse
//// tab | Python 3.10+
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial004_py310.py!}
+{!> ../../docs_src/response_model/tutorial004_py310.py!}
```
////
@@ -421,7 +421,7 @@ Sie können den *Pfadoperation-Dekorator*-Parameter `response_model_exclude_unse
//// tab | Python 3.9+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial004_py39.py!}
+{!> ../../docs_src/response_model/tutorial004_py39.py!}
```
////
@@ -429,7 +429,7 @@ Sie können den *Pfadoperation-Dekorator*-Parameter `response_model_exclude_unse
//// tab | Python 3.8+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial004.py!}
+{!> ../../docs_src/response_model/tutorial004.py!}
```
////
@@ -503,7 +503,7 @@ dann ist FastAPI klug genug (tatsächlich ist Pydantic klug genug) zu erkennen,
Diese Felder werden also in der JSON-Response enthalten sein.
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass Defaultwerte alles Mögliche sein können, nicht nur `None`.
@@ -519,7 +519,7 @@ Diese nehmen ein `set` von `str`s entgegen, welches Namen von Attributen sind, d
Das kann als schnelle Abkürzung verwendet werden, wenn Sie nur ein Pydantic-Modell haben und ein paar Daten von der Ausgabe ausschließen wollen.
-/// tip | "Tipp"
+/// tip | Tipp
Es wird dennoch empfohlen, dass Sie die Ideen von oben verwenden, also mehrere Klassen statt dieser Parameter.
@@ -532,7 +532,7 @@ Das trifft auch auf `response_model_by_alias` zu, welches ähnlich funktioniert.
//// tab | Python 3.10+
```Python hl_lines="29 35"
-{!> ../../../docs_src/response_model/tutorial005_py310.py!}
+{!> ../../docs_src/response_model/tutorial005_py310.py!}
```
////
@@ -540,12 +540,12 @@ Das trifft auch auf `response_model_by_alias` zu, welches ähnlich funktioniert.
//// tab | Python 3.8+
```Python hl_lines="31 37"
-{!> ../../../docs_src/response_model/tutorial005.py!}
+{!> ../../docs_src/response_model/tutorial005.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
Die Syntax `{"name", "description"}` erzeugt ein `set` mit diesen zwei Werten.
@@ -560,7 +560,7 @@ Wenn Sie vergessen, ein `set` zu verwenden, und stattdessen eine `list`e oder ei
//// tab | Python 3.10+
```Python hl_lines="29 35"
-{!> ../../../docs_src/response_model/tutorial006_py310.py!}
+{!> ../../docs_src/response_model/tutorial006_py310.py!}
```
////
@@ -568,7 +568,7 @@ Wenn Sie vergessen, ein `set` zu verwenden, und stattdessen eine `list`e oder ei
//// tab | Python 3.8+
```Python hl_lines="31 37"
-{!> ../../../docs_src/response_model/tutorial006.py!}
+{!> ../../docs_src/response_model/tutorial006.py!}
```
////
diff --git a/docs/de/docs/tutorial/response-status-code.md b/docs/de/docs/tutorial/response-status-code.md
index 5f96b83e4..a1b388a0a 100644
--- a/docs/de/docs/tutorial/response-status-code.md
+++ b/docs/de/docs/tutorial/response-status-code.md
@@ -8,11 +8,9 @@ So wie ein Responsemodell, können Sie auch einen HTTP-Statuscode für die Respo
* `@app.delete()`
* usw.
-```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
-```
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
-/// note | "Hinweis"
+/// 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.
@@ -33,7 +31,7 @@ Das wird:
-/// note | "Hinweis"
+/// note | Hinweis
Einige Responsecodes (siehe nächster Abschnitt) kennzeichnen, dass die Response keinen Body hat.
@@ -43,7 +41,7 @@ FastAPI versteht das und wird in der OpenAPI-Dokumentation anzeigen, dass es kei
## Über HTTP-Statuscodes
-/// note | "Hinweis"
+/// note | Hinweis
Wenn Sie bereits wissen, was HTTP-Statuscodes sind, überspringen Sie dieses Kapitel und fahren Sie mit dem nächsten fort.
@@ -66,7 +64,7 @@ Kurz:
* 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.
-/// tip | "Tipp"
+/// tip | Tipp
Um mehr über Statuscodes zu lernen, und welcher wofür verwendet wird, lesen Sie die MDN Dokumentation über HTTP-Statuscodes.
@@ -76,9 +74,7 @@ Um mehr über Statuscodes zu lernen, und welcher wofür verwendet wird, lesen Si
Schauen wir uns das vorherige Beispiel noch einmal an:
-```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
-```
+{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
`201` ist der Statuscode für „Created“ („Erzeugt“).
@@ -86,15 +82,13 @@ Aber Sie müssen sich nicht daran erinnern, welcher dieser Codes was bedeutet.
Sie können die Hilfsvariablen von `fastapi.status` verwenden.
-```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
-```
+{* ../../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:
-/// note | "Technische Details"
+/// note | Technische Details
Sie können auch `from starlette import status` verwenden.
diff --git a/docs/de/docs/tutorial/schema-extra-example.md b/docs/de/docs/tutorial/schema-extra-example.md
index 07b4bb759..f065ad4ca 100644
--- a/docs/de/docs/tutorial/schema-extra-example.md
+++ b/docs/de/docs/tutorial/schema-extra-example.md
@@ -8,35 +8,15 @@ Hier sind mehrere Möglichkeiten, das zu tun.
Sie können `examples` („Beispiele“) für ein Pydantic-Modell deklarieren, welche dem generierten JSON-Schema hinzugefügt werden.
-//// tab | Python 3.10+ Pydantic v2
+//// tab | Pydantic v2
-```Python hl_lines="13-24"
-{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
////
-//// tab | Python 3.10+ Pydantic v1
+//// tab | Pydantic v1
-```Python hl_lines="13-23"
-{!> ../../../docs_src/schema_extra_example/tutorial001_py310_pv1.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Pydantic v2
-
-```Python hl_lines="15-26"
-{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Pydantic v1
-
-```Python hl_lines="15-25"
-{!> ../../../docs_src/schema_extra_example/tutorial001_pv1.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
////
@@ -58,7 +38,7 @@ Sie können `schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Date
////
-/// tip | "Tipp"
+/// tip | Tipp
Mit derselben Technik können Sie das JSON-Schema erweitern und Ihre eigenen benutzerdefinierten Zusatzinformationen hinzufügen.
@@ -80,21 +60,7 @@ Mehr erfahren Sie am Ende dieser Seite.
Wenn Sie `Field()` mit Pydantic-Modellen verwenden, können Sie ebenfalls zusätzliche `examples` deklarieren:
-//// tab | Python 3.10+
-
-```Python hl_lines="2 8-11"
-{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="4 10-13"
-{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
## `examples` im JSON-Schema – OpenAPI
@@ -114,57 +80,7 @@ können Sie auch eine Gruppe von `examples` mit zusätzlichen Informationen dekl
Hier übergeben wir `examples`, welches ein einzelnes Beispiel für die in `Body()` erwarteten Daten enthält:
-//// tab | Python 3.10+
-
-```Python hl_lines="22-29"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="22-29"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="23-30"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="18-25"
-{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="20-27"
-{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *}
### Beispiel in der Dokumentations-Benutzeroberfläche
@@ -176,57 +92,7 @@ Mit jeder der oben genannten Methoden würde es in `/docs` so aussehen:
Sie können natürlich auch mehrere `examples` übergeben:
-//// tab | Python 3.10+
-
-```Python hl_lines="23-38"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="23-38"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="24-39"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="19-34"
-{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="21-36"
-{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}
Wenn Sie das tun, werden die Beispiele Teil des internen **JSON-Schemas** für diese Body-Daten.
@@ -267,57 +133,7 @@ Jedes spezifische Beispiel-`dict` in den `examples` kann Folgendes enthalten:
Sie können es so verwenden:
-//// tab | Python 3.10+
-
-```Python hl_lines="23-49"
-{!> ../../../docs_src/schema_extra_example/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="23-49"
-{!> ../../../docs_src/schema_extra_example/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="24-50"
-{!> ../../../docs_src/schema_extra_example/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="19-45"
-{!> ../../../docs_src/schema_extra_example/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ nicht annotiert
-
-/// tip | "Tipp"
-
-Bevorzugen Sie die `Annotated`-Version, falls möglich.
-
-///
-
-```Python hl_lines="21-47"
-{!> ../../../docs_src/schema_extra_example/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
### OpenAPI-Beispiele in der Dokumentations-Benutzeroberfläche
@@ -327,7 +143,7 @@ Wenn `openapi_examples` zu `Body()` hinzugefügt wird, würde `/docs` so aussehe
## Technische Details
-/// tip | "Tipp"
+/// tip | Tipp
Wenn Sie bereits **FastAPI** Version **0.99.0 oder höher** verwenden, können Sie diese Details wahrscheinlich **überspringen**.
@@ -337,7 +153,7 @@ Sie können dies als eine kurze **Geschichtsstunde** zu OpenAPI und JSON Schema
///
-/// warning | "Achtung"
+/// warning | Achtung
Dies sind sehr technische Details zu den Standards **JSON Schema** und **OpenAPI**.
diff --git a/docs/de/docs/tutorial/security/first-steps.md b/docs/de/docs/tutorial/security/first-steps.md
index 6bc42cf6c..935b8ecca 100644
--- a/docs/de/docs/tutorial/security/first-steps.md
+++ b/docs/de/docs/tutorial/security/first-steps.md
@@ -23,7 +23,7 @@ Kopieren Sie das Beispiel in eine Datei `main.py`:
//// tab | Python 3.9+
```Python
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -31,21 +31,21 @@ Kopieren Sie das Beispiel in eine Datei `main.py`:
//// tab | Python 3.8+
```Python
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
@@ -82,7 +82,7 @@ Sie werden etwa Folgendes sehen:
-/// check | "Authorize-Button!"
+/// check | Authorize-Button!
Sie haben bereits einen glänzenden, neuen „Authorize“-Button.
@@ -94,7 +94,7 @@ Und wenn Sie darauf klicken, erhalten Sie ein kleines Anmeldeformular zur Eingab
-/// note | "Hinweis"
+/// note | Hinweis
Es spielt keine Rolle, was Sie in das Formular eingeben, es wird noch nicht funktionieren. Wir kommen dahin.
@@ -157,7 +157,7 @@ Wenn wir eine Instanz der Klasse `OAuth2PasswordBearer` erstellen, übergeben wi
//// tab | Python 3.9+
```Python hl_lines="8"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -165,26 +165,26 @@ Wenn wir eine Instanz der Klasse `OAuth2PasswordBearer` erstellen, übergeben wi
//// tab | Python 3.8+
```Python hl_lines="7"
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="6"
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
Hier bezieht sich `tokenUrl="token"` auf eine relative URL `token`, die wir noch nicht erstellt haben. Da es sich um eine relative URL handelt, entspricht sie `./token`.
@@ -223,7 +223,7 @@ Jetzt können Sie dieses `oauth2_scheme` als Abhängigkeit `Depends` übergeben.
//// tab | Python 3.9+
```Python hl_lines="12"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -231,21 +231,21 @@ Jetzt können Sie dieses `oauth2_scheme` als Abhängigkeit `Depends` übergeben.
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
@@ -254,7 +254,7 @@ Diese Abhängigkeit stellt einen `str` bereit, der dem Parameter `token` der *Pf
**FastAPI** weiß, dass es diese Abhängigkeit verwenden kann, um ein „Sicherheitsschema“ im OpenAPI-Schema (und der automatischen API-Dokumentation) zu definieren.
-/// info | "Technische Details"
+/// info | Technische Details
**FastAPI** weiß, dass es die Klasse `OAuth2PasswordBearer` (deklariert in einer Abhängigkeit) verwenden kann, um das Sicherheitsschema in OpenAPI zu definieren, da es von `fastapi.security.oauth2.OAuth2` erbt, das wiederum von `fastapi.security.base.SecurityBase` erbt.
diff --git a/docs/de/docs/tutorial/security/get-current-user.md b/docs/de/docs/tutorial/security/get-current-user.md
index 8a68deeef..5f28f231f 100644
--- a/docs/de/docs/tutorial/security/get-current-user.md
+++ b/docs/de/docs/tutorial/security/get-current-user.md
@@ -5,7 +5,7 @@ Im vorherigen Kapitel hat das Sicherheitssystem (das auf dem Dependency Injectio
//// tab | Python 3.9+
```Python hl_lines="12"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -13,21 +13,21 @@ Im vorherigen Kapitel hat das Sicherheitssystem (das auf dem Dependency Injectio
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="10"
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
@@ -45,7 +45,7 @@ So wie wir Pydantic zum Deklarieren von Bodys verwenden, können wir es auch üb
//// tab | Python 3.10+
```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
+{!> ../../docs_src/security/tutorial002_an_py310.py!}
```
////
@@ -53,7 +53,7 @@ So wie wir Pydantic zum Deklarieren von Bodys verwenden, können wir es auch üb
//// tab | Python 3.9+
```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
+{!> ../../docs_src/security/tutorial002_an_py39.py!}
```
////
@@ -61,35 +61,35 @@ So wie wir Pydantic zum Deklarieren von Bodys verwenden, können wir es auch üb
//// tab | Python 3.8+
```Python hl_lines="5 13-17"
-{!> ../../../docs_src/security/tutorial002_an.py!}
+{!> ../../docs_src/security/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="3 10-14"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -107,7 +107,7 @@ So wie wir es zuvor in der *Pfadoperation* direkt gemacht haben, erhält unsere
//// tab | Python 3.10+
```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
+{!> ../../docs_src/security/tutorial002_an_py310.py!}
```
////
@@ -115,7 +115,7 @@ So wie wir es zuvor in der *Pfadoperation* direkt gemacht haben, erhält unsere
//// tab | Python 3.9+
```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
+{!> ../../docs_src/security/tutorial002_an_py39.py!}
```
////
@@ -123,35 +123,35 @@ So wie wir es zuvor in der *Pfadoperation* direkt gemacht haben, erhält unsere
//// tab | Python 3.8+
```Python hl_lines="26"
-{!> ../../../docs_src/security/tutorial002_an.py!}
+{!> ../../docs_src/security/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="23"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -163,7 +163,7 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
//// tab | Python 3.10+
```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
+{!> ../../docs_src/security/tutorial002_an_py310.py!}
```
////
@@ -171,7 +171,7 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
//// tab | Python 3.9+
```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
+{!> ../../docs_src/security/tutorial002_an_py39.py!}
```
////
@@ -179,35 +179,35 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
//// tab | Python 3.8+
```Python hl_lines="20-23 27-28"
-{!> ../../../docs_src/security/tutorial002_an.py!}
+{!> ../../docs_src/security/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="17-20 24-25"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -219,7 +219,7 @@ Und jetzt können wir wiederum `Depends` mit unserem `get_current_user` in der *
//// tab | Python 3.10+
```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
+{!> ../../docs_src/security/tutorial002_an_py310.py!}
```
////
@@ -227,7 +227,7 @@ Und jetzt können wir wiederum `Depends` mit unserem `get_current_user` in der *
//// tab | Python 3.9+
```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
+{!> ../../docs_src/security/tutorial002_an_py39.py!}
```
////
@@ -235,35 +235,35 @@ Und jetzt können wir wiederum `Depends` mit unserem `get_current_user` in der *
//// tab | Python 3.8+
```Python hl_lines="32"
-{!> ../../../docs_src/security/tutorial002_an.py!}
+{!> ../../docs_src/security/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="29"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -272,7 +272,7 @@ Beachten Sie, dass wir als Typ von `current_user` das Pydantic-Modell `User` dek
Das wird uns innerhalb der Funktion bei Codevervollständigung und Typprüfungen helfen.
-/// tip | "Tipp"
+/// tip | Tipp
Sie erinnern sich vielleicht, dass Requestbodys ebenfalls mit Pydantic-Modellen deklariert werden.
@@ -323,7 +323,7 @@ Und alle diese Tausenden von *Pfadoperationen* können nur drei Zeilen lang sein
//// tab | Python 3.10+
```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
+{!> ../../docs_src/security/tutorial002_an_py310.py!}
```
////
@@ -331,7 +331,7 @@ Und alle diese Tausenden von *Pfadoperationen* können nur drei Zeilen lang sein
//// tab | Python 3.9+
```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
+{!> ../../docs_src/security/tutorial002_an_py39.py!}
```
////
@@ -339,35 +339,35 @@ Und alle diese Tausenden von *Pfadoperationen* können nur drei Zeilen lang sein
//// tab | Python 3.8+
```Python hl_lines="31-33"
-{!> ../../../docs_src/security/tutorial002_an.py!}
+{!> ../../docs_src/security/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="28-30"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
diff --git a/docs/de/docs/tutorial/security/index.md b/docs/de/docs/tutorial/security/index.md
index ad0927361..b01243901 100644
--- a/docs/de/docs/tutorial/security/index.md
+++ b/docs/de/docs/tutorial/security/index.md
@@ -32,7 +32,7 @@ Heutzutage ist es nicht sehr populär und wird kaum verwendet.
OAuth2 spezifiziert nicht, wie die Kommunikation verschlüsselt werden soll, sondern erwartet, dass Ihre Anwendung mit HTTPS bereitgestellt wird.
-/// tip | "Tipp"
+/// tip | Tipp
Im Abschnitt über **Deployment** erfahren Sie, wie Sie HTTPS mithilfe von Traefik und Let's Encrypt kostenlos einrichten.
@@ -89,7 +89,7 @@ OpenAPI definiert die folgenden Sicherheitsschemas:
* Diese automatische Erkennung ist es, die in der OpenID Connect Spezifikation definiert ist.
-/// tip | "Tipp"
+/// tip | Tipp
Auch die Integration anderer Authentifizierungs-/Autorisierungsanbieter wie Google, Facebook, Twitter, GitHub, usw. ist möglich und relativ einfach.
diff --git a/docs/de/docs/tutorial/security/oauth2-jwt.md b/docs/de/docs/tutorial/security/oauth2-jwt.md
index 88f0dbe42..25c1e1c97 100644
--- a/docs/de/docs/tutorial/security/oauth2-jwt.md
+++ b/docs/de/docs/tutorial/security/oauth2-jwt.md
@@ -44,7 +44,7 @@ $ pip install "python-jose[cryptography]"
Hier verwenden wir das empfohlene: pyca/cryptography.
-/// tip | "Tipp"
+/// tip | Tipp
Dieses Tutorial verwendete zuvor PyJWT.
@@ -86,7 +86,7 @@ $ pip install "passlib[bcrypt]"
-/// tip | "Tipp"
+/// tip | Tipp
Mit `passlib` können Sie sogar konfigurieren, Passwörter zu lesen, die von **Django**, einem **Flask**-Sicherheit-Plugin, oder vielen anderen erstellt wurden.
@@ -102,7 +102,7 @@ Importieren Sie die benötigten Tools aus `passlib`.
Erstellen Sie einen PassLib-„Kontext“. Der wird für das Hashen und Verifizieren von Passwörtern verwendet.
-/// tip | "Tipp"
+/// tip | Tipp
Der PassLib-Kontext kann auch andere Hashing-Algorithmen verwenden, einschließlich deprecateter Alter, um etwa nur eine Verifizierung usw. zu ermöglichen.
@@ -121,7 +121,7 @@ Und noch eine, um einen Benutzer zu authentifizieren und zurückzugeben.
//// tab | Python 3.10+
```Python hl_lines="7 48 55-56 59-60 69-75"
-{!> ../../../docs_src/security/tutorial004_an_py310.py!}
+{!> ../../docs_src/security/tutorial004_an_py310.py!}
```
////
@@ -129,7 +129,7 @@ Und noch eine, um einen Benutzer zu authentifizieren und zurückzugeben.
//// tab | Python 3.9+
```Python hl_lines="7 48 55-56 59-60 69-75"
-{!> ../../../docs_src/security/tutorial004_an_py39.py!}
+{!> ../../docs_src/security/tutorial004_an_py39.py!}
```
////
@@ -137,40 +137,40 @@ Und noch eine, um einen Benutzer zu authentifizieren und zurückzugeben.
//// tab | Python 3.8+
```Python hl_lines="7 49 56-57 60-61 70-76"
-{!> ../../../docs_src/security/tutorial004_an.py!}
+{!> ../../docs_src/security/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="6 47 54-55 58-59 68-74"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="7 48 55-56 59-60 69-75"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
-/// note | "Hinweis"
+/// note | Hinweis
Wenn Sie sich die neue (gefakte) Datenbank `fake_users_db` anschauen, sehen Sie, wie das gehashte Passwort jetzt aussieht: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
@@ -207,7 +207,7 @@ Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren.
//// tab | Python 3.10+
```Python hl_lines="6 12-14 28-30 78-86"
-{!> ../../../docs_src/security/tutorial004_an_py310.py!}
+{!> ../../docs_src/security/tutorial004_an_py310.py!}
```
////
@@ -215,7 +215,7 @@ Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren.
//// tab | Python 3.9+
```Python hl_lines="6 12-14 28-30 78-86"
-{!> ../../../docs_src/security/tutorial004_an_py39.py!}
+{!> ../../docs_src/security/tutorial004_an_py39.py!}
```
////
@@ -223,35 +223,35 @@ Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren.
//// tab | Python 3.8+
```Python hl_lines="6 13-15 29-31 79-87"
-{!> ../../../docs_src/security/tutorial004_an.py!}
+{!> ../../docs_src/security/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="5 11-13 27-29 77-85"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="6 12-14 28-30 78-86"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -267,7 +267,7 @@ Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
//// tab | Python 3.10+
```Python hl_lines="89-106"
-{!> ../../../docs_src/security/tutorial004_an_py310.py!}
+{!> ../../docs_src/security/tutorial004_an_py310.py!}
```
////
@@ -275,7 +275,7 @@ Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
//// tab | Python 3.9+
```Python hl_lines="89-106"
-{!> ../../../docs_src/security/tutorial004_an_py39.py!}
+{!> ../../docs_src/security/tutorial004_an_py39.py!}
```
////
@@ -283,35 +283,35 @@ Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
//// tab | Python 3.8+
```Python hl_lines="90-107"
-{!> ../../../docs_src/security/tutorial004_an.py!}
+{!> ../../docs_src/security/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="88-105"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="89-106"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -325,7 +325,7 @@ Erstellen Sie einen echten JWT-Zugriffstoken und geben Sie ihn zurück.
//// tab | Python 3.10+
```Python hl_lines="117-132"
-{!> ../../../docs_src/security/tutorial004_an_py310.py!}
+{!> ../../docs_src/security/tutorial004_an_py310.py!}
```
////
@@ -333,7 +333,7 @@ Erstellen Sie einen echten JWT-Zugriffstoken und geben Sie ihn zurück.
//// tab | Python 3.9+
```Python hl_lines="117-132"
-{!> ../../../docs_src/security/tutorial004_an_py39.py!}
+{!> ../../docs_src/security/tutorial004_an_py39.py!}
```
////
@@ -341,35 +341,35 @@ Erstellen Sie einen echten JWT-Zugriffstoken und geben Sie ihn zurück.
//// tab | Python 3.8+
```Python hl_lines="118-133"
-{!> ../../../docs_src/security/tutorial004_an.py!}
+{!> ../../docs_src/security/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="114-129"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="115-130"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -436,7 +436,7 @@ Wenn Sie die Developer Tools öffnen, können Sie sehen, dass die gesendeten Dat
-/// note | "Hinweis"
+/// note | Hinweis
Beachten Sie den Header `Authorization` mit einem Wert, der mit `Bearer` beginnt.
diff --git a/docs/de/docs/tutorial/security/simple-oauth2.md b/docs/de/docs/tutorial/security/simple-oauth2.md
index 3b1c4ae28..2fa1385b0 100644
--- a/docs/de/docs/tutorial/security/simple-oauth2.md
+++ b/docs/de/docs/tutorial/security/simple-oauth2.md
@@ -55,7 +55,7 @@ Importieren Sie zunächst `OAuth2PasswordRequestForm` und verwenden Sie es als A
//// tab | Python 3.10+
```Python hl_lines="4 78"
-{!> ../../../docs_src/security/tutorial003_an_py310.py!}
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
```
////
@@ -63,7 +63,7 @@ Importieren Sie zunächst `OAuth2PasswordRequestForm` und verwenden Sie es als A
//// tab | Python 3.9+
```Python hl_lines="4 78"
-{!> ../../../docs_src/security/tutorial003_an_py39.py!}
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
```
////
@@ -71,35 +71,35 @@ Importieren Sie zunächst `OAuth2PasswordRequestForm` und verwenden Sie es als A
//// tab | Python 3.8+
```Python hl_lines="4 79"
-{!> ../../../docs_src/security/tutorial003_an.py!}
+{!> ../../docs_src/security/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="2 74"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="4 76"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -111,7 +111,7 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
* Einem optionalen `scope`-Feld als langem String, bestehend aus durch Leerzeichen getrennten Strings.
* Einem optionalen `grant_type` („Art der Anmeldung“).
-/// tip | "Tipp"
+/// tip | Tipp
Die OAuth2-Spezifikation *erfordert* tatsächlich ein Feld `grant_type` mit dem festen Wert `password`, aber `OAuth2PasswordRequestForm` erzwingt dies nicht.
@@ -136,7 +136,7 @@ Da es sich jedoch um einen häufigen Anwendungsfall handelt, wird er zur Vereinf
### Die Formulardaten verwenden
-/// tip | "Tipp"
+/// tip | Tipp
Die Instanz der Klassenabhängigkeit `OAuth2PasswordRequestForm` verfügt, statt eines Attributs `scope` mit dem durch Leerzeichen getrennten langen String, über das Attribut `scopes` mit einer tatsächlichen Liste von Strings, einem für jeden gesendeten Scope.
@@ -153,7 +153,7 @@ Für den Fehler verwenden wir die Exception `HTTPException`:
//// tab | Python 3.10+
```Python hl_lines="3 79-81"
-{!> ../../../docs_src/security/tutorial003_an_py310.py!}
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
```
////
@@ -161,7 +161,7 @@ Für den Fehler verwenden wir die Exception `HTTPException`:
//// tab | Python 3.9+
```Python hl_lines="3 79-81"
-{!> ../../../docs_src/security/tutorial003_an_py39.py!}
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
```
////
@@ -169,35 +169,35 @@ Für den Fehler verwenden wir die Exception `HTTPException`:
//// tab | Python 3.8+
```Python hl_lines="3 80-82"
-{!> ../../../docs_src/security/tutorial003_an.py!}
+{!> ../../docs_src/security/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="1 75-77"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="3 77-79"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -229,7 +229,7 @@ Der Dieb kann also nicht versuchen, die gleichen Passwörter in einem anderen Sy
//// tab | Python 3.10+
```Python hl_lines="82-85"
-{!> ../../../docs_src/security/tutorial003_an_py310.py!}
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
```
////
@@ -237,7 +237,7 @@ Der Dieb kann also nicht versuchen, die gleichen Passwörter in einem anderen Sy
//// tab | Python 3.9+
```Python hl_lines="82-85"
-{!> ../../../docs_src/security/tutorial003_an_py39.py!}
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
```
////
@@ -245,35 +245,35 @@ Der Dieb kann also nicht versuchen, die gleichen Passwörter in einem anderen Sy
//// tab | Python 3.8+
```Python hl_lines="83-86"
-{!> ../../../docs_src/security/tutorial003_an.py!}
+{!> ../../docs_src/security/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="78-81"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="80-83"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -310,7 +310,7 @@ Und es sollte einen `access_token` haben, mit einem String, der unseren Zugriffs
In diesem einfachen Beispiel gehen wir einfach völlig unsicher vor und geben denselben `username` wie der Token zurück.
-/// tip | "Tipp"
+/// tip | Tipp
Im nächsten Kapitel sehen Sie eine wirklich sichere Implementierung mit Passwort-Hashing und JWT-Tokens.
@@ -321,7 +321,7 @@ Aber konzentrieren wir uns zunächst auf die spezifischen Details, die wir benö
//// tab | Python 3.10+
```Python hl_lines="87"
-{!> ../../../docs_src/security/tutorial003_an_py310.py!}
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
```
////
@@ -329,7 +329,7 @@ Aber konzentrieren wir uns zunächst auf die spezifischen Details, die wir benö
//// tab | Python 3.9+
```Python hl_lines="87"
-{!> ../../../docs_src/security/tutorial003_an_py39.py!}
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
```
////
@@ -337,40 +337,40 @@ Aber konzentrieren wir uns zunächst auf die spezifischen Details, die wir benö
//// tab | Python 3.8+
```Python hl_lines="88"
-{!> ../../../docs_src/security/tutorial003_an.py!}
+{!> ../../docs_src/security/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="83"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="85"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
-/// tip | "Tipp"
+/// tip | Tipp
Gemäß der Spezifikation sollten Sie ein JSON mit einem `access_token` und einem `token_type` zurückgeben, genau wie in diesem Beispiel.
@@ -397,7 +397,7 @@ In unserem Endpunkt erhalten wir also nur dann einen Benutzer, wenn der Benutzer
//// tab | Python 3.10+
```Python hl_lines="58-66 69-74 94"
-{!> ../../../docs_src/security/tutorial003_an_py310.py!}
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
```
////
@@ -405,7 +405,7 @@ In unserem Endpunkt erhalten wir also nur dann einen Benutzer, wenn der Benutzer
//// tab | Python 3.9+
```Python hl_lines="58-66 69-74 94"
-{!> ../../../docs_src/security/tutorial003_an_py39.py!}
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
```
////
@@ -413,35 +413,35 @@ In unserem Endpunkt erhalten wir also nur dann einen Benutzer, wenn der Benutzer
//// tab | Python 3.8+
```Python hl_lines="59-67 70-75 95"
-{!> ../../../docs_src/security/tutorial003_an.py!}
+{!> ../../docs_src/security/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="56-64 67-70 88"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python hl_lines="58-66 69-72 90"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
diff --git a/docs/de/docs/tutorial/static-files.md b/docs/de/docs/tutorial/static-files.md
index cca8cd0ea..aa44e3f4e 100644
--- a/docs/de/docs/tutorial/static-files.md
+++ b/docs/de/docs/tutorial/static-files.md
@@ -8,10 +8,10 @@ Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisc
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
```Python hl_lines="2 6"
-{!../../../docs_src/static_files/tutorial001.py!}
+{!../../docs_src/static_files/tutorial001.py!}
```
-/// note | "Technische Details"
+/// note | Technische Details
Sie könnten auch `from starlette.staticfiles import StaticFiles` verwenden.
diff --git a/docs/de/docs/tutorial/testing.md b/docs/de/docs/tutorial/testing.md
index 43ced2aae..53459342b 100644
--- a/docs/de/docs/tutorial/testing.md
+++ b/docs/de/docs/tutorial/testing.md
@@ -27,10 +27,10 @@ Verwenden Sie das `TestClient`-Objekt auf die gleiche Weise wie `httpx`.
Schreiben Sie einfache `assert`-Anweisungen mit den Standard-Python-Ausdrücken, die Sie überprüfen müssen (wiederum, Standard-`pytest`).
```Python hl_lines="2 12 15-18"
-{!../../../docs_src/app_testing/tutorial001.py!}
+{!../../docs_src/app_testing/tutorial001.py!}
```
-/// tip | "Tipp"
+/// tip | Tipp
Beachten Sie, dass die Testfunktionen normal `def` und nicht `async def` sind.
@@ -40,7 +40,7 @@ Dadurch können Sie `pytest` ohne Komplikationen direkt nutzen.
///
-/// note | "Technische Details"
+/// note | Technische Details
Sie könnten auch `from starlette.testclient import TestClient` verwenden.
@@ -48,7 +48,7 @@ Sie könnten auch `from starlette.testclient import TestClient` verwenden.
///
-/// tip | "Tipp"
+/// 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.
@@ -75,7 +75,7 @@ In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung:
```Python
-{!../../../docs_src/app_testing/main.py!}
+{!../../docs_src/app_testing/main.py!}
```
### Testdatei
@@ -93,7 +93,7 @@ Dann könnten Sie eine Datei `test_main.py` mit Ihren Tests haben. Sie könnte s
Da sich diese Datei im selben Package befindet, können Sie relative Importe verwenden, um das Objekt `app` aus dem `main`-Modul (`main.py`) zu importieren:
```Python hl_lines="3"
-{!../../../docs_src/app_testing/test_main.py!}
+{!../../docs_src/app_testing/test_main.py!}
```
... und haben den Code für die Tests wie zuvor.
@@ -125,7 +125,7 @@ Beide *Pfadoperationen* erfordern einen `X-Token`-Header.
//// tab | Python 3.10+
```Python
-{!> ../../../docs_src/app_testing/app_b_an_py310/main.py!}
+{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
```
////
@@ -133,7 +133,7 @@ Beide *Pfadoperationen* erfordern einen `X-Token`-Header.
//// tab | Python 3.9+
```Python
-{!> ../../../docs_src/app_testing/app_b_an_py39/main.py!}
+{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
```
////
@@ -141,35 +141,35 @@ Beide *Pfadoperationen* erfordern einen `X-Token`-Header.
//// tab | Python 3.8+
```Python
-{!> ../../../docs_src/app_testing/app_b_an/main.py!}
+{!> ../../docs_src/app_testing/app_b_an/main.py!}
```
////
//// tab | Python 3.10+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python
-{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
+{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
//// tab | Python 3.8+ nicht annotiert
-/// tip | "Tipp"
+/// tip | Tipp
Bevorzugen Sie die `Annotated`-Version, falls möglich.
///
```Python
-{!> ../../../docs_src/app_testing/app_b/main.py!}
+{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
@@ -179,7 +179,7 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
Anschließend könnten Sie `test_main.py` mit den erweiterten Tests aktualisieren:
```Python
-{!> ../../../docs_src/app_testing/app_b/test_main.py!}
+{!> ../../docs_src/app_testing/app_b/test_main.py!}
```
Wenn Sie möchten, dass der Client Informationen im Request übergibt und Sie nicht wissen, wie das geht, können Sie suchen (googeln), wie es mit `httpx` gemacht wird, oder sogar, wie es mit `requests` gemacht wird, da das Design von HTTPX auf dem Design von Requests basiert.
diff --git a/docs/em/docs/advanced/additional-responses.md b/docs/em/docs/advanced/additional-responses.md
index 7a70718c5..e4442135e 100644
--- a/docs/em/docs/advanced/additional-responses.md
+++ b/docs/em/docs/advanced/additional-responses.md
@@ -27,7 +27,7 @@
🖼, 📣 ➕1️⃣ 📨 ⏮️ 👔 📟 `404` & Pydantic 🏷 `Message`, 👆 💪 ✍:
```Python hl_lines="18 22"
-{!../../../docs_src/additional_responses/tutorial001.py!}
+{!../../docs_src/additional_responses/tutorial001.py!}
```
/// note
@@ -178,7 +178,7 @@
🖼, 👆 💪 🚮 🌖 📻 🆎 `image/png`, 📣 👈 👆 *➡ 🛠️* 💪 📨 🎻 🎚 (⏮️ 📻 🆎 `application/json`) ⚖️ 🇩🇴 🖼:
```Python hl_lines="19-24 28"
-{!../../../docs_src/additional_responses/tutorial002.py!}
+{!../../docs_src/additional_responses/tutorial002.py!}
```
/// note
@@ -208,7 +208,7 @@
& 📨 ⏮️ 👔 📟 `200` 👈 ⚙️ 👆 `response_model`, ✋️ 🔌 🛃 `example`:
```Python hl_lines="20-31"
-{!../../../docs_src/additional_responses/tutorial003.py!}
+{!../../docs_src/additional_responses/tutorial003.py!}
```
⚫️ 🔜 🌐 🌀 & 🔌 👆 🗄, & 🎦 🛠️ 🩺:
@@ -244,7 +244,7 @@ new_dict = {**old_dict, "new key": "new value"}
🖼:
```Python hl_lines="13-17 26"
-{!../../../docs_src/additional_responses/tutorial004.py!}
+{!../../docs_src/additional_responses/tutorial004.py!}
```
## 🌖 ℹ 🔃 🗄 📨
diff --git a/docs/em/docs/advanced/additional-status-codes.md b/docs/em/docs/advanced/additional-status-codes.md
index 3f3b0aea4..5eb2ec90e 100644
--- a/docs/em/docs/advanced/additional-status-codes.md
+++ b/docs/em/docs/advanced/additional-status-codes.md
@@ -15,7 +15,7 @@
🏆 👈, 🗄 `JSONResponse`, & 📨 👆 🎚 📤 🔗, ⚒ `status_code` 👈 👆 💚:
```Python hl_lines="4 25"
-{!../../../docs_src/additional_status_codes/tutorial001.py!}
+{!../../docs_src/additional_status_codes/tutorial001.py!}
```
/// warning
@@ -28,7 +28,7 @@
///
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import JSONResponse`.
diff --git a/docs/em/docs/advanced/advanced-dependencies.md b/docs/em/docs/advanced/advanced-dependencies.md
index 22044c783..721428ce4 100644
--- a/docs/em/docs/advanced/advanced-dependencies.md
+++ b/docs/em/docs/advanced/advanced-dependencies.md
@@ -19,7 +19,7 @@
👈, 👥 📣 👩🔬 `__call__`:
```Python hl_lines="10"
-{!../../../docs_src/dependencies/tutorial011.py!}
+{!../../docs_src/dependencies/tutorial011.py!}
```
👉 💼, 👉 `__call__` ⚫️❔ **FastAPI** 🔜 ⚙️ ✅ 🌖 🔢 & 🎧-🔗, & 👉 ⚫️❔ 🔜 🤙 🚶♀️ 💲 🔢 👆 *➡ 🛠️ 🔢* ⏪.
@@ -29,7 +29,7 @@
& 🔜, 👥 💪 ⚙️ `__init__` 📣 🔢 👐 👈 👥 💪 ⚙️ "🔗" 🔗:
```Python hl_lines="7"
-{!../../../docs_src/dependencies/tutorial011.py!}
+{!../../docs_src/dependencies/tutorial011.py!}
```
👉 💼, **FastAPI** 🏆 🚫 ⏱ 👆 ⚖️ 💅 🔃 `__init__`, 👥 🔜 ⚙️ ⚫️ 🔗 👆 📟.
@@ -39,7 +39,7 @@
👥 💪 ✍ 👐 👉 🎓 ⏮️:
```Python hl_lines="16"
-{!../../../docs_src/dependencies/tutorial011.py!}
+{!../../docs_src/dependencies/tutorial011.py!}
```
& 👈 🌌 👥 💪 "🔗" 👆 🔗, 👈 🔜 ✔️ `"bar"` 🔘 ⚫️, 🔢 `checker.fixed_content`.
@@ -57,7 +57,7 @@ checker(q="somequery")
...& 🚶♀️ ⚫️❔ 👈 📨 💲 🔗 👆 *➡ 🛠️ 🔢* 🔢 `fixed_content_included`:
```Python hl_lines="20"
-{!../../../docs_src/dependencies/tutorial011.py!}
+{!../../docs_src/dependencies/tutorial011.py!}
```
/// tip
diff --git a/docs/em/docs/advanced/async-tests.md b/docs/em/docs/advanced/async-tests.md
index 11f885fe6..4d468acd4 100644
--- a/docs/em/docs/advanced/async-tests.md
+++ b/docs/em/docs/advanced/async-tests.md
@@ -33,13 +33,13 @@
📁 `main.py` 🔜 ✔️:
```Python
-{!../../../docs_src/async_tests/main.py!}
+{!../../docs_src/async_tests/main.py!}
```
📁 `test_main.py` 🔜 ✔️ 💯 `main.py`, ⚫️ 💪 👀 💖 👉 🔜:
```Python
-{!../../../docs_src/async_tests/test_main.py!}
+{!../../docs_src/async_tests/test_main.py!}
```
## 🏃 ⚫️
@@ -61,7 +61,7 @@ $ pytest
📑 `@pytest.mark.anyio` 💬 ✳ 👈 👉 💯 🔢 🔜 🤙 🔁:
```Python hl_lines="7"
-{!../../../docs_src/async_tests/test_main.py!}
+{!../../docs_src/async_tests/test_main.py!}
```
/// tip
@@ -73,7 +73,7 @@ $ pytest
⤴️ 👥 💪 ✍ `AsyncClient` ⏮️ 📱, & 📨 🔁 📨 ⚫️, ⚙️ `await`.
```Python hl_lines="9-12"
-{!../../../docs_src/async_tests/test_main.py!}
+{!../../docs_src/async_tests/test_main.py!}
```
👉 🌓:
diff --git a/docs/em/docs/advanced/behind-a-proxy.md b/docs/em/docs/advanced/behind-a-proxy.md
index bb65e1487..36aa2e6b3 100644
--- a/docs/em/docs/advanced/behind-a-proxy.md
+++ b/docs/em/docs/advanced/behind-a-proxy.md
@@ -80,7 +80,7 @@ $ uvicorn main:app --root-path /api/v1
🚥 👆 ⚙️ Hypercorn, ⚫️ ✔️ 🎛 `--root-path`.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
🔫 🔧 🔬 `root_path` 👉 ⚙️ 💼.
@@ -95,7 +95,7 @@ $ uvicorn main:app --root-path /api/v1
📥 👥 ✅ ⚫️ 📧 🎦 🎯.
```Python hl_lines="8"
-{!../../../docs_src/behind_a_proxy/tutorial001.py!}
+{!../../docs_src/behind_a_proxy/tutorial001.py!}
```
⤴️, 🚥 👆 ▶️ Uvicorn ⏮️:
@@ -124,7 +124,7 @@ $ uvicorn main:app --root-path /api/v1
👐, 🚥 👆 🚫 ✔️ 🌌 🚚 📋 ⏸ 🎛 💖 `--root-path` ⚖️ 🌓, 👆 💪 ⚒ `root_path` 🔢 🕐❔ 🏗 👆 FastAPI 📱:
```Python hl_lines="3"
-{!../../../docs_src/behind_a_proxy/tutorial002.py!}
+{!../../docs_src/behind_a_proxy/tutorial002.py!}
```
🚶♀️ `root_path` `FastAPI` 🔜 🌓 🚶♀️ `--root-path` 📋 ⏸ 🎛 Uvicorn ⚖️ Hypercorn.
@@ -306,7 +306,7 @@ $ uvicorn main:app --root-path /api/v1
🖼:
```Python hl_lines="4-7"
-{!../../../docs_src/behind_a_proxy/tutorial003.py!}
+{!../../docs_src/behind_a_proxy/tutorial003.py!}
```
🔜 🏗 🗄 🔗 💖:
@@ -355,7 +355,7 @@ $ uvicorn main:app --root-path /api/v1
🚥 👆 🚫 💚 **FastAPI** 🔌 🏧 💽 ⚙️ `root_path`, 👆 💪 ⚙️ 🔢 `root_path_in_servers=False`:
```Python hl_lines="9"
-{!../../../docs_src/behind_a_proxy/tutorial004.py!}
+{!../../docs_src/behind_a_proxy/tutorial004.py!}
```
& ⤴️ ⚫️ 🏆 🚫 🔌 ⚫️ 🗄 🔗.
diff --git a/docs/em/docs/advanced/custom-response.md b/docs/em/docs/advanced/custom-response.md
index eec87b91b..301f99957 100644
--- a/docs/em/docs/advanced/custom-response.md
+++ b/docs/em/docs/advanced/custom-response.md
@@ -31,7 +31,7 @@
✋️ 🚥 👆 🎯 👈 🎚 👈 👆 🛬 **🎻 ⏮️ 🎻**, 👆 💪 🚶♀️ ⚫️ 🔗 📨 🎓 & ❎ ➕ 🌥 👈 FastAPI 🔜 ✔️ 🚶♀️ 👆 📨 🎚 🔘 `jsonable_encoder` ⏭ 🚶♀️ ⚫️ 📨 🎓.
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001b.py!}
+{!../../docs_src/custom_response/tutorial001b.py!}
```
/// info
@@ -58,7 +58,7 @@
* 🚶♀️ `HTMLResponse` 🔢 `response_class` 👆 *➡ 🛠️ 👨🎨*.
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial002.py!}
+{!../../docs_src/custom_response/tutorial002.py!}
```
/// info
@@ -78,7 +78,7 @@
🎏 🖼 ⚪️➡️ 🔛, 🛬 `HTMLResponse`, 💪 👀 💖:
```Python hl_lines="2 7 19"
-{!../../../docs_src/custom_response/tutorial003.py!}
+{!../../docs_src/custom_response/tutorial003.py!}
```
/// warning
@@ -104,7 +104,7 @@
🖼, ⚫️ 💪 🕳 💖:
```Python hl_lines="7 21 23"
-{!../../../docs_src/custom_response/tutorial004.py!}
+{!../../docs_src/custom_response/tutorial004.py!}
```
👉 🖼, 🔢 `generate_html_response()` ⏪ 🏗 & 📨 `Response` ↩️ 🛬 🕸 `str`.
@@ -121,7 +121,7 @@
✔️ 🤯 👈 👆 💪 ⚙️ `Response` 📨 🕳 🙆, ⚖️ ✍ 🛃 🎧-🎓.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import HTMLResponse`.
@@ -145,7 +145,7 @@
FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎 🎚, ⚓️ 🔛 = & 🔁 = ✍ 🆎.
```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
+{!../../docs_src/response_directly/tutorial002.py!}
```
### `HTMLResponse`
@@ -157,7 +157,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
✊ ✍ ⚖️ 🔢 & 📨 ✅ ✍ 📨.
```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial005.py!}
+{!../../docs_src/custom_response/tutorial005.py!}
```
### `JSONResponse`
@@ -181,7 +181,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
///
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001.py!}
+{!../../docs_src/custom_response/tutorial001.py!}
```
/// tip
@@ -197,7 +197,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
👆 💪 📨 `RedirectResponse` 🔗:
```Python hl_lines="2 9"
-{!../../../docs_src/custom_response/tutorial006.py!}
+{!../../docs_src/custom_response/tutorial006.py!}
```
---
@@ -206,7 +206,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial006b.py!}
+{!../../docs_src/custom_response/tutorial006b.py!}
```
🚥 👆 👈, ⤴️ 👆 💪 📨 📛 🔗 ⚪️➡️ 👆 *➡ 🛠️* 🔢.
@@ -218,7 +218,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
👆 💪 ⚙️ `status_code` 🔢 🌀 ⏮️ `response_class` 🔢:
```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial006c.py!}
+{!../../docs_src/custom_response/tutorial006c.py!}
```
### `StreamingResponse`
@@ -226,7 +226,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
✊ 🔁 🚂 ⚖️ 😐 🚂/🎻 & 🎏 📨 💪.
```Python hl_lines="2 14"
-{!../../../docs_src/custom_response/tutorial007.py!}
+{!../../docs_src/custom_response/tutorial007.py!}
```
#### ⚙️ `StreamingResponse` ⏮️ 📁-💖 🎚
@@ -238,7 +238,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
👉 🔌 📚 🗃 🔗 ⏮️ ☁ 💾, 📹 🏭, & 🎏.
```{ .python .annotate hl_lines="2 10-12 14" }
-{!../../../docs_src/custom_response/tutorial008.py!}
+{!../../docs_src/custom_response/tutorial008.py!}
```
1️⃣. 👉 🚂 🔢. ⚫️ "🚂 🔢" ↩️ ⚫️ 🔌 `yield` 📄 🔘.
@@ -269,13 +269,13 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
📁 📨 🔜 🔌 ☑ `Content-Length`, `Last-Modified` & `ETag` 🎚.
```Python hl_lines="2 10"
-{!../../../docs_src/custom_response/tutorial009.py!}
+{!../../docs_src/custom_response/tutorial009.py!}
```
👆 💪 ⚙️ `response_class` 🔢:
```Python hl_lines="2 8 10"
-{!../../../docs_src/custom_response/tutorial009b.py!}
+{!../../docs_src/custom_response/tutorial009b.py!}
```
👉 💼, 👆 💪 📨 📁 ➡ 🔗 ⚪️➡️ 👆 *➡ 🛠️* 🔢.
@@ -291,7 +291,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
👆 💪 ✍ `CustomORJSONResponse`. 👑 👜 👆 ✔️ ✍ `Response.render(content)` 👩🔬 👈 📨 🎚 `bytes`:
```Python hl_lines="9-14 17"
-{!../../../docs_src/custom_response/tutorial009c.py!}
+{!../../docs_src/custom_response/tutorial009c.py!}
```
🔜 ↩️ 🛬:
@@ -319,7 +319,7 @@ FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎
🖼 🔛, **FastAPI** 🔜 ⚙️ `ORJSONResponse` 🔢, 🌐 *➡ 🛠️*, ↩️ `JSONResponse`.
```Python hl_lines="2 4"
-{!../../../docs_src/custom_response/tutorial010.py!}
+{!../../docs_src/custom_response/tutorial010.py!}
```
/// tip
diff --git a/docs/em/docs/advanced/dataclasses.md b/docs/em/docs/advanced/dataclasses.md
index 3f49ef07c..ab76e5083 100644
--- a/docs/em/docs/advanced/dataclasses.md
+++ b/docs/em/docs/advanced/dataclasses.md
@@ -5,7 +5,7 @@ FastAPI 🏗 🔛 🔝 **Pydantic**, & 👤 ✔️ 🌏 👆 ❔ ⚙️ Pyda
✋️ FastAPI 🐕🦺 ⚙️ `dataclasses` 🎏 🌌:
```Python hl_lines="1 7-12 19-20"
-{!../../../docs_src/dataclasses/tutorial001.py!}
+{!../../docs_src/dataclasses/tutorial001.py!}
```
👉 🐕🦺 👏 **Pydantic**, ⚫️ ✔️ 🔗 🐕🦺 `dataclasses`.
@@ -35,7 +35,7 @@ FastAPI 🏗 🔛 🔝 **Pydantic**, & 👤 ✔️ 🌏 👆 ❔ ⚙️ Pyda
👆 💪 ⚙️ `dataclasses` `response_model` 🔢:
```Python hl_lines="1 7-13 19"
-{!../../../docs_src/dataclasses/tutorial002.py!}
+{!../../docs_src/dataclasses/tutorial002.py!}
```
🎻 🔜 🔁 🗜 Pydantic 🎻.
@@ -53,7 +53,7 @@ FastAPI 🏗 🔛 🔝 **Pydantic**, & 👤 ✔️ 🌏 👆 ❔ ⚙️ Pyda
👈 💼, 👆 💪 🎯 💱 🐩 `dataclasses` ⏮️ `pydantic.dataclasses`, ❔ 💧-♻:
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
-{!../../../docs_src/dataclasses/tutorial003.py!}
+{!../../docs_src/dataclasses/tutorial003.py!}
```
1️⃣. 👥 🗄 `field` ⚪️➡️ 🐩 `dataclasses`.
diff --git a/docs/em/docs/advanced/events.md b/docs/em/docs/advanced/events.md
index 12c902c18..2eae2b366 100644
--- a/docs/em/docs/advanced/events.md
+++ b/docs/em/docs/advanced/events.md
@@ -31,7 +31,7 @@
👥 ✍ 🔁 🔢 `lifespan()` ⏮️ `yield` 💖 👉:
```Python hl_lines="16 19"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
📥 👥 ⚖ 😥 *🕴* 🛠️ 🚚 🏷 🚮 (❌) 🏷 🔢 📖 ⏮️ 🎰 🏫 🏷 ⏭ `yield`. 👉 📟 🔜 🛠️ **⏭** 🈸 **▶️ ✊ 📨**, ⏮️ *🕴*.
@@ -51,7 +51,7 @@
🥇 👜 👀, 👈 👥 ⚖ 🔁 🔢 ⏮️ `yield`. 👉 📶 🎏 🔗 ⏮️ `yield`.
```Python hl_lines="14-19"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
🥇 🍕 🔢, ⏭ `yield`, 🔜 🛠️ **⏭** 🈸 ▶️.
@@ -65,7 +65,7 @@
👈 🗜 🔢 🔘 🕳 🤙 "**🔁 🔑 👨💼**".
```Python hl_lines="1 13"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
**🔑 👨💼** 🐍 🕳 👈 👆 💪 ⚙️ `with` 📄, 🖼, `open()` 💪 ⚙️ 🔑 👨💼:
@@ -89,7 +89,7 @@ async with lifespan(app):
`lifespan` 🔢 `FastAPI` 📱 ✊ **🔁 🔑 👨💼**, 👥 💪 🚶♀️ 👆 🆕 `lifespan` 🔁 🔑 👨💼 ⚫️.
```Python hl_lines="22"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
## 🎛 🎉 (😢)
@@ -113,7 +113,7 @@ async with lifespan(app):
🚮 🔢 👈 🔜 🏃 ⏭ 🈸 ▶️, 📣 ⚫️ ⏮️ 🎉 `"startup"`:
```Python hl_lines="8"
-{!../../../docs_src/events/tutorial001.py!}
+{!../../docs_src/events/tutorial001.py!}
```
👉 💼, `startup` 🎉 🐕🦺 🔢 🔜 🔢 🏬 "💽" ( `dict`) ⏮️ 💲.
@@ -127,7 +127,7 @@ async with lifespan(app):
🚮 🔢 👈 🔜 🏃 🕐❔ 🈸 🤫 🔽, 📣 ⚫️ ⏮️ 🎉 `"shutdown"`:
```Python hl_lines="6"
-{!../../../docs_src/events/tutorial002.py!}
+{!../../docs_src/events/tutorial002.py!}
```
📥, `shutdown` 🎉 🐕🦺 🔢 🔜 ✍ ✍ ⏸ `"Application shutdown"` 📁 `log.txt`.
diff --git a/docs/em/docs/advanced/generate-clients.md b/docs/em/docs/advanced/generate-clients.md
index c8e044340..f09d75623 100644
--- a/docs/em/docs/advanced/generate-clients.md
+++ b/docs/em/docs/advanced/generate-clients.md
@@ -19,7 +19,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9-11 14-15 18 19 23"
-{!> ../../../docs_src/generate_clients/tutorial001.py!}
+{!> ../../docs_src/generate_clients/tutorial001.py!}
```
////
@@ -27,7 +27,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="7-9 12-13 16-17 21"
-{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial001_py39.py!}
```
////
@@ -139,7 +139,7 @@ frontend-app@1.0.0 generate-client /home/user/code/frontend-app
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="23 28 36"
-{!> ../../../docs_src/generate_clients/tutorial002.py!}
+{!> ../../docs_src/generate_clients/tutorial002.py!}
```
////
@@ -147,7 +147,7 @@ frontend-app@1.0.0 generate-client /home/user/code/frontend-app
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="21 26 34"
-{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial002_py39.py!}
```
////
@@ -200,7 +200,7 @@ FastAPI ⚙️ **😍 🆔** 🔠 *➡ 🛠️*, ⚫️ ⚙️ **🛠️ 🆔**
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="8-9 12"
-{!> ../../../docs_src/generate_clients/tutorial003.py!}
+{!> ../../docs_src/generate_clients/tutorial003.py!}
```
////
@@ -208,7 +208,7 @@ FastAPI ⚙️ **😍 🆔** 🔠 *➡ 🛠️*, ⚫️ ⚙️ **🛠️ 🆔**
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="6-7 10"
-{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial003_py39.py!}
```
////
@@ -234,7 +234,7 @@ FastAPI ⚙️ **😍 🆔** 🔠 *➡ 🛠️*, ⚫️ ⚙️ **🛠️ 🆔**
👥 💪 ⏬ 🗄 🎻 📁 `openapi.json` & ⤴️ 👥 💪 **❎ 👈 🔡 🔖** ⏮️ ✍ 💖 👉:
```Python
-{!../../../docs_src/generate_clients/tutorial004.py!}
+{!../../docs_src/generate_clients/tutorial004.py!}
```
⏮️ 👈, 🛠️ 🆔 🔜 📁 ⚪️➡️ 👜 💖 `items-get_items` `get_items`, 👈 🌌 👩💻 🚂 💪 🏗 🙅 👩🔬 📛.
diff --git a/docs/em/docs/advanced/middleware.md b/docs/em/docs/advanced/middleware.md
index e3cc389c6..914ce4a30 100644
--- a/docs/em/docs/advanced/middleware.md
+++ b/docs/em/docs/advanced/middleware.md
@@ -43,7 +43,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
**FastAPI** 🔌 📚 🛠️ ⚠ ⚙️ 💼, 👥 🔜 👀 ⏭ ❔ ⚙️ 👫.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
⏭ 🖼, 👆 💪 ⚙️ `from starlette.middleware.something import SomethingMiddleware`.
@@ -58,7 +58,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
🙆 📨 📨 `http` ⚖️ `ws` 🔜 ❎ 🔐 ⚖ ↩️.
```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial001.py!}
+{!../../docs_src/advanced_middleware/tutorial001.py!}
```
## `TrustedHostMiddleware`
@@ -66,7 +66,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
🛠️ 👈 🌐 📨 📨 ✔️ ☑ ⚒ `Host` 🎚, ✔ 💂♂ 🛡 🇺🇸🔍 🦠 🎚 👊.
```Python hl_lines="2 6-8"
-{!../../../docs_src/advanced_middleware/tutorial002.py!}
+{!../../docs_src/advanced_middleware/tutorial002.py!}
```
📄 ❌ 🐕🦺:
@@ -82,7 +82,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
🛠️ 🔜 🍵 👯♂️ 🐩 & 🎥 📨.
```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial003.py!}
+{!../../docs_src/advanced_middleware/tutorial003.py!}
```
📄 ❌ 🐕🦺:
diff --git a/docs/em/docs/advanced/openapi-callbacks.md b/docs/em/docs/advanced/openapi-callbacks.md
index 00d54ebec..f7b5e7ed9 100644
--- a/docs/em/docs/advanced/openapi-callbacks.md
+++ b/docs/em/docs/advanced/openapi-callbacks.md
@@ -32,7 +32,7 @@
👉 🍕 📶 😐, 🌅 📟 🎲 ⏪ 😰 👆:
```Python hl_lines="9-13 36-53"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
/// tip
@@ -93,7 +93,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
🥇 ✍ 🆕 `APIRouter` 👈 🔜 🔌 1️⃣ ⚖️ 🌅 ⏲.
```Python hl_lines="3 25"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
### ✍ ⏲ *➡ 🛠️*
@@ -106,7 +106,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
* & ⚫️ 💪 ✔️ 📄 📨 ⚫️ 🔜 📨, ✅ `response_model=InvoiceEventReceived`.
```Python hl_lines="16-18 21-22 28-32"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
📤 2️⃣ 👑 🔺 ⚪️➡️ 😐 *➡ 🛠️*:
@@ -176,7 +176,7 @@ https://www.external.org/events/invoices/2expen51ve
🔜 ⚙️ 🔢 `callbacks` *👆 🛠️ ➡ 🛠️ 👨🎨* 🚶♀️ 🔢 `.routes` (👈 🤙 `list` 🛣/*➡ 🛠️*) ⚪️➡️ 👈 ⏲ 📻:
```Python hl_lines="35"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
/// tip
diff --git a/docs/em/docs/advanced/path-operation-advanced-configuration.md b/docs/em/docs/advanced/path-operation-advanced-configuration.md
index b684df26f..47e89a90f 100644
--- a/docs/em/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/em/docs/advanced/path-operation-advanced-configuration.md
@@ -13,7 +13,7 @@
👆 🔜 ✔️ ⚒ 💭 👈 ⚫️ 😍 🔠 🛠️.
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### ⚙️ *➡ 🛠️ 🔢* 📛 {
@@ -23,7 +23,7 @@
👆 🔜 ⚫️ ⏮️ ❎ 🌐 👆 *➡ 🛠️*.
```Python hl_lines="2 12-21 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
/// tip
@@ -45,7 +45,7 @@
🚫 *➡ 🛠️* ⚪️➡️ 🏗 🗄 🔗 (& ➡️, ⚪️➡️ 🏧 🧾 ⚙️), ⚙️ 🔢 `include_in_schema` & ⚒ ⚫️ `False`:
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## 🏧 📛 ⚪️➡️ #️⃣
@@ -57,7 +57,7 @@
⚫️ 🏆 🚫 🎦 🆙 🧾, ✋️ 🎏 🧰 (✅ 🐉) 🔜 💪 ⚙️ 🎂.
```Python hl_lines="19-29"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```
## 🌖 📨
@@ -74,7 +74,7 @@
🕐❔ 👆 📣 *➡ 🛠️* 👆 🈸, **FastAPI** 🔁 🏗 🔗 🗃 🔃 👈 *➡ 🛠️* 🔌 🗄 🔗.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
🗄 🔧 ⚫️ 🤙 🛠️ 🎚.
@@ -101,7 +101,7 @@
👉 `openapi_extra` 💪 👍, 🖼, 📣 [🗄 ↔](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
```
🚥 👆 📂 🏧 🛠️ 🩺, 👆 ↔ 🔜 🎦 🆙 🔝 🎯 *➡ 🛠️*.
@@ -150,7 +150,7 @@
👆 💪 👈 ⏮️ `openapi_extra`:
```Python hl_lines="20-37 39-40"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
```
👉 🖼, 👥 🚫 📣 🙆 Pydantic 🏷. 👐, 📨 💪 🚫 🎻 🎻, ⚫️ ✍ 🔗 `bytes`, & 🔢 `magic_data_reader()` 🔜 🈚 🎻 ⚫️ 🌌.
@@ -166,7 +166,7 @@
🖼, 👉 🈸 👥 🚫 ⚙️ FastAPI 🛠️ 🛠️ ⚗ 🎻 🔗 ⚪️➡️ Pydantic 🏷 🚫 🏧 🔬 🎻. 👐, 👥 📣 📨 🎚 🆎 📁, 🚫 🎻:
```Python hl_lines="17-22 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
👐, 👐 👥 🚫 ⚙️ 🔢 🛠️ 🛠️, 👥 ⚙️ Pydantic 🏷 ❎ 🏗 🎻 🔗 💽 👈 👥 💚 📨 📁.
@@ -176,7 +176,7 @@
& ⤴️ 👆 📟, 👥 🎻 👈 📁 🎚 🔗, & ⤴️ 👥 🔄 ⚙️ 🎏 Pydantic 🏷 ✔ 📁 🎚:
```Python hl_lines="26-33"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
/// tip
diff --git a/docs/em/docs/advanced/response-change-status-code.md b/docs/em/docs/advanced/response-change-status-code.md
index 156efcc16..7f2e8c157 100644
--- a/docs/em/docs/advanced/response-change-status-code.md
+++ b/docs/em/docs/advanced/response-change-status-code.md
@@ -21,7 +21,7 @@
& ⤴️ 👆 💪 ⚒ `status_code` 👈 *🔀* 📨 🎚.
```Python hl_lines="1 9 12"
-{!../../../docs_src/response_change_status_code/tutorial001.py!}
+{!../../docs_src/response_change_status_code/tutorial001.py!}
```
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️).
diff --git a/docs/em/docs/advanced/response-cookies.md b/docs/em/docs/advanced/response-cookies.md
index 717fb87ce..0fe47baec 100644
--- a/docs/em/docs/advanced/response-cookies.md
+++ b/docs/em/docs/advanced/response-cookies.md
@@ -7,7 +7,7 @@
& ⤴️ 👆 💪 ⚒ 🍪 👈 *🔀* 📨 🎚.
```Python hl_lines="1 8-9"
-{!../../../docs_src/response_cookies/tutorial002.py!}
+{!../../docs_src/response_cookies/tutorial002.py!}
```
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️).
@@ -27,7 +27,7 @@
⤴️ ⚒ 🍪 ⚫️, & ⤴️ 📨 ⚫️:
```Python hl_lines="10-12"
-{!../../../docs_src/response_cookies/tutorial001.py!}
+{!../../docs_src/response_cookies/tutorial001.py!}
```
/// tip
@@ -42,7 +42,7 @@
### 🌅 ℹ
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import Response` ⚖️ `from starlette.responses import JSONResponse`.
diff --git a/docs/em/docs/advanced/response-directly.md b/docs/em/docs/advanced/response-directly.md
index 13ee081c2..335c381c7 100644
--- a/docs/em/docs/advanced/response-directly.md
+++ b/docs/em/docs/advanced/response-directly.md
@@ -35,10 +35,10 @@
📚 💼, 👆 💪 ⚙️ `jsonable_encoder` 🗜 👆 📊 ⏭ 🚶♀️ ⚫️ 📨:
```Python hl_lines="6-7 21-22"
-{!../../../docs_src/response_directly/tutorial001.py!}
+{!../../docs_src/response_directly/tutorial001.py!}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import JSONResponse`.
@@ -57,7 +57,7 @@
👆 💪 🚮 👆 📂 🎚 🎻, 🚮 ⚫️ `Response`, & 📨 ⚫️:
```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
+{!../../docs_src/response_directly/tutorial002.py!}
```
## 🗒
diff --git a/docs/em/docs/advanced/response-headers.md b/docs/em/docs/advanced/response-headers.md
index 27e1cdbd5..d577347fe 100644
--- a/docs/em/docs/advanced/response-headers.md
+++ b/docs/em/docs/advanced/response-headers.md
@@ -7,7 +7,7 @@
& ⤴️ 👆 💪 ⚒ 🎚 👈 *🔀* 📨 🎚.
```Python hl_lines="1 7-8"
-{!../../../docs_src/response_headers/tutorial002.py!}
+{!../../docs_src/response_headers/tutorial002.py!}
```
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️).
@@ -25,10 +25,10 @@
✍ 📨 🔬 [📨 📨 🔗](response-directly.md){.internal-link target=_blank} & 🚶♀️ 🎚 🌖 🔢:
```Python hl_lines="10-12"
-{!../../../docs_src/response_headers/tutorial001.py!}
+{!../../docs_src/response_headers/tutorial001.py!}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import Response` ⚖️ `from starlette.responses import JSONResponse`.
diff --git a/docs/em/docs/advanced/security/http-basic-auth.md b/docs/em/docs/advanced/security/http-basic-auth.md
index 33470a726..e6fe3e32c 100644
--- a/docs/em/docs/advanced/security/http-basic-auth.md
+++ b/docs/em/docs/advanced/security/http-basic-auth.md
@@ -21,7 +21,7 @@
* ⚫️ 🔌 `username` & `password` 📨.
```Python hl_lines="2 6 10"
-{!../../../docs_src/security/tutorial006.py!}
+{!../../docs_src/security/tutorial006.py!}
```
🕐❔ 👆 🔄 📂 📛 🥇 🕰 (⚖️ 🖊 "🛠️" 🔼 🩺) 🖥 🔜 💭 👆 👆 🆔 & 🔐:
@@ -43,7 +43,7 @@
⤴️ 👥 💪 ⚙️ `secrets.compare_digest()` 🚚 👈 `credentials.username` `"stanleyjobson"`, & 👈 `credentials.password` `"swordfish"`.
```Python hl_lines="1 11-21"
-{!../../../docs_src/security/tutorial007.py!}
+{!../../docs_src/security/tutorial007.py!}
```
👉 🔜 🎏:
@@ -109,5 +109,5 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
⏮️ 🔍 👈 🎓 ❌, 📨 `HTTPException` ⏮️ 👔 📟 4️⃣0️⃣1️⃣ (🎏 📨 🕐❔ 🙅♂ 🎓 🚚) & 🚮 🎚 `WWW-Authenticate` ⚒ 🖥 🎦 💳 📋 🔄:
```Python hl_lines="23-27"
-{!../../../docs_src/security/tutorial007.py!}
+{!../../docs_src/security/tutorial007.py!}
```
diff --git a/docs/em/docs/advanced/security/oauth2-scopes.md b/docs/em/docs/advanced/security/oauth2-scopes.md
index 73b2ec540..f4d1a3b82 100644
--- a/docs/em/docs/advanced/security/oauth2-scopes.md
+++ b/docs/em/docs/advanced/security/oauth2-scopes.md
@@ -63,7 +63,7 @@ Oauth2️⃣ 👫 🎻.
🥇, ➡️ 🔜 👀 🍕 👈 🔀 ⚪️➡️ 🖼 👑 **🔰 - 👩💻 🦮** [Oauth2️⃣ ⏮️ 🔐 (& 🔁), 📨 ⏮️ 🥙 🤝](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. 🔜 ⚙️ Oauth2️⃣ ↔:
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
🔜 ➡️ 📄 👈 🔀 🔁 🔁.
@@ -75,7 +75,7 @@ Oauth2️⃣ 👫 🎻.
`scopes` 🔢 📨 `dict` ⏮️ 🔠 ↔ 🔑 & 📛 💲:
```Python hl_lines="62-65"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
↩️ 👥 🔜 📣 📚 ↔, 👫 🔜 🎦 🆙 🛠️ 🩺 🕐❔ 👆 🕹-/✔.
@@ -103,7 +103,7 @@ Oauth2️⃣ 👫 🎻.
///
```Python hl_lines="155"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 📣 ↔ *➡ 🛠️* & 🔗
@@ -131,10 +131,10 @@ Oauth2️⃣ 👫 🎻.
///
```Python hl_lines="4 139 168"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
-/// info | "📡 ℹ"
+/// info | 📡 ℹ
`Security` 🤙 🏿 `Depends`, & ⚫️ ✔️ 1️⃣ ➕ 🔢 👈 👥 🔜 👀 ⏪.
@@ -159,7 +159,7 @@ Oauth2️⃣ 👫 🎻.
👉 `SecurityScopes` 🎓 🎏 `Request` (`Request` ⚙️ 🤚 📨 🎚 🔗).
```Python hl_lines="8 105"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## ⚙️ `scopes`
@@ -175,7 +175,7 @@ Oauth2️⃣ 👫 🎻.
👉 ⚠, 👥 🔌 ↔ 🚚 (🚥 🙆) 🎻 👽 🚀 (⚙️ `scope_str`). 👥 🚮 👈 🎻 ⚗ ↔ `WWW-Authenticate` 🎚 (👉 🍕 🔌).
```Python hl_lines="105 107-115"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## ✔ `username` & 💽 💠
@@ -193,7 +193,7 @@ Oauth2️⃣ 👫 🎻.
👥 ✔ 👈 👥 ✔️ 👩💻 ⏮️ 👈 🆔, & 🚥 🚫, 👥 🤚 👈 🎏 ⚠ 👥 ✍ ⏭.
```Python hl_lines="46 116-127"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## ✔ `scopes`
@@ -203,7 +203,7 @@ Oauth2️⃣ 👫 🎻.
👉, 👥 ⚙️ `security_scopes.scopes`, 👈 🔌 `list` ⏮️ 🌐 👫 ↔ `str`.
```Python hl_lines="128-134"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 🔗 🌲 & ↔
diff --git a/docs/em/docs/advanced/settings.md b/docs/em/docs/advanced/settings.md
index e84941b57..59fb71d73 100644
--- a/docs/em/docs/advanced/settings.md
+++ b/docs/em/docs/advanced/settings.md
@@ -149,7 +149,7 @@ Hello World from Python
👆 💪 ⚙️ 🌐 🎏 🔬 ⚒ & 🧰 👆 ⚙️ Pydantic 🏷, 💖 🎏 📊 🆎 & 🌖 🔬 ⏮️ `Field()`.
```Python hl_lines="2 5-8 11"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
/// tip
@@ -167,7 +167,7 @@ Hello World from Python
⤴️ 👆 💪 ⚙️ 🆕 `settings` 🎚 👆 🈸:
```Python hl_lines="18-20"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
### 🏃 💽
@@ -203,13 +203,13 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
🖼, 👆 💪 ✔️ 📁 `config.py` ⏮️:
```Python
-{!../../../docs_src/settings/app01/config.py!}
+{!../../docs_src/settings/app01/config.py!}
```
& ⤴️ ⚙️ ⚫️ 📁 `main.py`:
```Python hl_lines="3 11-13"
-{!../../../docs_src/settings/app01/main.py!}
+{!../../docs_src/settings/app01/main.py!}
```
/// tip
@@ -229,7 +229,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
👟 ⚪️➡️ ⏮️ 🖼, 👆 `config.py` 📁 💪 👀 💖:
```Python hl_lines="10"
-{!../../../docs_src/settings/app02/config.py!}
+{!../../docs_src/settings/app02/config.py!}
```
👀 👈 🔜 👥 🚫 ✍ 🔢 👐 `settings = Settings()`.
@@ -239,7 +239,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
🔜 👥 ✍ 🔗 👈 📨 🆕 `config.Settings()`.
```Python hl_lines="5 11-12"
-{!../../../docs_src/settings/app02/main.py!}
+{!../../docs_src/settings/app02/main.py!}
```
/// tip
@@ -253,7 +253,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
& ⤴️ 👥 💪 🚚 ⚫️ ⚪️➡️ *➡ 🛠️ 🔢* 🔗 & ⚙️ ⚫️ 🙆 👥 💪 ⚫️.
```Python hl_lines="16 18-20"
-{!../../../docs_src/settings/app02/main.py!}
+{!../../docs_src/settings/app02/main.py!}
```
### ⚒ & 🔬
@@ -261,7 +261,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
⤴️ ⚫️ 🔜 📶 ⏩ 🚚 🎏 ⚒ 🎚 ⏮️ 🔬 🏗 🔗 🔐 `get_settings`:
```Python hl_lines="9-10 13 21"
-{!../../../docs_src/settings/app02/test_main.py!}
+{!../../docs_src/settings/app02/test_main.py!}
```
🔗 🔐 👥 ⚒ 🆕 💲 `admin_email` 🕐❔ 🏗 🆕 `Settings` 🎚, & ⤴️ 👥 📨 👈 🆕 🎚.
@@ -304,7 +304,7 @@ APP_NAME="ChimichangApp"
& ⤴️ ℹ 👆 `config.py` ⏮️:
```Python hl_lines="9-10"
-{!../../../docs_src/settings/app03/config.py!}
+{!../../docs_src/settings/app03/config.py!}
```
📥 👥 ✍ 🎓 `Config` 🔘 👆 Pydantic `Settings` 🎓, & ⚒ `env_file` 📁 ⏮️ 🇨🇻 📁 👥 💚 ⚙️.
@@ -339,7 +339,7 @@ def get_settings():
✋️ 👥 ⚙️ `@lru_cache` 👨🎨 🔛 🔝, `Settings` 🎚 🔜 ✍ 🕴 🕐, 🥇 🕰 ⚫️ 🤙. 👶 👶
```Python hl_lines="1 10"
-{!../../../docs_src/settings/app03/main.py!}
+{!../../docs_src/settings/app03/main.py!}
```
⤴️ 🙆 🏁 🤙 `get_settings()` 🔗 ⏭ 📨, ↩️ 🛠️ 🔗 📟 `get_settings()` & 🏗 🆕 `Settings` 🎚, ⚫️ 🔜 📨 🎏 🎚 👈 📨 🔛 🥇 🤙, 🔄 & 🔄.
diff --git a/docs/em/docs/advanced/sub-applications.md b/docs/em/docs/advanced/sub-applications.md
index 1e0931f95..e19f3f234 100644
--- a/docs/em/docs/advanced/sub-applications.md
+++ b/docs/em/docs/advanced/sub-applications.md
@@ -11,7 +11,7 @@
🥇, ✍ 👑, 🔝-🎚, **FastAPI** 🈸, & 🚮 *➡ 🛠️*:
```Python hl_lines="3 6-8"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### 🎧-🈸
@@ -21,7 +21,7 @@
👉 🎧-🈸 ➕1️⃣ 🐩 FastAPI 🈸, ✋️ 👉 1️⃣ 👈 🔜 "🗻":
```Python hl_lines="11 14-16"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### 🗻 🎧-🈸
@@ -31,7 +31,7 @@
👉 💼, ⚫️ 🔜 📌 ➡ `/subapi`:
```Python hl_lines="11 19"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### ✅ 🏧 🛠️ 🩺
diff --git a/docs/em/docs/advanced/templates.md b/docs/em/docs/advanced/templates.md
index c45ff47a1..53428151d 100644
--- a/docs/em/docs/advanced/templates.md
+++ b/docs/em/docs/advanced/templates.md
@@ -28,7 +28,7 @@ $ pip install jinja2
* ⚙️ `templates` 👆 ✍ ✍ & 📨 `TemplateResponse`, 🚶♀️ `request` 1️⃣ 🔑-💲 👫 Jinja2️⃣ "🔑".
```Python hl_lines="4 11 15-18"
-{!../../../docs_src/templates/tutorial001.py!}
+{!../../docs_src/templates/tutorial001.py!}
```
/// note
@@ -43,7 +43,7 @@ $ pip install jinja2
///
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.templating import Jinja2Templates`.
@@ -56,7 +56,7 @@ $ pip install jinja2
⤴️ 👆 💪 ✍ 📄 `templates/item.html` ⏮️:
```jinja hl_lines="7"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
⚫️ 🔜 🎦 `id` ✊ ⚪️➡️ "🔑" `dict` 👆 🚶♀️:
@@ -70,13 +70,13 @@ $ pip install jinja2
& 👆 💪 ⚙️ `url_for()` 🔘 📄, & ⚙️ ⚫️, 🖼, ⏮️ `StaticFiles` 👆 📌.
```jinja hl_lines="4"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
👉 🖼, ⚫️ 🔜 🔗 🎚 📁 `static/styles.css` ⏮️:
```CSS hl_lines="4"
-{!../../../docs_src/templates/static/styles.css!}
+{!../../docs_src/templates/static/styles.css!}
```
& ↩️ 👆 ⚙️ `StaticFiles`, 👈 🎚 📁 🔜 🍦 🔁 👆 **FastAPI** 🈸 📛 `/static/styles.css`.
diff --git a/docs/em/docs/advanced/testing-database.md b/docs/em/docs/advanced/testing-database.md
deleted file mode 100644
index 825d545a9..000000000
--- a/docs/em/docs/advanced/testing-database.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# 🔬 💽
-
-👆 💪 ⚙️ 🎏 🔗 🔐 ⚪️➡️ [🔬 🔗 ⏮️ 🔐](testing-dependencies.md){.internal-link target=_blank} 📉 💽 🔬.
-
-👆 💪 💚 ⚒ 🆙 🎏 💽 🔬, 💾 💽 ⏮️ 💯, 🏤-🥧 ⚫️ ⏮️ 🔬 💽, ♒️.
-
-👑 💭 ⚫️❔ 🎏 👆 👀 👈 ⏮️ 📃.
-
-## 🚮 💯 🗄 📱
-
-➡️ ℹ 🖼 ⚪️➡️ [🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank} ⚙️ 🔬 💽.
-
-🌐 📱 📟 🎏, 👆 💪 🚶 🔙 👈 📃 ✅ ❔ ⚫️.
-
-🕴 🔀 📥 🆕 🔬 📁.
-
-👆 😐 🔗 `get_db()` 🔜 📨 💽 🎉.
-
-💯, 👆 💪 ⚙️ 🔗 🔐 📨 👆 *🛃* 💽 🎉 ↩️ 1️⃣ 👈 🔜 ⚙️ 🛎.
-
-👉 🖼 👥 🔜 ✍ 🍕 💽 🕴 💯.
-
-## 📁 📊
-
-👥 ✍ 🆕 📁 `sql_app/tests/test_sql_app.py`.
-
-🆕 📁 📊 👀 💖:
-
-``` hl_lines="9-11"
-.
-└── sql_app
- ├── __init__.py
- ├── crud.py
- ├── database.py
- ├── main.py
- ├── models.py
- ├── schemas.py
- └── tests
- ├── __init__.py
- └── test_sql_app.py
-```
-
-## ✍ 🆕 💽 🎉
-
-🥇, 👥 ✍ 🆕 💽 🎉 ⏮️ 🆕 💽.
-
-💯 👥 🔜 ⚙️ 📁 `test.db` ↩️ `sql_app.db`.
-
-✋️ 🎂 🎉 📟 🌅 ⚖️ 🌘 🎏, 👥 📁 ⚫️.
-
-```Python hl_lines="8-13"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-/// tip
-
-👆 💪 📉 ❎ 👈 📟 🚮 ⚫️ 🔢 & ⚙️ ⚫️ ⚪️➡️ 👯♂️ `database.py` & `tests/test_sql_app.py`.
-
-🦁 & 🎯 🔛 🎯 🔬 📟, 👥 🖨 ⚫️.
-
-///
-
-## ✍ 💽
-
-↩️ 🔜 👥 🔜 ⚙️ 🆕 💽 🆕 📁, 👥 💪 ⚒ 💭 👥 ✍ 💽 ⏮️:
-
-```Python
-Base.metadata.create_all(bind=engine)
-```
-
-👈 🛎 🤙 `main.py`, ✋️ ⏸ `main.py` ⚙️ 💽 📁 `sql_app.db`, & 👥 💪 ⚒ 💭 👥 ✍ `test.db` 💯.
-
-👥 🚮 👈 ⏸ 📥, ⏮️ 🆕 📁.
-
-```Python hl_lines="16"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-## 🔗 🔐
-
-🔜 👥 ✍ 🔗 🔐 & 🚮 ⚫️ 🔐 👆 📱.
-
-```Python hl_lines="19-24 27"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-/// tip
-
-📟 `override_get_db()` 🌖 ⚫️❔ 🎏 `get_db()`, ✋️ `override_get_db()` 👥 ⚙️ `TestingSessionLocal` 🔬 💽 ↩️.
-
-///
-
-## 💯 📱
-
-⤴️ 👥 💪 💯 📱 🛎.
-
-```Python hl_lines="32-47"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-& 🌐 🛠️ 👥 ⚒ 💽 ⏮️ 💯 🔜 `test.db` 💽 ↩️ 👑 `sql_app.db`.
diff --git a/docs/em/docs/advanced/testing-dependencies.md b/docs/em/docs/advanced/testing-dependencies.md
index 8bcffcc29..027767df1 100644
--- a/docs/em/docs/advanced/testing-dependencies.md
+++ b/docs/em/docs/advanced/testing-dependencies.md
@@ -29,7 +29,7 @@
& ⤴️ **FastAPI** 🔜 🤙 👈 🔐 ↩️ ⏮️ 🔗.
```Python hl_lines="28-29 32"
-{!../../../docs_src/dependency_testing/tutorial001.py!}
+{!../../docs_src/dependency_testing/tutorial001.py!}
```
/// tip
diff --git a/docs/em/docs/advanced/testing-events.md b/docs/em/docs/advanced/testing-events.md
index d64436eb9..071d49c21 100644
--- a/docs/em/docs/advanced/testing-events.md
+++ b/docs/em/docs/advanced/testing-events.md
@@ -3,5 +3,5 @@
🕐❔ 👆 💪 👆 🎉 🐕🦺 (`startup` & `shutdown`) 🏃 👆 💯, 👆 💪 ⚙️ `TestClient` ⏮️ `with` 📄:
```Python hl_lines="9-12 20-24"
-{!../../../docs_src/app_testing/tutorial003.py!}
+{!../../docs_src/app_testing/tutorial003.py!}
```
diff --git a/docs/em/docs/advanced/testing-websockets.md b/docs/em/docs/advanced/testing-websockets.md
index 5fb1e9c34..62939c343 100644
--- a/docs/em/docs/advanced/testing-websockets.md
+++ b/docs/em/docs/advanced/testing-websockets.md
@@ -5,7 +5,7 @@
👉, 👆 ⚙️ `TestClient` `with` 📄, 🔗*️⃣:
```Python hl_lines="27-31"
-{!../../../docs_src/app_testing/tutorial002.py!}
+{!../../docs_src/app_testing/tutorial002.py!}
```
/// note
diff --git a/docs/em/docs/advanced/using-request-directly.md b/docs/em/docs/advanced/using-request-directly.md
index edc951d96..3eb0067ad 100644
--- a/docs/em/docs/advanced/using-request-directly.md
+++ b/docs/em/docs/advanced/using-request-directly.md
@@ -30,7 +30,7 @@
👈 👆 💪 🔐 📨 🔗.
```Python hl_lines="1 7-8"
-{!../../../docs_src/using_request_directly/tutorial001.py!}
+{!../../docs_src/using_request_directly/tutorial001.py!}
```
📣 *➡ 🛠️ 🔢* 🔢 ⏮️ 🆎 ➖ `Request` **FastAPI** 🔜 💭 🚶♀️ `Request` 👈 🔢.
@@ -49,7 +49,7 @@
👆 💪 ✍ 🌅 ℹ 🔃 `Request` 🎚 🛂 💃 🧾 🕸.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.requests import Request`.
diff --git a/docs/em/docs/advanced/websockets.md b/docs/em/docs/advanced/websockets.md
index 30dc3043e..4b260e20a 100644
--- a/docs/em/docs/advanced/websockets.md
+++ b/docs/em/docs/advanced/websockets.md
@@ -39,7 +39,7 @@ $ pip install websockets
✋️ ⚫️ 🙅 🌌 🎯 🔛 💽-🚄 *️⃣ & ✔️ 👷 🖼:
```Python hl_lines="2 6-38 41-43"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
## ✍ `websocket`
@@ -47,10 +47,10 @@ $ pip install websockets
👆 **FastAPI** 🈸, ✍ `websocket`:
```Python hl_lines="1 46-47"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.websockets import WebSocket`.
@@ -63,7 +63,7 @@ $ pip install websockets
👆 *️⃣ 🛣 👆 💪 `await` 📧 & 📨 📧.
```Python hl_lines="48-52"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
👆 💪 📨 & 📨 💱, ✍, & 🎻 💽.
@@ -116,7 +116,7 @@ $ uvicorn main:app --reload
👫 👷 🎏 🌌 🎏 FastAPI 🔗/*➡ 🛠️*:
```Python hl_lines="66-77 76-91"
-{!../../../docs_src/websockets/tutorial002.py!}
+{!../../docs_src/websockets/tutorial002.py!}
```
/// info
@@ -163,7 +163,7 @@ $ uvicorn main:app --reload
🕐❔ *️⃣ 🔗 📪, `await websocket.receive_text()` 🔜 🤚 `WebSocketDisconnect` ⚠, ❔ 👆 💪 ⤴️ ✊ & 🍵 💖 👉 🖼.
```Python hl_lines="81-83"
-{!../../../docs_src/websockets/tutorial003.py!}
+{!../../docs_src/websockets/tutorial003.py!}
```
🔄 ⚫️ 👅:
diff --git a/docs/em/docs/advanced/wsgi.md b/docs/em/docs/advanced/wsgi.md
index 6a4ed073c..8c0008c74 100644
--- a/docs/em/docs/advanced/wsgi.md
+++ b/docs/em/docs/advanced/wsgi.md
@@ -13,7 +13,7 @@
& ⤴️ 🗻 👈 🔽 ➡.
```Python hl_lines="2-3 22"
-{!../../../docs_src/wsgi/tutorial001.py!}
+{!../../docs_src/wsgi/tutorial001.py!}
```
## ✅ ⚫️
diff --git a/docs/em/docs/alternatives.md b/docs/em/docs/alternatives.md
index 334c0de73..59b587285 100644
--- a/docs/em/docs/alternatives.md
+++ b/docs/em/docs/alternatives.md
@@ -36,7 +36,7 @@
///
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
✔️ 🏧 🛠️ 🧾 🕸 👩💻 🔢.
@@ -56,7 +56,7 @@
👐 🦁 🏺, ⚫️ 😑 💖 👍 🏏 🏗 🔗. ⏭ 👜 🔎 "✳ 🎂 🛠️" 🏺.
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
◾-🛠️. ⚒ ⚫️ ⏩ 🌀 & 🏏 🧰 & 🍕 💪.
@@ -98,7 +98,7 @@ def read_url():
👀 🔀 `requests.get(...)` & `@app.get(...)`.
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
* ✔️ 🙅 & 🏋️ 🛠️.
* ⚙️ 🇺🇸🔍 👩🔬 📛 (🛠️) 🔗, 🎯 & 🏋️ 🌌.
@@ -118,7 +118,7 @@ def read_url():
👈 ⚫️❔ 🕐❔ 💬 🔃 ⏬ 2️⃣.0️⃣ ⚫️ ⚠ 💬 "🦁", & ⏬ 3️⃣ ➕ "🗄".
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🛠️ & ⚙️ 📂 🐩 🛠️ 🔧, ↩️ 🛃 🔗.
@@ -147,7 +147,7 @@ def read_url():
✋️ ⚫️ ✍ ⏭ 📤 🔀 🐍 🆎 🔑. , 🔬 🔠 🔗 👆 💪 ⚙️ 🎯 🇨🇻 & 🎓 🚚 🍭.
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
⚙️ 📟 🔬 "🔗" 👈 🚚 💽 🆎 & 🔬, 🔁.
@@ -169,7 +169,7 @@ Webarg ✍ 🎏 🍭 👩💻.
///
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
✔️ 🏧 🔬 📨 📨 💽.
@@ -199,7 +199,7 @@ APISpec ✍ 🎏 🍭 👩💻.
///
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🐕🦺 📂 🐩 🛠️, 🗄.
@@ -231,7 +231,7 @@ APISpec ✍ 🎏 🍭 👩💻.
///
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🏗 🗄 🔗 🔁, ⚪️➡️ 🎏 📟 👈 🔬 🛠️ & 🔬.
@@ -251,7 +251,7 @@ APISpec ✍ 🎏 🍭 👩💻.
⚫️ 💪 🚫 🍵 🔁 🏷 📶 👍. , 🚥 🎻 💪 📨 🎻 🎚 👈 ✔️ 🔘 🏑 👈 🔄 🐦 🎻 🎚, ⚫️ 🚫🔜 ☑ 📄 & ✔.
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
⚙️ 🐍 🆎 ✔️ 👑 👨🎨 🐕🦺.
@@ -263,7 +263,7 @@ APISpec ✍ 🎏 🍭 👩💻.
⚫️ 🕐 🥇 📶 ⏩ 🐍 🛠️ ⚓️ 🔛 `asyncio`. ⚫️ ⚒ 📶 🎏 🏺.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
⚫️ ⚙️ `uvloop` ↩️ 🔢 🐍 `asyncio` ➰. 👈 ⚫️❔ ⚒ ⚫️ ⏩.
@@ -271,7 +271,7 @@ APISpec ✍ 🎏 🍭 👩💻.
///
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🔎 🌌 ✔️ 😜 🎭.
@@ -287,7 +287,7 @@ APISpec ✍ 🎏 🍭 👩💻.
, 💽 🔬, 🛠️, & 🧾, ✔️ ⌛ 📟, 🚫 🔁. ⚖️ 👫 ✔️ 🛠️ 🛠️ 🔛 🔝 🦅, 💖 🤗. 👉 🎏 🔺 🔨 🎏 🛠️ 👈 😮 🦅 🔧, ✔️ 1️⃣ 📨 🎚 & 1️⃣ 📨 🎚 🔢.
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🔎 🌌 🤚 👑 🎭.
@@ -313,7 +313,7 @@ APISpec ✍ 🎏 🍭 👩💻.
🛣 📣 👁 🥉, ⚙️ 🔢 📣 🎏 🥉 (↩️ ⚙️ 👨🎨 👈 💪 🥉 ▶️️ 🔛 🔝 🔢 👈 🍵 🔗). 👉 🔐 ❔ ✳ 🔨 ⚫️ 🌘 ❔ 🏺 (& 💃) 🔨 ⚫️. ⚫️ 🎏 📟 👜 👈 📶 😆 🔗.
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🔬 ➕ 🔬 💽 🆎 ⚙️ "🔢" 💲 🏷 🔢. 👉 📉 👨🎨 🐕🦺, & ⚫️ 🚫 💪 Pydantic ⏭.
@@ -321,7 +321,7 @@ APISpec ✍ 🎏 🍭 👩💻.
///
-### 🤗
+### 🤗
🤗 🕐 🥇 🛠️ 🛠️ 📄 🛠️ 🔢 🆎 ⚙️ 🐍 🆎 🔑. 👉 👑 💭 👈 😮 🎏 🧰 🎏.
@@ -341,7 +341,7 @@ APISpec ✍ 🎏 🍭 👩💻.
///
-/// check | "💭 😮 **FastAPI**"
+/// check | 💭 😮 **FastAPI**
🤗 😮 🍕 APIStar, & 1️⃣ 🧰 👤 🔎 🏆 👍, 🌟 APIStar.
@@ -385,7 +385,7 @@ APIStar ✍ ✡ 🇺🇸🏛. 🎏 👨 👈 ✍:
///
-/// check | "😮 **FastAPI** "
+/// check | 😮 **FastAPI**
🔀.
@@ -409,7 +409,7 @@ Pydantic 🗃 🔬 💽 🔬, 🛠️ & 🧾 (⚙️ 🎻 🔗) ⚓️ 🔛
⚫️ ⭐ 🍭. 👐 ⚫️ ⏩ 🌘 🍭 📇. & ⚫️ ⚓️ 🔛 🎏 🐍 🆎 🔑, 👨🎨 🐕🦺 👑.
-/// check | "**FastAPI** ⚙️ ⚫️"
+/// check | **FastAPI** ⚙️ ⚫️
🍵 🌐 💽 🔬, 💽 🛠️ & 🏧 🏷 🧾 (⚓️ 🔛 🎻 🔗).
@@ -444,7 +444,7 @@ Pydantic 🗃 🔬 💽 🔬, 🛠️ & 🧾 (⚙️ 🎻 🔗) ⚓️ 🔛
👈 1️⃣ 👑 👜 👈 **FastAPI** 🚮 🔛 🔝, 🌐 ⚓️ 🔛 🐍 🆎 🔑 (⚙️ Pydantic). 👈, ➕ 🔗 💉 ⚙️, 💂♂ 🚙, 🗄 🔗 ⚡, ♒️.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
🔫 🆕 "🐩" ➖ 🛠️ ✳ 🐚 🏉 👨🎓. ⚫️ 🚫 "🐍 🐩" (🇩🇬), 👐 👫 🛠️ 🔨 👈.
@@ -452,7 +452,7 @@ Pydantic 🗃 🔬 💽 🔬, 🛠️ & 🧾 (⚙️ 🎻 🔗) ⚓️ 🔛
///
-/// check | "**FastAPI** ⚙️ ⚫️"
+/// check | **FastAPI** ⚙️ ⚫️
🍵 🌐 🐚 🕸 🍕. ❎ ⚒ 🔛 🔝.
@@ -470,7 +470,7 @@ Uvicorn 🌩-⏩ 🔫 💽, 🏗 🔛 uvloop & httptool.
⚫️ 👍 💽 💃 & **FastAPI**.
-/// check | "**FastAPI** 👍 ⚫️"
+/// check | **FastAPI** 👍 ⚫️
👑 🕸 💽 🏃 **FastAPI** 🈸.
diff --git a/docs/em/docs/how-to/conditional-openapi.md b/docs/em/docs/how-to/conditional-openapi.md
index a17ba4eec..a5932933a 100644
--- a/docs/em/docs/how-to/conditional-openapi.md
+++ b/docs/em/docs/how-to/conditional-openapi.md
@@ -30,7 +30,7 @@
🖼:
```Python hl_lines="6 11"
-{!../../../docs_src/conditional_openapi/tutorial001.py!}
+{!../../docs_src/conditional_openapi/tutorial001.py!}
```
📥 👥 📣 ⚒ `openapi_url` ⏮️ 🎏 🔢 `"/openapi.json"`.
diff --git a/docs/em/docs/how-to/custom-request-and-route.md b/docs/em/docs/how-to/custom-request-and-route.md
index 1f66c6eda..cd8811d4e 100644
--- a/docs/em/docs/how-to/custom-request-and-route.md
+++ b/docs/em/docs/how-to/custom-request-and-route.md
@@ -43,7 +43,7 @@
👈 🌌, 🎏 🛣 🎓 💪 🍵 🗜 🗜 ⚖️ 🗜 📨.
```Python hl_lines="8-15"
-{!../../../docs_src/custom_request_and_route/tutorial001.py!}
+{!../../docs_src/custom_request_and_route/tutorial001.py!}
```
### ✍ 🛃 `GzipRoute` 🎓
@@ -57,10 +57,10 @@
📥 👥 ⚙️ ⚫️ ✍ `GzipRequest` ⚪️➡️ ⏮️ 📨.
```Python hl_lines="18-26"
-{!../../../docs_src/custom_request_and_route/tutorial001.py!}
+{!../../docs_src/custom_request_and_route/tutorial001.py!}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
`Request` ✔️ `request.scope` 🔢, 👈 🐍 `dict` ⚗ 🗃 🔗 📨.
@@ -97,13 +97,13 @@
🌐 👥 💪 🍵 📨 🔘 `try`/`except` 🍫:
```Python hl_lines="13 15"
-{!../../../docs_src/custom_request_and_route/tutorial002.py!}
+{!../../docs_src/custom_request_and_route/tutorial002.py!}
```
🚥 ⚠ 📉, `Request` 👐 🔜 ↔, 👥 💪 ✍ & ⚒ ⚙️ 📨 💪 🕐❔ 🚚 ❌:
```Python hl_lines="16-18"
-{!../../../docs_src/custom_request_and_route/tutorial002.py!}
+{!../../docs_src/custom_request_and_route/tutorial002.py!}
```
## 🛃 `APIRoute` 🎓 📻
@@ -111,11 +111,11 @@
👆 💪 ⚒ `route_class` 🔢 `APIRouter`:
```Python hl_lines="26"
-{!../../../docs_src/custom_request_and_route/tutorial003.py!}
+{!../../docs_src/custom_request_and_route/tutorial003.py!}
```
👉 🖼, *➡ 🛠️* 🔽 `router` 🔜 ⚙️ 🛃 `TimedRoute` 🎓, & 🔜 ✔️ ➕ `X-Response-Time` 🎚 📨 ⏮️ 🕰 ⚫️ ✊ 🏗 📨:
```Python hl_lines="13-20"
-{!../../../docs_src/custom_request_and_route/tutorial003.py!}
+{!../../docs_src/custom_request_and_route/tutorial003.py!}
```
diff --git a/docs/em/docs/how-to/extending-openapi.md b/docs/em/docs/how-to/extending-openapi.md
index dc9adf80e..698c78ec1 100644
--- a/docs/em/docs/how-to/extending-openapi.md
+++ b/docs/em/docs/how-to/extending-openapi.md
@@ -47,7 +47,7 @@
🥇, ✍ 🌐 👆 **FastAPI** 🈸 🛎:
```Python hl_lines="1 4 7-9"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
+{!../../docs_src/extending_openapi/tutorial001.py!}
```
### 🏗 🗄 🔗
@@ -55,7 +55,7 @@
⤴️, ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗, 🔘 `custom_openapi()` 🔢:
```Python hl_lines="2 15-20"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
+{!../../docs_src/extending_openapi/tutorial001.py!}
```
### 🔀 🗄 🔗
@@ -63,7 +63,7 @@
🔜 👆 💪 🚮 📄 ↔, ❎ 🛃 `x-logo` `info` "🎚" 🗄 🔗:
```Python hl_lines="21-23"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
+{!../../docs_src/extending_openapi/tutorial001.py!}
```
### 💾 🗄 🔗
@@ -75,7 +75,7 @@
⚫️ 🔜 🏗 🕴 🕐, & ⤴️ 🎏 💾 🔗 🔜 ⚙️ ⏭ 📨.
```Python hl_lines="13-14 24-25"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
+{!../../docs_src/extending_openapi/tutorial001.py!}
```
### 🔐 👩🔬
@@ -83,7 +83,7 @@
🔜 👆 💪 ❎ `.openapi()` 👩🔬 ⏮️ 👆 🆕 🔢.
```Python hl_lines="28"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
+{!../../docs_src/extending_openapi/tutorial001.py!}
```
### ✅ ⚫️
diff --git a/docs/em/docs/how-to/graphql.md b/docs/em/docs/how-to/graphql.md
index b8610b767..5d0d95567 100644
--- a/docs/em/docs/how-to/graphql.md
+++ b/docs/em/docs/how-to/graphql.md
@@ -36,7 +36,7 @@
📥 🤪 🎮 ❔ 👆 💪 🛠️ 🍓 ⏮️ FastAPI:
```Python hl_lines="3 22 25-26"
-{!../../../docs_src/graphql/tutorial001.py!}
+{!../../docs_src/graphql/tutorial001.py!}
```
👆 💪 💡 🌅 🔃 🍓 🍓 🧾.
diff --git a/docs/em/docs/how-to/sql-databases-peewee.md b/docs/em/docs/how-to/sql-databases-peewee.md
deleted file mode 100644
index 88b827c24..000000000
--- a/docs/em/docs/how-to/sql-databases-peewee.md
+++ /dev/null
@@ -1,576 +0,0 @@
-# 🗄 (🔗) 💽 ⏮️ 🏒
-
-/// warning
-
-🚥 👆 ▶️, 🔰 [🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank} 👈 ⚙️ 🇸🇲 🔜 🥃.
-
-💭 🆓 🚶 👉.
-
-///
-
-🚥 👆 ▶️ 🏗 ⚪️➡️ 🖌, 👆 🎲 👻 📆 ⏮️ 🇸🇲 🐜 ([🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank}), ⚖️ 🙆 🎏 🔁 🐜.
-
-🚥 👆 ⏪ ✔️ 📟 🧢 👈 ⚙️ 🏒 🐜, 👆 💪 ✅ 📥 ❔ ⚙️ ⚫️ ⏮️ **FastAPI**.
-
-/// warning | "🐍 3️⃣.7️⃣ ➕ ✔"
-
-👆 🔜 💪 🐍 3️⃣.7️⃣ ⚖️ 🔛 🔒 ⚙️ 🏒 ⏮️ FastAPI.
-
-///
-
-## 🏒 🔁
-
-🏒 🚫 🔧 🔁 🛠️, ⚖️ ⏮️ 👫 🤯.
-
-🏒 ✔️ 🏋️ 🔑 🔃 🚮 🔢 & 🔃 ❔ ⚫️ 🔜 ⚙️.
-
-🚥 👆 🛠️ 🈸 ⏮️ 🗝 🚫-🔁 🛠️, & 💪 👷 ⏮️ 🌐 🚮 🔢, **⚫️ 💪 👑 🧰**.
-
-✋️ 🚥 👆 💪 🔀 🔢, 🐕🦺 🌖 🌘 1️⃣ 🔁 💽, 👷 ⏮️ 🔁 🛠️ (💖 FastAPI), ♒️, 👆 🔜 💪 🚮 🏗 ➕ 📟 🔐 👈 🔢.
-
-👐, ⚫️ 💪 ⚫️, & 📥 👆 🔜 👀 ⚫️❔ ⚫️❔ 📟 👆 ✔️ 🚮 💪 ⚙️ 🏒 ⏮️ FastAPI.
-
-/// note | "📡 ℹ"
-
-👆 💪 ✍ 🌅 🔃 🏒 🧍 🔃 🔁 🐍 🩺, ❔, 🇵🇷.
-
-///
-
-## 🎏 📱
-
-👥 🔜 ✍ 🎏 🈸 🇸🇲 🔰 ([🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank}).
-
-🌅 📟 🤙 🎏.
-
-, 👥 🔜 🎯 🕴 🔛 🔺.
-
-## 📁 📊
-
-➡️ 💬 👆 ✔️ 📁 📛 `my_super_project` 👈 🔌 🎧-📁 🤙 `sql_app` ⏮️ 📊 💖 👉:
-
-```
-.
-└── sql_app
- ├── __init__.py
- ├── crud.py
- ├── database.py
- ├── main.py
- └── schemas.py
-```
-
-👉 🌖 🎏 📊 👥 ✔️ 🇸🇲 🔰.
-
-🔜 ➡️ 👀 ⚫️❔ 🔠 📁/🕹 🔨.
-
-## ✍ 🏒 🍕
-
-➡️ 🔗 📁 `sql_app/database.py`.
-
-### 🐩 🏒 📟
-
-➡️ 🥇 ✅ 🌐 😐 🏒 📟, ✍ 🏒 💽:
-
-```Python hl_lines="3 5 22"
-{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
-```
-
-/// tip
-
-✔️ 🤯 👈 🚥 👆 💚 ⚙️ 🎏 💽, 💖 ✳, 👆 🚫 🚫 🔀 🎻. 👆 🔜 💪 ⚙️ 🎏 🏒 💽 🎓.
-
-///
-
-#### 🗒
-
-❌:
-
-```Python
-check_same_thread=False
-```
-
-🌓 1️⃣ 🇸🇲 🔰:
-
-```Python
-connect_args={"check_same_thread": False}
-```
-
-...⚫️ 💪 🕴 `SQLite`.
-
-/// info | "📡 ℹ"
-
-⚫️❔ 🎏 📡 ℹ [🗄 (🔗) 💽](../tutorial/sql-databases.md#_7){.internal-link target=_blank} ✔.
-
-///
-
-### ⚒ 🏒 🔁-🔗 `PeeweeConnectionState`
-
-👑 ❔ ⏮️ 🏒 & FastAPI 👈 🏒 ⚓️ 🙇 🔛 🐍 `threading.local`, & ⚫️ 🚫 ✔️ 🎯 🌌 🔐 ⚫️ ⚖️ ➡️ 👆 🍵 🔗/🎉 🔗 (🔨 🇸🇲 🔰).
-
-& `threading.local` 🚫 🔗 ⏮️ 🆕 🔁 ⚒ 🏛 🐍.
-
-/// note | "📡 ℹ"
-
-`threading.local` ⚙️ ✔️ "🎱" 🔢 👈 ✔️ 🎏 💲 🔠 🧵.
-
-👉 ⚠ 🗝 🛠️ 🏗 ✔️ 1️⃣ 👁 🧵 📍 📨, 🙅♂ 🌖, 🙅♂ 🌘.
-
-⚙️ 👉, 🔠 📨 🔜 ✔️ 🚮 👍 💽 🔗/🎉, ❔ ☑ 🏁 🥅.
-
-✋️ FastAPI, ⚙️ 🆕 🔁 ⚒, 💪 🍵 🌅 🌘 1️⃣ 📨 🔛 🎏 🧵. & 🎏 🕰, 👁 📨, ⚫️ 💪 🏃 💗 👜 🎏 🧵 (🧵), ⚓️ 🔛 🚥 👆 ⚙️ `async def` ⚖️ 😐 `def`. 👉 ⚫️❔ 🤝 🌐 🎭 📈 FastAPI.
-
-///
-
-✋️ 🐍 3️⃣.7️⃣ & 🔛 🚚 🌖 🏧 🎛 `threading.local`, 👈 💪 ⚙️ 🥉 🌐❔ `threading.local` 🔜 ⚙️, ✋️ 🔗 ⏮️ 🆕 🔁 ⚒.
-
-👥 🔜 ⚙️ 👈. ⚫️ 🤙 `contextvars`.
-
-👥 🔜 🔐 🔗 🍕 🏒 👈 ⚙️ `threading.local` & ❎ 👫 ⏮️ `contextvars`, ⏮️ 🔗 ℹ.
-
-👉 5️⃣📆 😑 🍖 🏗 (& ⚫️ 🤙), 👆 🚫 🤙 💪 🍕 🤔 ❔ ⚫️ 👷 ⚙️ ⚫️.
-
-👥 🔜 ✍ `PeeweeConnectionState`:
-
-```Python hl_lines="10-19"
-{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
-```
-
-👉 🎓 😖 ⚪️➡️ 🎁 🔗 🎓 ⚙️ 🏒.
-
-⚫️ ✔️ 🌐 ⚛ ⚒ 🏒 ⚙️ `contextvars` ↩️ `threading.local`.
-
-`contextvars` 👷 🍖 🎏 🌘 `threading.local`. ✋️ 🎂 🏒 🔗 📟 🤔 👈 👉 🎓 👷 ⏮️ `threading.local`.
-
-, 👥 💪 ➕ 🎱 ⚒ ⚫️ 👷 🚥 ⚫️ ⚙️ `threading.local`. `__init__`, `__setattr__`, & `__getattr__` 🛠️ 🌐 ✔ 🎱 👉 ⚙️ 🏒 🍵 🤔 👈 ⚫️ 🔜 🔗 ⏮️ FastAPI.
-
-/// tip
-
-👉 🔜 ⚒ 🏒 🎭 ☑ 🕐❔ ⚙️ ⏮️ FastAPI. 🚫 🎲 📂 ⚖️ 📪 🔗 👈 ➖ ⚙️, 🏗 ❌, ♒️.
-
-✋️ ⚫️ 🚫 🤝 🏒 🔁 💎-🏋️. 👆 🔜 ⚙️ 😐 `def` 🔢 & 🚫 `async def`.
-
-///
-
-### ⚙️ 🛃 `PeeweeConnectionState` 🎓
-
-🔜, 📁 `._state` 🔗 🔢 🏒 💽 `db` 🎚 ⚙️ 🆕 `PeeweeConnectionState`:
-
-```Python hl_lines="24"
-{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
-```
-
-/// tip
-
-⚒ 💭 👆 📁 `db._state` *⏮️* 🏗 `db`.
-
-///
-
-/// tip
-
-👆 🔜 🎏 🙆 🎏 🏒 💽, 🔌 `PostgresqlDatabase`, `MySQLDatabase`, ♒️.
-
-///
-
-## ✍ 💽 🏷
-
-➡️ 🔜 👀 📁 `sql_app/models.py`.
-
-### ✍ 🏒 🏷 👆 💽
-
-🔜 ✍ 🏒 🏷 (🎓) `User` & `Item`.
-
-👉 🎏 👆 🔜 🚥 👆 ⏩ 🏒 🔰 & ℹ 🏷 ✔️ 🎏 💽 🇸🇲 🔰.
-
-/// tip
-
-🏒 ⚙️ ⚖ "**🏷**" 🔗 👉 🎓 & 👐 👈 🔗 ⏮️ 💽.
-
-✋️ Pydantic ⚙️ ⚖ "**🏷**" 🔗 🕳 🎏, 💽 🔬, 🛠️, & 🧾 🎓 & 👐.
-
-///
-
-🗄 `db` ⚪️➡️ `database` (📁 `database.py` ⚪️➡️ 🔛) & ⚙️ ⚫️ 📥.
-
-```Python hl_lines="3 6-12 15-21"
-{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
-```
-
-/// tip
-
-🏒 ✍ 📚 🎱 🔢.
-
-⚫️ 🔜 🔁 🚮 `id` 🔢 🔢 👑 🔑.
-
-⚫️ 🔜 ⚒ 📛 🏓 ⚓️ 🔛 🎓 📛.
-
- `Item`, ⚫️ 🔜 ✍ 🔢 `owner_id` ⏮️ 🔢 🆔 `User`. ✋️ 👥 🚫 📣 ⚫️ 🙆.
-
-///
-
-## ✍ Pydantic 🏷
-
-🔜 ➡️ ✅ 📁 `sql_app/schemas.py`.
-
-/// tip
-
-❎ 😨 🖖 🏒 *🏷* & Pydantic *🏷*, 👥 🔜 ✔️ 📁 `models.py` ⏮️ 🏒 🏷, & 📁 `schemas.py` ⏮️ Pydantic 🏷.
-
-👫 Pydantic 🏷 🔬 🌅 ⚖️ 🌘 "🔗" (☑ 📊 💠).
-
-👉 🔜 ℹ 👥 ❎ 😨 ⏪ ⚙️ 👯♂️.
-
-///
-
-### ✍ Pydantic *🏷* / 🔗
-
-✍ 🌐 🎏 Pydantic 🏷 🇸🇲 🔰:
-
-```Python hl_lines="16-18 21-22 25-30 34-35 38-39 42-48"
-{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
-```
-
-/// tip
-
-📥 👥 🏗 🏷 ⏮️ `id`.
-
-👥 🚫 🎯 ✔ `id` 🔢 🏒 🏷, ✋️ 🏒 🚮 1️⃣ 🔁.
-
-👥 ❎ 🎱 `owner_id` 🔢 `Item`.
-
-///
-
-### ✍ `PeeweeGetterDict` Pydantic *🏷* / 🔗
-
-🕐❔ 👆 🔐 💛 🏒 🎚, 💖 `some_user.items`, 🏒 🚫 🚚 `list` `Item`.
-
-⚫️ 🚚 🎁 🛃 🎚 🎓 `ModelSelect`.
-
-⚫️ 💪 ✍ `list` 🚮 🏬 ⏮️ `list(some_user.items)`.
-
-✋️ 🎚 ⚫️ 🚫 `list`. & ⚫️ 🚫 ☑ 🐍 🚂. ↩️ 👉, Pydantic 🚫 💭 🔢 ❔ 🗜 ⚫️ `list` Pydantic *🏷* / 🔗.
-
-✋️ ⏮️ ⏬ Pydantic ✔ 🚚 🛃 🎓 👈 😖 ⚪️➡️ `pydantic.utils.GetterDict`, 🚚 🛠️ ⚙️ 🕐❔ ⚙️ `orm_mode = True` 🗃 💲 🐜 🏷 🔢.
-
-👥 🔜 ✍ 🛃 `PeeweeGetterDict` 🎓 & ⚙️ ⚫️ 🌐 🎏 Pydantic *🏷* / 🔗 👈 ⚙️ `orm_mode`:
-
-```Python hl_lines="3 8-13 31 49"
-{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
-```
-
-📥 👥 ✅ 🚥 🔢 👈 ➖ 🔐 (✅ `.items` `some_user.items`) 👐 `peewee.ModelSelect`.
-
-& 🚥 👈 💼, 📨 `list` ⏮️ ⚫️.
-
-& ⤴️ 👥 ⚙️ ⚫️ Pydantic *🏷* / 🔗 👈 ⚙️ `orm_mode = True`, ⏮️ 📳 🔢 `getter_dict = PeeweeGetterDict`.
-
-/// tip
-
-👥 🕴 💪 ✍ 1️⃣ `PeeweeGetterDict` 🎓, & 👥 💪 ⚙️ ⚫️ 🌐 Pydantic *🏷* / 🔗.
-
-///
-
-## 💩 🇨🇻
-
-🔜 ➡️ 👀 📁 `sql_app/crud.py`.
-
-### ✍ 🌐 💩 🇨🇻
-
-✍ 🌐 🎏 💩 🇨🇻 🇸🇲 🔰, 🌐 📟 📶 🎏:
-
-```Python hl_lines="1 4-5 8-9 12-13 16-20 23-24 27-30"
-{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
-```
-
-📤 🔺 ⏮️ 📟 🇸🇲 🔰.
-
-👥 🚫 🚶♀️ `db` 🔢 🤭. ↩️ 👥 ⚙️ 🏷 🔗. 👉 ↩️ `db` 🎚 🌐 🎚, 👈 🔌 🌐 🔗 ⚛. 👈 ⚫️❔ 👥 ✔️ 🌐 `contextvars` ℹ 🔛.
-
-🆖, 🕐❔ 🛬 📚 🎚, 💖 `get_users`, 👥 🔗 🤙 `list`, 💖:
-
-```Python
-list(models.User.select())
-```
-
-👉 🎏 🤔 👈 👥 ✔️ ✍ 🛃 `PeeweeGetterDict`. ✋️ 🛬 🕳 👈 ⏪ `list` ↩️ `peewee.ModelSelect` `response_model` *➡ 🛠️* ⏮️ `List[models.User]` (👈 👥 🔜 👀 ⏪) 🔜 👷 ☑.
-
-## 👑 **FastAPI** 📱
-
-& 🔜 📁 `sql_app/main.py` ➡️ 🛠️ & ⚙️ 🌐 🎏 🍕 👥 ✍ ⏭.
-
-### ✍ 💽 🏓
-
-📶 🙃 🌌 ✍ 💽 🏓:
-
-```Python hl_lines="9-11"
-{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
-```
-
-### ✍ 🔗
-
-✍ 🔗 👈 🔜 🔗 💽 ▶️️ ▶️ 📨 & 🔌 ⚫️ 🔚:
-
-```Python hl_lines="23-29"
-{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
-```
-
-📥 👥 ✔️ 🛁 `yield` ↩️ 👥 🤙 🚫 ⚙️ 💽 🎚 🔗.
-
-⚫️ 🔗 💽 & ♻ 🔗 💽 🔗 🔢 👈 🔬 🔠 📨 (⚙️ `contextvars` 🎱 ⚪️➡️ 🔛).
-
-↩️ 💽 🔗 ⚠ 👤/🅾 🚧, 👉 🔗 ✍ ⏮️ 😐 `def` 🔢.
-
-& ⤴️, 🔠 *➡ 🛠️ 🔢* 👈 💪 🔐 💽 👥 🚮 ⚫️ 🔗.
-
-✋️ 👥 🚫 ⚙️ 💲 👐 👉 🔗 (⚫️ 🤙 🚫 🤝 🙆 💲, ⚫️ ✔️ 🛁 `yield`). , 👥 🚫 🚮 ⚫️ *➡ 🛠️ 🔢* ✋️ *➡ 🛠️ 👨🎨* `dependencies` 🔢:
-
-```Python hl_lines="32 40 47 59 65 72"
-{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
-```
-
-### 🔑 🔢 🎧-🔗
-
-🌐 `contextvars` 🍕 👷, 👥 💪 ⚒ 💭 👥 ✔️ 🔬 💲 `ContextVar` 🔠 📨 👈 ⚙️ 💽, & 👈 💲 🔜 ⚙️ 💽 🇵🇸 (🔗, 💵, ♒️) 🎂 📨.
-
-👈, 👥 💪 ✍ ➕1️⃣ `async` 🔗 `reset_db_state()` 👈 ⚙️ 🎧-🔗 `get_db()`. ⚫️ 🔜 ⚒ 💲 🔑 🔢 (⏮️ 🔢 `dict`) 👈 🔜 ⚙️ 💽 🇵🇸 🎂 📨. & ⤴️ 🔗 `get_db()` 🔜 🏪 ⚫️ 💽 🇵🇸 (🔗, 💵, ♒️).
-
-```Python hl_lines="18-20"
-{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
-```
-
-**⏭ 📨**, 👥 🔜 ⏲ 👈 🔑 🔢 🔄 `async` 🔗 `reset_db_state()` & ⤴️ ✍ 🆕 🔗 `get_db()` 🔗, 👈 🆕 📨 🔜 ✔️ 🚮 👍 💽 🇵🇸 (🔗, 💵, ♒️).
-
-/// tip
-
-FastAPI 🔁 🛠️, 1️⃣ 📨 💪 ▶️ ➖ 🛠️, & ⏭ 🏁, ➕1️⃣ 📨 💪 📨 & ▶️ 🏭 👍, & ⚫️ 🌐 💪 🛠️ 🎏 🧵.
-
-✋️ 🔑 🔢 🤔 👫 🔁 ⚒,, 🏒 💽 🇵🇸 ⚒ `async` 🔗 `reset_db_state()` 🔜 🚧 🚮 👍 💽 🎂 🎂 📨.
-
- & 🎏 🕰, 🎏 🛠️ 📨 🔜 ✔️ 🚮 👍 💽 🇵🇸 👈 🔜 🔬 🎂 📨.
-
-///
-
-#### 🏒 🗳
-
-🚥 👆 ⚙️ 🏒 🗳, ☑ 💽 `db.obj`.
-
-, 👆 🔜 ⏲ ⚫️ ⏮️:
-
-```Python hl_lines="3-4"
-async def reset_db_state():
- database.db.obj._state._state.set(db_state_default.copy())
- database.db.obj._state.reset()
-```
-
-### ✍ 👆 **FastAPI** *➡ 🛠️*
-
-🔜, 😒, 📥 🐩 **FastAPI** *➡ 🛠️* 📟.
-
-```Python hl_lines="32-37 40-43 46-53 56-62 65-68 71-79"
-{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
-```
-
-### 🔃 `def` 🆚 `async def`
-
-🎏 ⏮️ 🇸🇲, 👥 🚫 🔨 🕳 💖:
-
-```Python
-user = await models.User.select().first()
-```
-
-...✋️ ↩️ 👥 ⚙️:
-
-```Python
-user = models.User.select().first()
-```
-
-, 🔄, 👥 🔜 📣 *➡ 🛠️ 🔢* & 🔗 🍵 `async def`, ⏮️ 😐 `def`,:
-
-```Python hl_lines="2"
-# Something goes here
-def read_users(skip: int = 0, limit: int = 100):
- # Something goes here
-```
-
-## 🔬 🏒 ⏮️ 🔁
-
-👉 🖼 🔌 ➕ *➡ 🛠️* 👈 🔬 📏 🏭 📨 ⏮️ `time.sleep(sleep_time)`.
-
-⚫️ 🔜 ✔️ 💽 🔗 📂 ▶️ & 🔜 ⌛ 🥈 ⏭ 🙇 🔙. & 🔠 🆕 📨 🔜 ⌛ 🕐 🥈 🌘.
-
-👉 🔜 💪 ➡️ 👆 💯 👈 👆 📱 ⏮️ 🏒 & FastAPI 🎭 ☑ ⏮️ 🌐 💩 🔃 🧵.
-
-🚥 👆 💚 ✅ ❔ 🏒 🔜 💔 👆 📱 🚥 ⚙️ 🍵 🛠️, 🚶 `sql_app/database.py` 📁 & 🏤 ⏸:
-
-```Python
-# db._state = PeeweeConnectionState()
-```
-
-& 📁 `sql_app/main.py` 📁, 🏤 💪 `async` 🔗 `reset_db_state()` & ❎ ⚫️ ⏮️ `pass`:
-
-```Python
-async def reset_db_state():
-# database.db._state._state.set(db_state_default.copy())
-# database.db._state.reset()
- pass
-```
-
-⤴️ 🏃 👆 📱 ⏮️ Uvicorn:
-
-get 🛠️
-/// info | "`@decorator` ℹ"
+/// info | `@decorator` ℹ
👈 `@something` ❕ 🐍 🤙 "👨🎨".
@@ -307,7 +307,7 @@ https://example.com/items/foo
* **🔢**: 🔢 🔛 "👨🎨" (🔛 `@app.get("/")`).
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
👉 🐍 🔢.
@@ -321,7 +321,7 @@ https://example.com/items/foo
👆 💪 🔬 ⚫️ 😐 🔢 ↩️ `async def`:
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
+{!../../docs_src/first_steps/tutorial003.py!}
```
/// note
@@ -333,7 +333,7 @@ https://example.com/items/foo
### 🔁 5️⃣: 📨 🎚
```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
👆 💪 📨 `dict`, `list`, ⭐ 💲 `str`, `int`, ♒️.
diff --git a/docs/em/docs/tutorial/handling-errors.md b/docs/em/docs/tutorial/handling-errors.md
index ed32ab53a..e0edae51a 100644
--- a/docs/em/docs/tutorial/handling-errors.md
+++ b/docs/em/docs/tutorial/handling-errors.md
@@ -26,7 +26,7 @@
### 🗄 `HTTPException`
```Python hl_lines="1"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### 🤚 `HTTPException` 👆 📟
@@ -42,7 +42,7 @@
👉 🖼, 🕐❔ 👩💻 📨 🏬 🆔 👈 🚫 🔀, 🤚 ⚠ ⏮️ 👔 📟 `404`:
```Python hl_lines="11"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### 📉 📨
@@ -82,7 +82,7 @@
✋️ 💼 👆 💪 ⚫️ 🏧 😐, 👆 💪 🚮 🛃 🎚:
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial002.py!}
+{!../../docs_src/handling_errors/tutorial002.py!}
```
## ❎ 🛃 ⚠ 🐕🦺
@@ -96,7 +96,7 @@
👆 💪 🚮 🛃 ⚠ 🐕🦺 ⏮️ `@app.exception_handler()`:
```Python hl_lines="5-7 13-18 24"
-{!../../../docs_src/handling_errors/tutorial003.py!}
+{!../../docs_src/handling_errors/tutorial003.py!}
```
📥, 🚥 👆 📨 `/unicorns/yolo`, *➡ 🛠️* 🔜 `raise` `UnicornException`.
@@ -109,7 +109,7 @@
{"message": "Oops! yolo did something. There goes a rainbow..."}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.requests import Request` & `from starlette.responses import JSONResponse`.
@@ -136,7 +136,7 @@
⚠ 🐕🦺 🔜 📨 `Request` & ⚠.
```Python hl_lines="2 14-16"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
🔜, 🚥 👆 🚶 `/items/foo`, ↩️ 💆♂ 🔢 🎻 ❌ ⏮️:
@@ -189,10 +189,10 @@ path -> item_id
🖼, 👆 💪 💚 📨 ✅ ✍ 📨 ↩️ 🎻 👫 ❌:
```Python hl_lines="3-4 9-11 22"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import PlainTextResponse`.
@@ -207,7 +207,7 @@ path -> item_id
👆 💪 ⚙️ ⚫️ ⏪ 🛠️ 👆 📱 🕹 💪 & ℹ ⚫️, 📨 ⚫️ 👩💻, ♒️.
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial005.py!}
+{!../../docs_src/handling_errors/tutorial005.py!}
```
🔜 🔄 📨 ❌ 🏬 💖:
@@ -267,7 +267,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
🚥 👆 💚 ⚙️ ⚠ ⤴️ ⏮️ 🎏 🔢 ⚠ 🐕🦺 ⚪️➡️ **FastAPI**, 👆 💪 🗄 & 🏤-⚙️ 🔢 ⚠ 🐕🦺 ⚪️➡️ `fastapi.exception_handlers`:
```Python hl_lines="2-5 15 21"
-{!../../../docs_src/handling_errors/tutorial006.py!}
+{!../../docs_src/handling_errors/tutorial006.py!}
```
👉 🖼 👆 `print`😅 ❌ ⏮️ 📶 🎨 📧, ✋️ 👆 🤚 💭. 👆 💪 ⚙️ ⚠ & ⤴️ 🏤-⚙️ 🔢 ⚠ 🐕🦺.
diff --git a/docs/em/docs/tutorial/header-params.md b/docs/em/docs/tutorial/header-params.md
index 82583c7c3..d9eafe77e 100644
--- a/docs/em/docs/tutorial/header-params.md
+++ b/docs/em/docs/tutorial/header-params.md
@@ -9,7 +9,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001.py!}
+{!> ../../docs_src/header_params/tutorial001.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="1"
-{!> ../../../docs_src/header_params/tutorial001_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_py310.py!}
```
////
@@ -31,7 +31,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001.py!}
+{!> ../../docs_src/header_params/tutorial001.py!}
```
////
@@ -39,12 +39,12 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/header_params/tutorial001_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_py310.py!}
```
////
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
`Header` "👭" 🎓 `Path`, `Query` & `Cookie`. ⚫️ 😖 ⚪️➡️ 🎏 ⚠ `Param` 🎓.
@@ -77,7 +77,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial002.py!}
+{!> ../../docs_src/header_params/tutorial002.py!}
```
////
@@ -85,7 +85,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="8"
-{!> ../../../docs_src/header_params/tutorial002_py310.py!}
+{!> ../../docs_src/header_params/tutorial002_py310.py!}
```
////
@@ -109,7 +109,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003.py!}
+{!> ../../docs_src/header_params/tutorial003.py!}
```
////
@@ -117,7 +117,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_py39.py!}
+{!> ../../docs_src/header_params/tutorial003_py39.py!}
```
////
@@ -125,7 +125,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/header_params/tutorial003_py310.py!}
+{!> ../../docs_src/header_params/tutorial003_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/metadata.md b/docs/em/docs/tutorial/metadata.md
index 6caeed4cd..a30db113d 100644
--- a/docs/em/docs/tutorial/metadata.md
+++ b/docs/em/docs/tutorial/metadata.md
@@ -18,7 +18,7 @@
👆 💪 ⚒ 👫 ⏩:
```Python hl_lines="3-16 19-31"
-{!../../../docs_src/metadata/tutorial001.py!}
+{!../../docs_src/metadata/tutorial001.py!}
```
/// tip
@@ -52,7 +52,7 @@
✍ 🗃 👆 🔖 & 🚶♀️ ⚫️ `openapi_tags` 🔢:
```Python hl_lines="3-16 18"
-{!../../../docs_src/metadata/tutorial004.py!}
+{!../../docs_src/metadata/tutorial004.py!}
```
👀 👈 👆 💪 ⚙️ ✍ 🔘 📛, 🖼 "💳" 🔜 🎦 🦁 (**💳**) & "🎀" 🔜 🎦 ❕ (_🎀_).
@@ -68,7 +68,7 @@
⚙️ `tags` 🔢 ⏮️ 👆 *➡ 🛠️* (& `APIRouter`Ⓜ) 🛠️ 👫 🎏 🔖:
```Python hl_lines="21 26"
-{!../../../docs_src/metadata/tutorial004.py!}
+{!../../docs_src/metadata/tutorial004.py!}
```
/// info
@@ -98,7 +98,7 @@
🖼, ⚒ ⚫️ 🍦 `/api/v1/openapi.json`:
```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial002.py!}
+{!../../docs_src/metadata/tutorial002.py!}
```
🚥 👆 💚 ❎ 🗄 🔗 🍕 👆 💪 ⚒ `openapi_url=None`, 👈 🔜 ❎ 🧾 👩💻 🔢 👈 ⚙️ ⚫️.
@@ -117,5 +117,5 @@
🖼, ⚒ 🦁 🎚 🍦 `/documentation` & ❎ 📄:
```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial003.py!}
+{!../../docs_src/metadata/tutorial003.py!}
```
diff --git a/docs/em/docs/tutorial/middleware.md b/docs/em/docs/tutorial/middleware.md
index b9bb12e00..a794ab019 100644
--- a/docs/em/docs/tutorial/middleware.md
+++ b/docs/em/docs/tutorial/middleware.md
@@ -11,7 +11,7 @@
* ⚫️ 💪 🕳 👈 **📨** ⚖️ 🏃 🙆 💪 📟.
* ⤴️ ⚫️ 📨 **📨**.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
🚥 👆 ✔️ 🔗 ⏮️ `yield`, 🚪 📟 🔜 🏃 *⏮️* 🛠️.
@@ -32,7 +32,7 @@
* 👆 💪 ⤴️ 🔀 🌅 `response` ⏭ 🛬 ⚫️.
```Python hl_lines="8-9 11 14"
-{!../../../docs_src/middleware/tutorial001.py!}
+{!../../docs_src/middleware/tutorial001.py!}
```
/// tip
@@ -43,7 +43,7 @@
///
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.requests import Request`.
@@ -60,7 +60,7 @@
🖼, 👆 💪 🚮 🛃 🎚 `X-Process-Time` ⚗ 🕰 🥈 👈 ⚫️ ✊ 🛠️ 📨 & 🏗 📨:
```Python hl_lines="10 12-13"
-{!../../../docs_src/middleware/tutorial001.py!}
+{!../../docs_src/middleware/tutorial001.py!}
```
## 🎏 🛠️
diff --git a/docs/em/docs/tutorial/path-operation-configuration.md b/docs/em/docs/tutorial/path-operation-configuration.md
index 1979bed2b..deb71c807 100644
--- a/docs/em/docs/tutorial/path-operation-configuration.md
+++ b/docs/em/docs/tutorial/path-operation-configuration.md
@@ -19,7 +19,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001.py!}
```
////
@@ -27,7 +27,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py39.py!}
```
////
@@ -35,14 +35,14 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="1 15"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py310.py!}
```
////
👈 👔 📟 🔜 ⚙️ 📨 & 🔜 🚮 🗄 🔗.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette import status`.
@@ -57,7 +57,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002.py!}
```
////
@@ -65,7 +65,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py39.py!}
```
////
@@ -73,7 +73,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="15 20 25"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py310.py!}
```
////
@@ -91,7 +91,7 @@
**FastAPI** 🐕🦺 👈 🎏 🌌 ⏮️ ✅ 🎻:
```Python hl_lines="1 8-10 13 18"
-{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
+{!../../docs_src/path_operation_configuration/tutorial002b.py!}
```
## 📄 & 📛
@@ -101,7 +101,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003.py!}
```
////
@@ -109,7 +109,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py39.py!}
```
////
@@ -117,7 +117,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="18-19"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py310.py!}
```
////
@@ -131,7 +131,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="19-27"
-{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004.py!}
```
////
@@ -139,7 +139,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="19-27"
-{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py39.py!}
```
////
@@ -147,7 +147,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="17-25"
-{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py310.py!}
```
////
@@ -163,7 +163,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005.py!}
```
////
@@ -171,7 +171,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py39.py!}
```
////
@@ -179,7 +179,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="19"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py310.py!}
```
////
@@ -205,7 +205,7 @@
🚥 👆 💪 ™ *➡ 🛠️* 😢, ✋️ 🍵 ❎ ⚫️, 🚶♀️ 🔢 `deprecated`:
```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_configuration/tutorial006.py!}
```
⚫️ 🔜 🎯 ™ 😢 🎓 🩺:
diff --git a/docs/em/docs/tutorial/path-params-numeric-validations.md b/docs/em/docs/tutorial/path-params-numeric-validations.md
index a7952984c..74dbb55f7 100644
--- a/docs/em/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/em/docs/tutorial/path-params-numeric-validations.md
@@ -9,7 +9,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="1"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
@@ -31,7 +31,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
@@ -39,7 +39,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
@@ -71,7 +71,7 @@
, 👆 💪 📣 👆 🔢:
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
## ✔ 🔢 👆 💪, 🎱
@@ -83,7 +83,7 @@
🐍 🏆 🚫 🕳 ⏮️ 👈 `*`, ✋️ ⚫️ 🔜 💭 👈 🌐 📄 🔢 🔜 🤙 🇨🇻 ❌ (🔑-💲 👫), 💭 kwargs. 🚥 👫 🚫 ✔️ 🔢 💲.
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
## 🔢 🔬: 👑 🌘 ⚖️ 🌓
@@ -93,7 +93,7 @@
📥, ⏮️ `ge=1`, `item_id` 🔜 💪 🔢 🔢 "`g`🅾 🌘 ⚖️ `e`🅾" `1`.
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
## 🔢 🔬: 🌘 🌘 & 🌘 🌘 ⚖️ 🌓
@@ -104,7 +104,7 @@
* `le`: `l`👭 🌘 ⚖️ `e`🅾
```Python hl_lines="9"
-{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
## 🔢 🔬: 🎈, 🌘 🌘 & 🌘 🌘
@@ -118,7 +118,7 @@
& 🎏 lt.
```Python hl_lines="11"
-{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
## 🌃
@@ -140,7 +140,7 @@
///
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
🕐❔ 👆 🗄 `Query`, `Path` & 🎏 ⚪️➡️ `fastapi`, 👫 🤙 🔢.
diff --git a/docs/em/docs/tutorial/path-params.md b/docs/em/docs/tutorial/path-params.md
index e0d51a1df..daf5417eb 100644
--- a/docs/em/docs/tutorial/path-params.md
+++ b/docs/em/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
👆 💪 📣 ➡ "🔢" ⚖️ "🔢" ⏮️ 🎏 ❕ ⚙️ 🐍 📁 🎻:
```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
💲 ➡ 🔢 `item_id` 🔜 🚶♀️ 👆 🔢 ❌ `item_id`.
@@ -19,7 +19,7 @@
👆 💪 📣 🆎 ➡ 🔢 🔢, ⚙️ 🐩 🐍 🆎 ✍:
```Python hl_lines="7"
-{!../../../docs_src/path_params/tutorial002.py!}
+{!../../docs_src/path_params/tutorial002.py!}
```
👉 💼, `item_id` 📣 `int`.
@@ -122,7 +122,7 @@
↩️ *➡ 🛠️* 🔬 ✔, 👆 💪 ⚒ 💭 👈 ➡ `/users/me` 📣 ⏭ 1️⃣ `/users/{user_id}`:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
+{!../../docs_src/path_params/tutorial003.py!}
```
⏪, ➡ `/users/{user_id}` 🔜 🏏 `/users/me`, "💭" 👈 ⚫️ 📨 🔢 `user_id` ⏮️ 💲 `"me"`.
@@ -130,7 +130,7 @@
➡, 👆 🚫🔜 ↔ ➡ 🛠️:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003b.py!}
+{!../../docs_src/path_params/tutorial003b.py!}
```
🥇 🕐 🔜 🕧 ⚙️ ↩️ ➡ 🏏 🥇.
@@ -148,7 +148,7 @@
⤴️ ✍ 🎓 🔢 ⏮️ 🔧 💲, ❔ 🔜 💪 ☑ 💲:
```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
/// info
@@ -168,7 +168,7 @@
⤴️ ✍ *➡ 🔢* ⏮️ 🆎 ✍ ⚙️ 🔢 🎓 👆 ✍ (`ModelName`):
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### ✅ 🩺
@@ -186,7 +186,7 @@
👆 💪 🔬 ⚫️ ⏮️ *🔢 👨🎓* 👆 ✍ 🔢 `ModelName`:
```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
#### 🤚 *🔢 💲*
@@ -194,7 +194,7 @@
👆 💪 🤚 ☑ 💲 ( `str` 👉 💼) ⚙️ `model_name.value`, ⚖️ 🏢, `your_enum_member.value`:
```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
/// tip
@@ -210,7 +210,7 @@
👫 🔜 🗜 👫 🔗 💲 (🎻 👉 💼) ⏭ 🛬 👫 👩💻:
```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
👆 👩💻 👆 🔜 🤚 🎻 📨 💖:
@@ -251,7 +251,7 @@
, 👆 💪 ⚙️ ⚫️ ⏮️:
```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
+{!../../docs_src/path_params/tutorial004.py!}
```
/// tip
diff --git a/docs/em/docs/tutorial/query-params-str-validations.md b/docs/em/docs/tutorial/query-params-str-validations.md
index 23873155e..f75c0a26f 100644
--- a/docs/em/docs/tutorial/query-params-str-validations.md
+++ b/docs/em/docs/tutorial/query-params-str-validations.md
@@ -7,7 +7,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial001.py!}
```
////
@@ -15,7 +15,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial001_py310.py!}
```
////
@@ -41,7 +41,7 @@ FastAPI 🔜 💭 👈 💲 `q` 🚫 ✔ ↩️ 🔢 💲 `= None`.
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="3"
-{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002.py!}
```
////
@@ -49,7 +49,7 @@ FastAPI 🔜 💭 👈 💲 `q` 🚫 ✔ ↩️ 🔢 💲 `= None`.
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="1"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
////
@@ -61,7 +61,7 @@ FastAPI 🔜 💭 👈 💲 `q` 🚫 ✔ ↩️ 🔢 💲 `= None`.
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002.py!}
```
////
@@ -69,7 +69,7 @@ FastAPI 🔜 💭 👈 💲 `q` 🚫 ✔ ↩️ 🔢 💲 `= None`.
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
////
@@ -137,7 +137,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003.py!}
```
////
@@ -145,7 +145,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_py310.py!}
```
////
@@ -157,7 +157,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial004.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004.py!}
```
////
@@ -165,7 +165,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_py310.py!}
```
////
@@ -187,7 +187,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
➡️ 💬 👈 👆 💚 📣 `q` 🔢 🔢 ✔️ `min_length` `3`, & ✔️ 🔢 💲 `"fixedquery"`:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial005.py!}
+{!../../docs_src/query_params_str_validations/tutorial005.py!}
```
/// note
@@ -219,7 +219,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
, 🕐❔ 👆 💪 📣 💲 ✔ ⏪ ⚙️ `Query`, 👆 💪 🎯 🚫 📣 🔢 💲:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006.py!}
+{!../../docs_src/query_params_str_validations/tutorial006.py!}
```
### ✔ ⏮️ ❕ (`...`)
@@ -227,7 +227,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
📤 🎛 🌌 🎯 📣 👈 💲 ✔. 👆 💪 ⚒ `default` 🔢 🔑 💲 `...`:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006b.py!}
+{!../../docs_src/query_params_str_validations/tutorial006b.py!}
```
/// info
@@ -249,7 +249,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c.py!}
```
////
@@ -257,7 +257,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
```
////
@@ -273,7 +273,7 @@ Pydantic, ❔ ⚫️❔ 🏋️ 🌐 💽 🔬 & 🛠️ FastAPI, ✔️
🚥 👆 💭 😬 ⚙️ `...`, 👆 💪 🗄 & ⚙️ `Required` ⚪️➡️ Pydantic:
```Python hl_lines="2 8"
-{!../../../docs_src/query_params_str_validations/tutorial006d.py!}
+{!../../docs_src/query_params_str_validations/tutorial006d.py!}
```
/// tip
@@ -291,7 +291,7 @@ Pydantic, ❔ ⚫️❔ 🏋️ 🌐 💽 🔬 & 🛠️ FastAPI, ✔️
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011.py!}
```
////
@@ -299,7 +299,7 @@ Pydantic, ❔ ⚫️❔ 🏋️ 🌐 💽 🔬 & 🛠️ FastAPI, ✔️
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_py39.py!}
```
////
@@ -307,7 +307,7 @@ Pydantic, ❔ ⚫️❔ 🏋️ 🌐 💽 🔬 & 🛠️ FastAPI, ✔️
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_py310.py!}
```
////
@@ -348,7 +348,7 @@ http://localhost:8000/items/?q=foo&q=bar
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial012.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012.py!}
```
////
@@ -356,7 +356,7 @@ http://localhost:8000/items/?q=foo&q=bar
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_py39.py!}
```
////
@@ -383,7 +383,7 @@ http://localhost:8000/items/
👆 💪 ⚙️ `list` 🔗 ↩️ `List[str]` (⚖️ `list[str]` 🐍 3️⃣.9️⃣ ➕):
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial013.py!}
+{!../../docs_src/query_params_str_validations/tutorial013.py!}
```
/// note
@@ -413,7 +413,7 @@ http://localhost:8000/items/
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007.py!}
```
////
@@ -421,7 +421,7 @@ http://localhost:8000/items/
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_py310.py!}
```
////
@@ -431,7 +431,7 @@ http://localhost:8000/items/
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="13"
-{!> ../../../docs_src/query_params_str_validations/tutorial008.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008.py!}
```
////
@@ -439,7 +439,7 @@ http://localhost:8000/items/
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_py310.py!}
```
////
@@ -465,7 +465,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009.py!}
```
////
@@ -473,7 +473,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_py310.py!}
```
////
@@ -489,7 +489,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="18"
-{!> ../../../docs_src/query_params_str_validations/tutorial010.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010.py!}
```
////
@@ -497,7 +497,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="16"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_py310.py!}
```
////
@@ -513,7 +513,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014.py!}
```
////
@@ -521,7 +521,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/query-params.md b/docs/em/docs/tutorial/query-params.md
index 9bdab9e3c..c8432f182 100644
--- a/docs/em/docs/tutorial/query-params.md
+++ b/docs/em/docs/tutorial/query-params.md
@@ -3,7 +3,7 @@
🕐❔ 👆 📣 🎏 🔢 🔢 👈 🚫 🍕 ➡ 🔢, 👫 🔁 🔬 "🔢" 🔢.
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
+{!../../docs_src/query_params/tutorial001.py!}
```
🔢 ⚒ 🔑-💲 👫 👈 🚶 ⏮️ `?` 📛, 🎏 `&` 🦹.
@@ -66,7 +66,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial002.py!}
+{!> ../../docs_src/query_params/tutorial002.py!}
```
////
@@ -74,7 +74,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial002_py310.py!}
+{!> ../../docs_src/query_params/tutorial002_py310.py!}
```
////
@@ -94,7 +94,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial003.py!}
+{!> ../../docs_src/query_params/tutorial003.py!}
```
////
@@ -102,7 +102,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial003_py310.py!}
+{!> ../../docs_src/query_params/tutorial003_py310.py!}
```
////
@@ -151,7 +151,7 @@ http://127.0.0.1:8000/items/foo?short=yes
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="8 10"
-{!> ../../../docs_src/query_params/tutorial004.py!}
+{!> ../../docs_src/query_params/tutorial004.py!}
```
////
@@ -159,7 +159,7 @@ http://127.0.0.1:8000/items/foo?short=yes
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="6 8"
-{!> ../../../docs_src/query_params/tutorial004_py310.py!}
+{!> ../../docs_src/query_params/tutorial004_py310.py!}
```
////
@@ -173,7 +173,7 @@ http://127.0.0.1:8000/items/foo?short=yes
✋️ 🕐❔ 👆 💚 ⚒ 🔢 🔢 ✔, 👆 💪 🚫 📣 🙆 🔢 💲:
```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
+{!../../docs_src/query_params/tutorial005.py!}
```
📥 🔢 🔢 `needy` ✔ 🔢 🔢 🆎 `str`.
@@ -221,7 +221,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/query_params/tutorial006.py!}
+{!> ../../docs_src/query_params/tutorial006.py!}
```
////
@@ -229,7 +229,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="8"
-{!> ../../../docs_src/query_params/tutorial006_py310.py!}
+{!> ../../docs_src/query_params/tutorial006_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/request-files.md b/docs/em/docs/tutorial/request-files.md
index 010aa76bf..9dcad81b4 100644
--- a/docs/em/docs/tutorial/request-files.md
+++ b/docs/em/docs/tutorial/request-files.md
@@ -17,7 +17,7 @@
🗄 `File` & `UploadFile` ⚪️➡️ `fastapi`:
```Python hl_lines="1"
-{!../../../docs_src/request_files/tutorial001.py!}
+{!../../docs_src/request_files/tutorial001.py!}
```
## 🔬 `File` 🔢
@@ -25,7 +25,7 @@
✍ 📁 🔢 🎏 🌌 👆 🔜 `Body` ⚖️ `Form`:
```Python hl_lines="7"
-{!../../../docs_src/request_files/tutorial001.py!}
+{!../../docs_src/request_files/tutorial001.py!}
```
/// info
@@ -55,7 +55,7 @@
🔬 📁 🔢 ⏮️ 🆎 `UploadFile`:
```Python hl_lines="12"
-{!../../../docs_src/request_files/tutorial001.py!}
+{!../../docs_src/request_files/tutorial001.py!}
```
⚙️ `UploadFile` ✔️ 📚 📈 🤭 `bytes`:
@@ -99,13 +99,13 @@ contents = await myfile.read()
contents = myfile.file.read()
```
-/// note | "`async` 📡 ℹ"
+/// note | `async` 📡 ℹ
🕐❔ 👆 ⚙️ `async` 👩🔬, **FastAPI** 🏃 📁 👩🔬 🧵 & ⌛ 👫.
///
-/// note | "💃 📡 ℹ"
+/// note | 💃 📡 ℹ
**FastAPI**'Ⓜ `UploadFile` 😖 🔗 ⚪️➡️ **💃**'Ⓜ `UploadFile`, ✋️ 🚮 💪 🍕 ⚒ ⚫️ 🔗 ⏮️ **Pydantic** & 🎏 🍕 FastAPI.
@@ -117,7 +117,7 @@ contents = myfile.file.read()
**FastAPI** 🔜 ⚒ 💭 ✍ 👈 📊 ⚪️➡️ ▶️️ 🥉 ↩️ 🎻.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
📊 ⚪️➡️ 📨 🛎 🗜 ⚙️ "📻 🆎" `application/x-www-form-urlencoded` 🕐❔ ⚫️ 🚫 🔌 📁.
@@ -142,7 +142,7 @@ contents = myfile.file.read()
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02.py!}
+{!> ../../docs_src/request_files/tutorial001_02.py!}
```
////
@@ -150,7 +150,7 @@ contents = myfile.file.read()
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7 14"
-{!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
+{!> ../../docs_src/request_files/tutorial001_02_py310.py!}
```
////
@@ -160,7 +160,7 @@ contents = myfile.file.read()
👆 💪 ⚙️ `File()` ⏮️ `UploadFile`, 🖼, ⚒ 🌖 🗃:
```Python hl_lines="13"
-{!../../../docs_src/request_files/tutorial001_03.py!}
+{!../../docs_src/request_files/tutorial001_03.py!}
```
## 💗 📁 📂
@@ -174,7 +174,7 @@ contents = myfile.file.read()
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10 15"
-{!> ../../../docs_src/request_files/tutorial002.py!}
+{!> ../../docs_src/request_files/tutorial002.py!}
```
////
@@ -182,14 +182,14 @@ contents = myfile.file.read()
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="8 13"
-{!> ../../../docs_src/request_files/tutorial002_py39.py!}
+{!> ../../docs_src/request_files/tutorial002_py39.py!}
```
////
👆 🔜 📨, 📣, `list` `bytes` ⚖️ `UploadFile`Ⓜ.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.responses import HTMLResponse`.
@@ -204,7 +204,7 @@ contents = myfile.file.read()
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="18"
-{!> ../../../docs_src/request_files/tutorial003.py!}
+{!> ../../docs_src/request_files/tutorial003.py!}
```
////
@@ -212,7 +212,7 @@ contents = myfile.file.read()
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="16"
-{!> ../../../docs_src/request_files/tutorial003_py39.py!}
+{!> ../../docs_src/request_files/tutorial003_py39.py!}
```
////
diff --git a/docs/em/docs/tutorial/request-forms-and-files.md b/docs/em/docs/tutorial/request-forms-and-files.md
index ab39d1b94..80793dae4 100644
--- a/docs/em/docs/tutorial/request-forms-and-files.md
+++ b/docs/em/docs/tutorial/request-forms-and-files.md
@@ -13,7 +13,7 @@
## 🗄 `File` & `Form`
```Python hl_lines="1"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!../../docs_src/request_forms_and_files/tutorial001.py!}
```
## 🔬 `File` & `Form` 🔢
@@ -21,7 +21,7 @@
✍ 📁 & 📨 🔢 🎏 🌌 👆 🔜 `Body` ⚖️ `Query`:
```Python hl_lines="8"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!../../docs_src/request_forms_and_files/tutorial001.py!}
```
📁 & 📨 🏑 🔜 📂 📨 📊 & 👆 🔜 📨 📁 & 📨 🏑.
diff --git a/docs/em/docs/tutorial/request-forms.md b/docs/em/docs/tutorial/request-forms.md
index 74117c47d..d364d2c92 100644
--- a/docs/em/docs/tutorial/request-forms.md
+++ b/docs/em/docs/tutorial/request-forms.md
@@ -15,7 +15,7 @@
🗄 `Form` ⚪️➡️ `fastapi`:
```Python hl_lines="1"
-{!../../../docs_src/request_forms/tutorial001.py!}
+{!../../docs_src/request_forms/tutorial001.py!}
```
## 🔬 `Form` 🔢
@@ -23,7 +23,7 @@
✍ 📨 🔢 🎏 🌌 👆 🔜 `Body` ⚖️ `Query`:
```Python hl_lines="7"
-{!../../../docs_src/request_forms/tutorial001.py!}
+{!../../docs_src/request_forms/tutorial001.py!}
```
🖼, 1️⃣ 🌌 Oauth2️⃣ 🔧 💪 ⚙️ (🤙 "🔐 💧") ⚫️ ✔ 📨 `username` & `password` 📨 🏑.
@@ -50,7 +50,7 @@
**FastAPI** 🔜 ⚒ 💭 ✍ 👈 📊 ⚪️➡️ ▶️️ 🥉 ↩️ 🎻.
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
📊 ⚪️➡️ 📨 🛎 🗜 ⚙️ "📻 🆎" `application/x-www-form-urlencoded`.
diff --git a/docs/em/docs/tutorial/response-model.md b/docs/em/docs/tutorial/response-model.md
index 9483508aa..fb5c17dd6 100644
--- a/docs/em/docs/tutorial/response-model.md
+++ b/docs/em/docs/tutorial/response-model.md
@@ -7,7 +7,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="18 23"
-{!> ../../../docs_src/response_model/tutorial001_01.py!}
+{!> ../../docs_src/response_model/tutorial001_01.py!}
```
////
@@ -15,7 +15,7 @@
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="18 23"
-{!> ../../../docs_src/response_model/tutorial001_01_py39.py!}
+{!> ../../docs_src/response_model/tutorial001_01_py39.py!}
```
////
@@ -23,7 +23,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="16 21"
-{!> ../../../docs_src/response_model/tutorial001_01_py310.py!}
+{!> ../../docs_src/response_model/tutorial001_01_py310.py!}
```
////
@@ -62,7 +62,7 @@ FastAPI 🔜 ⚙️ 👉 📨 🆎:
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001.py!}
+{!> ../../docs_src/response_model/tutorial001.py!}
```
////
@@ -70,7 +70,7 @@ FastAPI 🔜 ⚙️ 👉 📨 🆎:
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001_py39.py!}
+{!> ../../docs_src/response_model/tutorial001_py39.py!}
```
////
@@ -78,7 +78,7 @@ FastAPI 🔜 ⚙️ 👉 📨 🆎:
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001_py310.py!}
+{!> ../../docs_src/response_model/tutorial001_py310.py!}
```
////
@@ -116,7 +116,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9 11"
-{!> ../../../docs_src/response_model/tutorial002.py!}
+{!> ../../docs_src/response_model/tutorial002.py!}
```
////
@@ -124,7 +124,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7 9"
-{!> ../../../docs_src/response_model/tutorial002_py310.py!}
+{!> ../../docs_src/response_model/tutorial002_py310.py!}
```
////
@@ -143,7 +143,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="18"
-{!> ../../../docs_src/response_model/tutorial002.py!}
+{!> ../../docs_src/response_model/tutorial002.py!}
```
////
@@ -151,7 +151,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="16"
-{!> ../../../docs_src/response_model/tutorial002_py310.py!}
+{!> ../../docs_src/response_model/tutorial002_py310.py!}
```
////
@@ -175,7 +175,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9 11 16"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -183,7 +183,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="9 11 16"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -193,7 +193,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -201,7 +201,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -211,7 +211,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -219,7 +219,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -249,7 +249,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9-13 15-16 20"
-{!> ../../../docs_src/response_model/tutorial003_01.py!}
+{!> ../../docs_src/response_model/tutorial003_01.py!}
```
////
@@ -257,7 +257,7 @@ FastAPI 🔜 ⚙️ 👉 `response_model` 🌐 💽 🧾, 🔬, ♒️. & **
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7-10 13-14 18"
-{!> ../../../docs_src/response_model/tutorial003_01_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_01_py310.py!}
```
////
@@ -303,7 +303,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
🏆 ⚠ 💼 🔜 [🛬 📨 🔗 🔬 ⏪ 🏧 🩺](../advanced/response-directly.md){.internal-link target=_blank}.
```Python hl_lines="8 10-11"
-{!> ../../../docs_src/response_model/tutorial003_02.py!}
+{!> ../../docs_src/response_model/tutorial003_02.py!}
```
👉 🙅 💼 🍵 🔁 FastAPI ↩️ 📨 🆎 ✍ 🎓 (⚖️ 🏿) `Response`.
@@ -315,7 +315,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
👆 💪 ⚙️ 🏿 `Response` 🆎 ✍:
```Python hl_lines="8-9"
-{!> ../../../docs_src/response_model/tutorial003_03.py!}
+{!> ../../docs_src/response_model/tutorial003_03.py!}
```
👉 🔜 👷 ↩️ `RedirectResponse` 🏿 `Response`, & FastAPI 🔜 🔁 🍵 👉 🙅 💼.
@@ -329,7 +329,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="10"
-{!> ../../../docs_src/response_model/tutorial003_04.py!}
+{!> ../../docs_src/response_model/tutorial003_04.py!}
```
////
@@ -337,7 +337,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="8"
-{!> ../../../docs_src/response_model/tutorial003_04_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_04_py310.py!}
```
////
@@ -355,7 +355,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/response_model/tutorial003_05.py!}
+{!> ../../docs_src/response_model/tutorial003_05.py!}
```
////
@@ -363,7 +363,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/response_model/tutorial003_05_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_05_py310.py!}
```
////
@@ -377,7 +377,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="11 13-14"
-{!> ../../../docs_src/response_model/tutorial004.py!}
+{!> ../../docs_src/response_model/tutorial004.py!}
```
////
@@ -385,7 +385,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="11 13-14"
-{!> ../../../docs_src/response_model/tutorial004_py39.py!}
+{!> ../../docs_src/response_model/tutorial004_py39.py!}
```
////
@@ -393,7 +393,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="9 11-12"
-{!> ../../../docs_src/response_model/tutorial004_py310.py!}
+{!> ../../docs_src/response_model/tutorial004_py310.py!}
```
////
@@ -413,7 +413,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial004.py!}
+{!> ../../docs_src/response_model/tutorial004.py!}
```
////
@@ -421,7 +421,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial004_py39.py!}
+{!> ../../docs_src/response_model/tutorial004_py39.py!}
```
////
@@ -429,7 +429,7 @@ FastAPI 🔨 📚 👜 🔘 ⏮️ Pydantic ⚒ 💭 👈 📚 🎏 🚫 🎓
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial004_py310.py!}
+{!> ../../docs_src/response_model/tutorial004_py310.py!}
```
////
@@ -524,7 +524,7 @@ FastAPI 🙃 🥃 (🤙, Pydantic 🙃 🥃) 🤔 👈, ✋️ `description`, `t
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="31 37"
-{!> ../../../docs_src/response_model/tutorial005.py!}
+{!> ../../docs_src/response_model/tutorial005.py!}
```
////
@@ -532,7 +532,7 @@ FastAPI 🙃 🥃 (🤙, Pydantic 🙃 🥃) 🤔 👈, ✋️ `description`, `t
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="29 35"
-{!> ../../../docs_src/response_model/tutorial005_py310.py!}
+{!> ../../docs_src/response_model/tutorial005_py310.py!}
```
////
@@ -552,7 +552,7 @@ FastAPI 🙃 🥃 (🤙, Pydantic 🙃 🥃) 🤔 👈, ✋️ `description`, `t
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="31 37"
-{!> ../../../docs_src/response_model/tutorial006.py!}
+{!> ../../docs_src/response_model/tutorial006.py!}
```
////
@@ -560,7 +560,7 @@ FastAPI 🙃 🥃 (🤙, Pydantic 🙃 🥃) 🤔 👈, ✋️ `description`, `t
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="29 35"
-{!> ../../../docs_src/response_model/tutorial006_py310.py!}
+{!> ../../docs_src/response_model/tutorial006_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/response-status-code.md b/docs/em/docs/tutorial/response-status-code.md
index 57c44777a..478060326 100644
--- a/docs/em/docs/tutorial/response-status-code.md
+++ b/docs/em/docs/tutorial/response-status-code.md
@@ -9,7 +9,7 @@
* ♒️.
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
/// note
@@ -77,7 +77,7 @@ FastAPI 💭 👉, & 🔜 🏭 🗄 🩺 👈 🇵🇸 📤 🙅♂ 📨
➡️ 👀 ⏮️ 🖼 🔄:
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
`201` 👔 📟 "✍".
@@ -87,14 +87,14 @@ FastAPI 💭 👉, & 🔜 🏭 🗄 🩺 👈 🇵🇸 📤 🙅♂ 📨
👆 💪 ⚙️ 🏪 🔢 ⚪️➡️ `fastapi.status`.
```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
+{!../../docs_src/response_status_code/tutorial002.py!}
```
👫 🏪, 👫 🧑🤝🧑 🎏 🔢, ✋️ 👈 🌌 👆 💪 ⚙️ 👨🎨 📋 🔎 👫:
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette import status`.
diff --git a/docs/em/docs/tutorial/schema-extra-example.md b/docs/em/docs/tutorial/schema-extra-example.md
index 8562de09c..e4f877a8e 100644
--- a/docs/em/docs/tutorial/schema-extra-example.md
+++ b/docs/em/docs/tutorial/schema-extra-example.md
@@ -11,7 +11,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="15-23"
-{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
+{!> ../../docs_src/schema_extra_example/tutorial001.py!}
```
////
@@ -19,7 +19,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="13-21"
-{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial001_py310.py!}
```
////
@@ -43,7 +43,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="4 10-13"
-{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
+{!> ../../docs_src/schema_extra_example/tutorial002.py!}
```
////
@@ -51,7 +51,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="2 8-11"
-{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial002_py310.py!}
```
////
@@ -83,7 +83,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="20-25"
-{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003.py!}
```
////
@@ -91,7 +91,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="18-23"
-{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003_py310.py!}
```
////
@@ -118,7 +118,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="21-47"
-{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004.py!}
```
////
@@ -126,7 +126,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="19-45"
-{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/security/first-steps.md b/docs/em/docs/tutorial/security/first-steps.md
index 538ea7b0a..21c48757f 100644
--- a/docs/em/docs/tutorial/security/first-steps.md
+++ b/docs/em/docs/tutorial/security/first-steps.md
@@ -21,7 +21,7 @@
📁 🖼 📁 `main.py`:
```Python
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
## 🏃 ⚫️
@@ -56,7 +56,7 @@ $ uvicorn main:app --reload
-/// check | "✔ 🔼 ❗"
+/// check | ✔ 🔼 ❗
👆 ⏪ ✔️ ✨ 🆕 "✔" 🔼.
@@ -129,7 +129,7 @@ Oauth2️⃣ 🔧 👈 👩💻 ⚖️ 🛠️ 💪 🔬 💽 👈 🔓 👩
🕐❔ 👥 ✍ 👐 `OAuth2PasswordBearer` 🎓 👥 🚶♀️ `tokenUrl` 🔢. 👉 🔢 🔌 📛 👈 👩💻 (🕸 🏃 👩💻 🖥) 🔜 ⚙️ 📨 `username` & `password` ✔ 🤚 🤝.
```Python hl_lines="6"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
/// tip
@@ -169,14 +169,14 @@ oauth2_scheme(some, parameters)
🔜 👆 💪 🚶♀️ 👈 `oauth2_scheme` 🔗 ⏮️ `Depends`.
```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
👉 🔗 🔜 🚚 `str` 👈 🛠️ 🔢 `token` *➡ 🛠️ 🔢*.
**FastAPI** 🔜 💭 👈 ⚫️ 💪 ⚙️ 👉 🔗 🔬 "💂♂ ⚖" 🗄 🔗 (& 🏧 🛠️ 🩺).
-/// info | "📡 ℹ"
+/// info | 📡 ℹ
**FastAPI** 🔜 💭 👈 ⚫️ 💪 ⚙️ 🎓 `OAuth2PasswordBearer` (📣 🔗) 🔬 💂♂ ⚖ 🗄 ↩️ ⚫️ 😖 ⚪️➡️ `fastapi.security.oauth2.OAuth2`, ❔ 🔄 😖 ⚪️➡️ `fastapi.security.base.SecurityBase`.
diff --git a/docs/em/docs/tutorial/security/get-current-user.md b/docs/em/docs/tutorial/security/get-current-user.md
index 15545f427..4e5b4ebfc 100644
--- a/docs/em/docs/tutorial/security/get-current-user.md
+++ b/docs/em/docs/tutorial/security/get-current-user.md
@@ -3,7 +3,7 @@
⏮️ 📃 💂♂ ⚙️ (❔ 🧢 🔛 🔗 💉 ⚙️) 🤝 *➡ 🛠️ 🔢* `token` `str`:
```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
✋️ 👈 🚫 👈 ⚠.
@@ -19,7 +19,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -27,7 +27,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="3 10-14"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -45,7 +45,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -53,7 +53,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="23"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -65,7 +65,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -73,7 +73,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="17-20 24-25"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -85,7 +85,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -93,7 +93,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="29"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -153,7 +153,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -161,7 +161,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="28-30"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/security/oauth2-jwt.md b/docs/em/docs/tutorial/security/oauth2-jwt.md
index 3ab8cc986..95fa58f71 100644
--- a/docs/em/docs/tutorial/security/oauth2-jwt.md
+++ b/docs/em/docs/tutorial/security/oauth2-jwt.md
@@ -121,7 +121,7 @@ $ pip install "passlib[bcrypt]"
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="7 48 55-56 59-60 69-75"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -129,7 +129,7 @@ $ pip install "passlib[bcrypt]"
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="6 47 54-55 58-59 68-74"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
@@ -171,7 +171,7 @@ $ openssl rand -hex 32
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="6 12-14 28-30 78-86"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -179,7 +179,7 @@ $ openssl rand -hex 32
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="5 11-13 27-29 77-85"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
@@ -195,7 +195,7 @@ $ openssl rand -hex 32
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="89-106"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -203,7 +203,7 @@ $ openssl rand -hex 32
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="88-105"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
@@ -217,7 +217,7 @@ $ openssl rand -hex 32
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="115-130"
-{!> ../../../docs_src/security/tutorial004.py!}
+{!> ../../docs_src/security/tutorial004.py!}
```
////
@@ -225,7 +225,7 @@ $ openssl rand -hex 32
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="114-129"
-{!> ../../../docs_src/security/tutorial004_py310.py!}
+{!> ../../docs_src/security/tutorial004_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/security/simple-oauth2.md b/docs/em/docs/tutorial/security/simple-oauth2.md
index 937546be8..43d928ce7 100644
--- a/docs/em/docs/tutorial/security/simple-oauth2.md
+++ b/docs/em/docs/tutorial/security/simple-oauth2.md
@@ -55,7 +55,7 @@ Oauth2️⃣ 👫 🎻.
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="4 76"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -63,7 +63,7 @@ Oauth2️⃣ 👫 🎻.
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="2 74"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -117,7 +117,7 @@ Oauth2️⃣ 🔌 🤙 *🚚* 🏑 `grant_type` ⏮️ 🔧 💲 `password`, ✋
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="3 77-79"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -125,7 +125,7 @@ Oauth2️⃣ 🔌 🤙 *🚚* 🏑 `grant_type` ⏮️ 🔧 💲 `password`, ✋
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="1 75-77"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -157,7 +157,7 @@ Oauth2️⃣ 🔌 🤙 *🚚* 🏑 `grant_type` ⏮️ 🔧 💲 `password`, ✋
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="80-83"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -165,7 +165,7 @@ Oauth2️⃣ 🔌 🤙 *🚚* 🏑 `grant_type` ⏮️ 🔧 💲 `password`, ✋
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="78-81"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -213,7 +213,7 @@ UserInDB(
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="85"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -221,7 +221,7 @@ UserInDB(
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="83"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -253,7 +253,7 @@ UserInDB(
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="58-66 69-72 90"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -261,7 +261,7 @@ UserInDB(
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="55-64 67-70 88"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
diff --git a/docs/em/docs/tutorial/sql-databases.md b/docs/em/docs/tutorial/sql-databases.md
index 2492c8708..49162dd62 100644
--- a/docs/em/docs/tutorial/sql-databases.md
+++ b/docs/em/docs/tutorial/sql-databases.md
@@ -110,13 +110,13 @@ $ pip install sqlalchemy
### 🗄 🇸🇲 🍕
```Python hl_lines="1-3"
-{!../../../docs_src/sql_databases/sql_app/database.py!}
+{!../../docs_src/sql_databases/sql_app/database.py!}
```
### ✍ 💽 📛 🇸🇲
```Python hl_lines="5-6"
-{!../../../docs_src/sql_databases/sql_app/database.py!}
+{!../../docs_src/sql_databases/sql_app/database.py!}
```
👉 🖼, 👥 "🔗" 🗄 💽 (📂 📁 ⏮️ 🗄 💽).
@@ -146,7 +146,7 @@ SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
👥 🔜 ⏪ ⚙️ 👉 `engine` 🎏 🥉.
```Python hl_lines="8-10"
-{!../../../docs_src/sql_databases/sql_app/database.py!}
+{!../../docs_src/sql_databases/sql_app/database.py!}
```
#### 🗒
@@ -159,7 +159,7 @@ connect_args={"check_same_thread": False}
...💪 🕴 `SQLite`. ⚫️ 🚫 💪 🎏 💽.
-/// info | "📡 ℹ"
+/// info | 📡 ℹ
🔢 🗄 🔜 🕴 ✔ 1️⃣ 🧵 🔗 ⏮️ ⚫️, 🤔 👈 🔠 🧵 🔜 🍵 🔬 📨.
@@ -184,7 +184,7 @@ connect_args={"check_same_thread": False}
✍ `SessionLocal` 🎓, ⚙️ 🔢 `sessionmaker`:
```Python hl_lines="11"
-{!../../../docs_src/sql_databases/sql_app/database.py!}
+{!../../docs_src/sql_databases/sql_app/database.py!}
```
### ✍ `Base` 🎓
@@ -194,7 +194,7 @@ connect_args={"check_same_thread": False}
⏪ 👥 🔜 😖 ⚪️➡️ 👉 🎓 ✍ 🔠 💽 🏷 ⚖️ 🎓 (🐜 🏷):
```Python hl_lines="13"
-{!../../../docs_src/sql_databases/sql_app/database.py!}
+{!../../docs_src/sql_databases/sql_app/database.py!}
```
## ✍ 💽 🏷
@@ -220,7 +220,7 @@ connect_args={"check_same_thread": False}
👫 🎓 🇸🇲 🏷.
```Python hl_lines="4 7-8 18-19"
-{!../../../docs_src/sql_databases/sql_app/models.py!}
+{!../../docs_src/sql_databases/sql_app/models.py!}
```
`__tablename__` 🔢 💬 🇸🇲 📛 🏓 ⚙️ 💽 🔠 👫 🏷.
@@ -236,7 +236,7 @@ connect_args={"check_same_thread": False}
& 👥 🚶♀️ 🇸🇲 🎓 "🆎", `Integer`, `String`, & `Boolean`, 👈 🔬 🆎 💽, ❌.
```Python hl_lines="1 10-13 21-24"
-{!../../../docs_src/sql_databases/sql_app/models.py!}
+{!../../docs_src/sql_databases/sql_app/models.py!}
```
### ✍ 💛
@@ -248,7 +248,7 @@ connect_args={"check_same_thread": False}
👉 🔜 ▶️️, 🌅 ⚖️ 🌘, "🎱" 🔢 👈 🔜 🔌 💲 ⚪️➡️ 🎏 🏓 🔗 👉 1️⃣.
```Python hl_lines="2 15 26"
-{!../../../docs_src/sql_databases/sql_app/models.py!}
+{!../../docs_src/sql_databases/sql_app/models.py!}
```
🕐❔ 🔐 🔢 `items` `User`, `my_user.items`, ⚫️ 🔜 ✔️ 📇 `Item` 🇸🇲 🏷 (⚪️➡️ `items` 🏓) 👈 ✔️ 💱 🔑 ☝ 👉 ⏺ `users` 🏓.
@@ -284,7 +284,7 @@ connect_args={"check_same_thread": False}
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="3 6-8 11-12 23-24 27-28"
-{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app/schemas.py!}
```
////
@@ -292,7 +292,7 @@ connect_args={"check_same_thread": False}
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="3 6-8 11-12 23-24 27-28"
-{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
////
@@ -300,7 +300,7 @@ connect_args={"check_same_thread": False}
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="1 4-6 9-10 21-22 25-26"
-{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
////
@@ -334,7 +334,7 @@ name: str
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="15-17 31-34"
-{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app/schemas.py!}
```
////
@@ -342,7 +342,7 @@ name: str
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="15-17 31-34"
-{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
////
@@ -350,7 +350,7 @@ name: str
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="13-15 29-32"
-{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
////
@@ -372,7 +372,7 @@ name: str
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="15 19-20 31 36-37"
-{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app/schemas.py!}
```
////
@@ -380,7 +380,7 @@ name: str
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="15 19-20 31 36-37"
-{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
////
@@ -388,7 +388,7 @@ name: str
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python hl_lines="13 17-18 29 34-35"
-{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
////
@@ -466,7 +466,7 @@ current_user.items
* ✍ 💗 🏬.
```Python hl_lines="1 3 6-7 10-11 14-15 27-28"
-{!../../../docs_src/sql_databases/sql_app/crud.py!}
+{!../../docs_src/sql_databases/sql_app/crud.py!}
```
/// tip
@@ -487,7 +487,7 @@ current_user.items
* `refresh` 👆 👐 (👈 ⚫️ 🔌 🙆 🆕 📊 ⚪️➡️ 💽, 💖 🏗 🆔).
```Python hl_lines="18-24 31-36"
-{!../../../docs_src/sql_databases/sql_app/crud.py!}
+{!../../docs_src/sql_databases/sql_app/crud.py!}
```
/// tip
@@ -539,7 +539,7 @@ current_user.items
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="9"
-{!> ../../../docs_src/sql_databases/sql_app/main.py!}
+{!> ../../docs_src/sql_databases/sql_app/main.py!}
```
////
@@ -547,7 +547,7 @@ current_user.items
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="7"
-{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/main.py!}
```
////
@@ -577,7 +577,7 @@ current_user.items
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="15-20"
-{!> ../../../docs_src/sql_databases/sql_app/main.py!}
+{!> ../../docs_src/sql_databases/sql_app/main.py!}
```
////
@@ -585,7 +585,7 @@ current_user.items
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="13-18"
-{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/main.py!}
```
////
@@ -609,7 +609,7 @@ current_user.items
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="24 32 38 47 53"
-{!> ../../../docs_src/sql_databases/sql_app/main.py!}
+{!> ../../docs_src/sql_databases/sql_app/main.py!}
```
////
@@ -617,12 +617,12 @@ current_user.items
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="22 30 36 45 51"
-{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/main.py!}
```
////
-/// info | "📡 ℹ"
+/// info | 📡 ℹ
🔢 `db` 🤙 🆎 `SessionLocal`, ✋️ 👉 🎓 (✍ ⏮️ `sessionmaker()`) "🗳" 🇸🇲 `Session`,, 👨🎨 🚫 🤙 💭 ⚫️❔ 👩🔬 🚚.
@@ -637,7 +637,7 @@ current_user.items
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="23-28 31-34 37-42 45-49 52-55"
-{!> ../../../docs_src/sql_databases/sql_app/main.py!}
+{!> ../../docs_src/sql_databases/sql_app/main.py!}
```
////
@@ -645,7 +645,7 @@ current_user.items
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="21-26 29-32 35-40 43-47 50-53"
-{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/main.py!}
```
////
@@ -705,7 +705,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
///
-/// note | "📶 📡 ℹ"
+/// note | 📶 📡 ℹ
🚥 👆 😟 & ✔️ ⏬ 📡 💡, 👆 💪 ✅ 📶 📡 ℹ ❔ 👉 `async def` 🆚 `def` 🍵 [🔁](../async.md#i_2){.internal-link target=_blank} 🩺.
@@ -732,13 +732,13 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
* `sql_app/database.py`:
```Python
-{!../../../docs_src/sql_databases/sql_app/database.py!}
+{!../../docs_src/sql_databases/sql_app/database.py!}
```
* `sql_app/models.py`:
```Python
-{!../../../docs_src/sql_databases/sql_app/models.py!}
+{!../../docs_src/sql_databases/sql_app/models.py!}
```
* `sql_app/schemas.py`:
@@ -746,7 +746,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python
-{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app/schemas.py!}
```
////
@@ -754,7 +754,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python
-{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
////
@@ -762,7 +762,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python
-{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
+{!> ../../docs_src/sql_databases/sql_app_py310/schemas.py!}
```
////
@@ -770,7 +770,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
* `sql_app/crud.py`:
```Python
-{!../../../docs_src/sql_databases/sql_app/crud.py!}
+{!../../docs_src/sql_databases/sql_app/crud.py!}
```
* `sql_app/main.py`:
@@ -778,7 +778,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python
-{!> ../../../docs_src/sql_databases/sql_app/main.py!}
+{!> ../../docs_src/sql_databases/sql_app/main.py!}
```
////
@@ -786,7 +786,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python
-{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/main.py!}
```
////
@@ -843,7 +843,7 @@ $ uvicorn sql_app.main:app --reload
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python hl_lines="14-22"
-{!> ../../../docs_src/sql_databases/sql_app/alt_main.py!}
+{!> ../../docs_src/sql_databases/sql_app/alt_main.py!}
```
////
@@ -851,7 +851,7 @@ $ uvicorn sql_app.main:app --reload
//// tab | 🐍 3️⃣.9️⃣ & 🔛
```Python hl_lines="12-20"
-{!> ../../../docs_src/sql_databases/sql_app_py39/alt_main.py!}
+{!> ../../docs_src/sql_databases/sql_app_py39/alt_main.py!}
```
////
diff --git a/docs/em/docs/tutorial/static-files.md b/docs/em/docs/tutorial/static-files.md
index 3305746c2..c9bb9ff6a 100644
--- a/docs/em/docs/tutorial/static-files.md
+++ b/docs/em/docs/tutorial/static-files.md
@@ -8,10 +8,10 @@
* "🗻" `StaticFiles()` 👐 🎯 ➡.
```Python hl_lines="2 6"
-{!../../../docs_src/static_files/tutorial001.py!}
+{!../../docs_src/static_files/tutorial001.py!}
```
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.staticfiles import StaticFiles`.
diff --git a/docs/em/docs/tutorial/testing.md b/docs/em/docs/tutorial/testing.md
index 75dd2d295..27cf9f16e 100644
--- a/docs/em/docs/tutorial/testing.md
+++ b/docs/em/docs/tutorial/testing.md
@@ -27,7 +27,7 @@
✍ 🙅 `assert` 📄 ⏮️ 🐩 🐍 🧬 👈 👆 💪 ✅ (🔄, 🐩 `pytest`).
```Python hl_lines="2 12 15-18"
-{!../../../docs_src/app_testing/tutorial001.py!}
+{!../../docs_src/app_testing/tutorial001.py!}
```
/// tip
@@ -40,7 +40,7 @@
///
-/// note | "📡 ℹ"
+/// note | 📡 ℹ
👆 💪 ⚙️ `from starlette.testclient import TestClient`.
@@ -75,7 +75,7 @@
```Python
-{!../../../docs_src/app_testing/main.py!}
+{!../../docs_src/app_testing/main.py!}
```
### 🔬 📁
@@ -93,7 +93,7 @@
↩️ 👉 📁 🎏 📦, 👆 💪 ⚙️ ⚖ 🗄 🗄 🎚 `app` ⚪️➡️ `main` 🕹 (`main.py`):
```Python hl_lines="3"
-{!../../../docs_src/app_testing/test_main.py!}
+{!../../docs_src/app_testing/test_main.py!}
```
...& ✔️ 📟 💯 💖 ⏭.
@@ -125,7 +125,7 @@
//// tab | 🐍 3️⃣.6️⃣ & 🔛
```Python
-{!> ../../../docs_src/app_testing/app_b/main.py!}
+{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
@@ -133,7 +133,7 @@
//// tab | 🐍 3️⃣.1️⃣0️⃣ & 🔛
```Python
-{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
+{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
@@ -143,7 +143,7 @@
👆 💪 ⤴️ ℹ `test_main.py` ⏮️ ↔ 💯:
```Python
-{!> ../../../docs_src/app_testing/app_b/test_main.py!}
+{!> ../../docs_src/app_testing/app_b/test_main.py!}
```
🕐❔ 👆 💪 👩💻 🚶♀️ ℹ 📨 & 👆 🚫 💭 ❔, 👆 💪 🔎 (🇺🇸🔍) ❔ ⚫️ `httpx`, ⚖️ ❔ ⚫️ ⏮️ `requests`, 🇸🇲 🔧 ⚓️ 🔛 📨' 🔧.
diff --git a/docs/en/data/external_links.yml b/docs/en/data/external_links.yml
index 63fd3d0cf..9e411a631 100644
--- a/docs/en/data/external_links.yml
+++ b/docs/en/data/external_links.yml
@@ -1,5 +1,9 @@
Articles:
English:
+ - author: Balthazar Rouberol
+ author_link: https://balthazar-rouberol.com
+ link: https://blog.balthazar-rouberol.com/how-to-profile-a-fastapi-asynchronous-request
+ title: How to profile a FastAPI asynchronous request
- author: Stephen Siegert - Neon
link: https://neon.tech/blog/deploy-a-serverless-fastapi-app-with-neon-postgres-and-aws-app-runner-at-any-scale
title: Deploy a Serverless FastAPI App with Neon Postgres and AWS App Runner at any scale
@@ -335,6 +339,10 @@ Articles:
link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築
Portuguese:
+ - author: Eduardo Mendes
+ author_link: https://bolha.us/@dunossauro
+ link: https://fastapidozero.dunossauro.com/
+ title: FastAPI do ZERO
- author: Jessica Temporal
author_link: https://jtemporal.com/socials
link: https://jtemporal.com/dicas-para-migrar-de-flask-para-fastapi-e-vice-versa/
diff --git a/docs/en/data/members.yml b/docs/en/data/members.yml
index 0069f8c75..a3a6b912d 100644
--- a/docs/en/data/members.yml
+++ b/docs/en/data/members.yml
@@ -11,6 +11,9 @@ members:
- login: svlandeg
avatar_url: https://avatars.githubusercontent.com/u/8796347
url: https://github.com/svlandeg
+- login: YuriiMotov
+ avatar_url: https://avatars.githubusercontent.com/u/109919500
+ url: https://github.com/YuriiMotov
- login: estebanx64
avatar_url: https://avatars.githubusercontent.com/u/10840422
url: https://github.com/estebanx64
diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml
index 3a767b6b1..1c83579e2 100644
--- a/docs/en/data/sponsors.yml
+++ b/docs/en/data/sponsors.yml
@@ -17,7 +17,7 @@ gold:
- url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge
title: Auth, user management and more for your B2B product
img: https://fastapi.tiangolo.com/img/sponsors/propelauth.png
- - url: https://docs.withcoherence.com/coherence-templates/full-stack-template/#fastapi?utm_medium=advertising&utm_source=fastapi&utm_campaign=docs
+ - url: https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=website
title: Coherence
img: https://fastapi.tiangolo.com/img/sponsors/coherence.png
- url: https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral
@@ -26,12 +26,12 @@ gold:
- url: https://zuplo.link/fastapi-gh
title: 'Zuplo: Scale, Protect, Document, and Monetize your FastAPI'
img: https://fastapi.tiangolo.com/img/sponsors/zuplo.png
- - url: https://fine.dev?ref=fastapibadge
- title: "Fine's AI FastAPI Workflow: Effortlessly Deploy and Integrate FastAPI into Your Project"
- img: https://fastapi.tiangolo.com/img/sponsors/fine.png
- url: https://liblab.com?utm_source=fastapi
title: liblab - Generate SDKs from FastAPI
img: https://fastapi.tiangolo.com/img/sponsors/liblab.png
+ - url: https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi
+ title: Deploy & scale any full-stack web app on Render. Focus on building apps, not infra.
+ img: https://fastapi.tiangolo.com/img/sponsors/render.svg
silver:
- url: https://github.com/deepset-ai/haystack/
title: Build powerful search from composable, open source building blocks
diff --git a/docs/en/data/sponsors_badge.yml b/docs/en/data/sponsors_badge.yml
index d8a41fbcb..7470b0238 100644
--- a/docs/en/data/sponsors_badge.yml
+++ b/docs/en/data/sponsors_badge.yml
@@ -30,3 +30,5 @@ logins:
- svix
- zuplo-oss
- Kong
+ - speakeasy-api
+ - jess-render
diff --git a/docs/en/docs/advanced/additional-responses.md b/docs/en/docs/advanced/additional-responses.md
index 674f0672c..03d48c2a7 100644
--- a/docs/en/docs/advanced/additional-responses.md
+++ b/docs/en/docs/advanced/additional-responses.md
@@ -18,7 +18,7 @@ But for those additional responses you have to make sure you return a `Response`
You can pass to your *path operation decorators* a parameter `responses`.
-It receives a `dict`, the keys are status codes for each response, like `200`, and the values are other `dict`s with the information for each of them.
+It receives a `dict`: the keys are status codes for each response (like `200`), and the values are other `dict`s with the information for each of them.
Each of those response `dict`s can have a key `model`, containing a Pydantic model, just like `response_model`.
@@ -26,9 +26,7 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod
For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:
-```Python hl_lines="18 22"
-{!../../../docs_src/additional_responses/tutorial001.py!}
-```
+{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
/// note
@@ -177,9 +175,7 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
-```Python hl_lines="19-24 28"
-{!../../../docs_src/additional_responses/tutorial002.py!}
-```
+{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
/// note
@@ -207,9 +203,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd
And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:
-```Python hl_lines="20-31"
-{!../../../docs_src/additional_responses/tutorial003.py!}
-```
+{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
It will all be combined and included in your OpenAPI, and shown in the API docs:
@@ -243,9 +237,7 @@ You can use that technique to reuse some predefined responses in your *path oper
For example:
-```Python hl_lines="13-17 26"
-{!../../../docs_src/additional_responses/tutorial004.py!}
-```
+{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
## More information about OpenAPI responses
diff --git a/docs/en/docs/advanced/additional-status-codes.md b/docs/en/docs/advanced/additional-status-codes.md
index 99ad72b53..077a00488 100644
--- a/docs/en/docs/advanced/additional-status-codes.md
+++ b/docs/en/docs/advanced/additional-status-codes.md
@@ -14,57 +14,7 @@ But you also want it to accept new items. And when the items didn't exist before
To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want:
-//// tab | Python 3.10+
-
-```Python hl_lines="4 25"
-{!> ../../../docs_src/additional_status_codes/tutorial001_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="4 25"
-{!> ../../../docs_src/additional_status_codes/tutorial001_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="4 26"
-{!> ../../../docs_src/additional_status_codes/tutorial001_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="2 23"
-{!> ../../../docs_src/additional_status_codes/tutorial001_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="4 25"
-{!> ../../../docs_src/additional_status_codes/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
/// warning
@@ -76,7 +26,7 @@ Make sure it has the data you want it to have, and that the values are valid JSO
///
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.responses import JSONResponse`.
diff --git a/docs/en/docs/advanced/advanced-dependencies.md b/docs/en/docs/advanced/advanced-dependencies.md
index f65e1b180..f933fd264 100644
--- a/docs/en/docs/advanced/advanced-dependencies.md
+++ b/docs/en/docs/advanced/advanced-dependencies.md
@@ -18,35 +18,7 @@ Not the class itself (which is already a callable), but an instance of that clas
To do that, we declare a method `__call__`:
-//// tab | Python 3.9+
-
-```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="11"
-{!> ../../../docs_src/dependencies/tutorial011_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
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.
@@ -54,35 +26,7 @@ In this case, this `__call__` is what **FastAPI** will use to check for addition
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
-//// tab | Python 3.9+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="8"
-{!> ../../../docs_src/dependencies/tutorial011_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="7"
-{!> ../../../docs_src/dependencies/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.
@@ -90,35 +34,7 @@ In this case, **FastAPI** won't ever touch or care about `__init__`, we will use
We could create an instance of this class with:
-//// tab | Python 3.9+
-
-```Python hl_lines="18"
-{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial011_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="16"
-{!> ../../../docs_src/dependencies/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.
@@ -134,35 +50,7 @@ checker(q="somequery")
...and pass whatever that returns as the value of the dependency in our *path operation function* as the parameter `fixed_content_included`:
-//// tab | Python 3.9+
-
-```Python hl_lines="22"
-{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="21"
-{!> ../../../docs_src/dependencies/tutorial011_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
/// tip
diff --git a/docs/en/docs/advanced/async-tests.md b/docs/en/docs/advanced/async-tests.md
index 580d9142c..8d6929222 100644
--- a/docs/en/docs/advanced/async-tests.md
+++ b/docs/en/docs/advanced/async-tests.md
@@ -32,15 +32,11 @@ For a simple example, let's consider a file structure similar to the one describ
The file `main.py` would have:
-```Python
-{!../../../docs_src/async_tests/main.py!}
-```
+{* ../../docs_src/async_tests/main.py *}
The file `test_main.py` would have the tests for `main.py`, it could look like this now:
-```Python
-{!../../../docs_src/async_tests/test_main.py!}
-```
+{* ../../docs_src/async_tests/test_main.py *}
## Run it
@@ -60,9 +56,7 @@ $ pytest
The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously:
-```Python hl_lines="7"
-{!../../../docs_src/async_tests/test_main.py!}
-```
+{* ../../docs_src/async_tests/test_main.py hl[7] *}
/// tip
@@ -72,9 +66,7 @@ Note that the test function is now `async def` instead of just `def` as before w
Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`.
-```Python hl_lines="9-12"
-{!../../../docs_src/async_tests/test_main.py!}
-```
+{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
This is the equivalent to:
@@ -102,6 +94,6 @@ As the testing function is now asynchronous, you can now also call (and `await`)
/// 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 5ff64016c..1f0d0fd9f 100644
--- a/docs/en/docs/advanced/behind-a-proxy.md
+++ b/docs/en/docs/advanced/behind-a-proxy.md
@@ -18,9 +18,7 @@ In this case, the original path `/app` would actually be served at `/api/v1/app`
Even though all your code is written assuming there's just `/app`.
-```Python hl_lines="6"
-{!../../../docs_src/behind_a_proxy/tutorial001.py!}
-```
+{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.
@@ -84,7 +82,7 @@ $ fastapi run main.py --root-path /api/v1
If you use Hypercorn, it also has the option `--root-path`.
-/// note | "Technical Details"
+/// note | Technical Details
The ASGI specification defines a `root_path` for this use case.
@@ -98,9 +96,7 @@ You can get the current `root_path` used by your application for each request, i
Here we are including it in the message just for demonstration purposes.
-```Python hl_lines="8"
-{!../../../docs_src/behind_a_proxy/tutorial001.py!}
-```
+{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
Then, if you start Uvicorn with:
@@ -127,9 +123,7 @@ The response would be something like:
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:
-```Python hl_lines="3"
-{!../../../docs_src/behind_a_proxy/tutorial002.py!}
-```
+{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn.
@@ -303,15 +297,13 @@ This is a more advanced use case. Feel free to skip it.
By default, **FastAPI** will create a `server` in the OpenAPI schema with the URL for the `root_path`.
-But you can also provide other alternative `servers`, for example if you want *the same* docs UI to interact with a staging and production environments.
+But you can also provide other alternative `servers`, for example if you want *the same* docs UI to interact with both a staging and a production environment.
If you pass a custom list of `servers` and there's a `root_path` (because your API lives behind a proxy), **FastAPI** will insert a "server" with this `root_path` at the beginning of the list.
For example:
-```Python hl_lines="4-7"
-{!../../../docs_src/behind_a_proxy/tutorial003.py!}
-```
+{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
Will generate an OpenAPI schema like:
@@ -358,9 +350,7 @@ The docs UI will interact with the server that you select.
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`:
-```Python hl_lines="9"
-{!../../../docs_src/behind_a_proxy/tutorial004.py!}
-```
+{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
and then it won't include it in the OpenAPI schema.
diff --git a/docs/en/docs/advanced/custom-response.md b/docs/en/docs/advanced/custom-response.md
index 79f755815..8268dd81a 100644
--- a/docs/en/docs/advanced/custom-response.md
+++ b/docs/en/docs/advanced/custom-response.md
@@ -30,9 +30,7 @@ This is because by default, FastAPI will inspect every item inside and make sure
But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class.
-```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001b.py!}
-```
+{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
/// info
@@ -57,9 +55,7 @@ To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
* Import `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*.
-```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial002.py!}
-```
+{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
/// info
@@ -77,9 +73,7 @@ As seen in [Return a Response directly](response-directly.md){.internal-link tar
The same example from above, returning an `HTMLResponse`, could look like:
-```Python hl_lines="2 7 19"
-{!../../../docs_src/custom_response/tutorial003.py!}
-```
+{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
/// warning
@@ -103,9 +97,7 @@ The `response_class` will then be used only to document the OpenAPI *path operat
For example, it could be something like:
-```Python hl_lines="7 21 23"
-{!../../../docs_src/custom_response/tutorial004.py!}
-```
+{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
@@ -121,7 +113,7 @@ Here are some of the available responses.
Keep in mind that you can use `Response` to return anything else, or even create a custom sub-class.
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.responses import HTMLResponse`.
@@ -142,11 +134,9 @@ It accepts the following parameters:
* `headers` - A `dict` of strings.
* `media_type` - A `str` giving the media type. E.g. `"text/html"`.
-FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the media_type and appending a charset for text types.
+FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types.
-```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
-```
+{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
### `HTMLResponse`
@@ -154,11 +144,9 @@ Takes some text or bytes and returns an HTML response, as you read above.
### `PlainTextResponse`
-Takes some text or bytes and returns an plain text response.
+Takes some text or bytes and returns a plain text response.
-```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial005.py!}
-```
+{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
### `JSONResponse`
@@ -192,9 +180,7 @@ This requires installing `ujson` for example with `pip install ujson`.
///
-```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001.py!}
-```
+{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
/// tip
@@ -208,18 +194,14 @@ Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default
You can return a `RedirectResponse` directly:
-```Python hl_lines="2 9"
-{!../../../docs_src/custom_response/tutorial006.py!}
-```
+{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
---
Or you can use it in the `response_class` parameter:
-```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial006b.py!}
-```
+{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
If you do that, then you can return the URL directly from your *path operation* function.
@@ -229,17 +211,13 @@ In this case, the `status_code` used will be the default one for the `RedirectRe
You can also use the `status_code` parameter combined with the `response_class` parameter:
-```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial006c.py!}
-```
+{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
### `StreamingResponse`
Takes an async generator or a normal generator/iterator and streams the response body.
-```Python hl_lines="2 14"
-{!../../../docs_src/custom_response/tutorial007.py!}
-```
+{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
#### Using `StreamingResponse` with file-like objects
@@ -249,9 +227,7 @@ That way, you don't have to read it all first in memory, and you can pass that g
This includes many libraries to interact with cloud storage, video processing, and others.
-```{ .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. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
@@ -273,22 +249,18 @@ Asynchronously streams a file as the response.
Takes a different set of arguments to instantiate than the other response types:
-* `path` - The filepath to the file to stream.
+* `path` - The file path to the file to stream.
* `headers` - Any custom headers to include, as a dictionary.
* `media_type` - A string giving the media type. If unset, the filename or path will be used to infer a media type.
* `filename` - If set, this will be included in the response `Content-Disposition`.
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
-```Python hl_lines="2 10"
-{!../../../docs_src/custom_response/tutorial009.py!}
-```
+{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
You can also use the `response_class` parameter:
-```Python hl_lines="2 8 10"
-{!../../../docs_src/custom_response/tutorial009b.py!}
-```
+{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
In this case, you can return the file path directly from your *path operation* function.
@@ -302,9 +274,7 @@ Let's say you want it to return indented and formatted JSON, so you want to use
You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`:
-```Python hl_lines="9-14 17"
-{!../../../docs_src/custom_response/tutorial009c.py!}
-```
+{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
Now instead of returning:
@@ -330,9 +300,7 @@ The parameter that defines this is `default_response_class`.
In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`.
-```Python hl_lines="2 4"
-{!../../../docs_src/custom_response/tutorial010.py!}
-```
+{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
/// tip
diff --git a/docs/en/docs/advanced/dataclasses.md b/docs/en/docs/advanced/dataclasses.md
index 252ab6fa5..2936c6d5d 100644
--- a/docs/en/docs/advanced/dataclasses.md
+++ b/docs/en/docs/advanced/dataclasses.md
@@ -4,9 +4,7 @@ FastAPI is built on top of **Pydantic**, and I have been showing you how to use
But FastAPI also supports using `dataclasses` the same way:
-```Python hl_lines="1 7-12 19-20"
-{!../../../docs_src/dataclasses/tutorial001.py!}
-```
+{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
This is still supported thanks to **Pydantic**, as it has internal support for `dataclasses`.
@@ -34,9 +32,7 @@ But if you have a bunch of dataclasses laying around, this is a nice trick to us
You can also use `dataclasses` in the `response_model` parameter:
-```Python hl_lines="1 7-13 19"
-{!../../../docs_src/dataclasses/tutorial002.py!}
-```
+{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
The dataclass will be automatically converted to a Pydantic dataclass.
@@ -52,9 +48,7 @@ In some cases, you might still have to use Pydantic's version of `dataclasses`.
In that case, you can simply swap the standard `dataclasses` with `pydantic.dataclasses`, which is a drop-in replacement:
-```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
-{!../../../docs_src/dataclasses/tutorial003.py!}
-```
+{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
1. We still import `field` from standard `dataclasses`.
diff --git a/docs/en/docs/advanced/events.md b/docs/en/docs/advanced/events.md
index 7fd934344..19465d891 100644
--- a/docs/en/docs/advanced/events.md
+++ b/docs/en/docs/advanced/events.md
@@ -30,9 +30,7 @@ Let's start with an example and then see it in detail.
We create an async function `lifespan()` with `yield` like this:
-```Python hl_lines="16 19"
-{!../../../docs_src/events/tutorial003.py!}
-```
+{* ../../docs_src/events/tutorial003.py hl[16,19] *}
Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.
@@ -50,9 +48,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷
The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
-```Python hl_lines="14-19"
-{!../../../docs_src/events/tutorial003.py!}
-```
+{* ../../docs_src/events/tutorial003.py hl[14:19] *}
The first part of the function, before the `yield`, will be executed **before** the application starts.
@@ -64,9 +60,7 @@ If you check, the function is decorated with an `@asynccontextmanager`.
That converts the function into something called an "**async context manager**".
-```Python hl_lines="1 13"
-{!../../../docs_src/events/tutorial003.py!}
-```
+{* ../../docs_src/events/tutorial003.py hl[1,13] *}
A **context manager** in Python is something that you can use in a `with` statement, for example, `open()` can be used as a context manager:
@@ -88,9 +82,7 @@ In our code example above, we don't use it directly, but we pass it to FastAPI f
The `lifespan` parameter of the `FastAPI` app takes an **async context manager**, so we can pass our new `lifespan` async context manager to it.
-```Python hl_lines="22"
-{!../../../docs_src/events/tutorial003.py!}
-```
+{* ../../docs_src/events/tutorial003.py hl[22] *}
## Alternative Events (deprecated)
@@ -112,9 +104,7 @@ These functions can be declared with `async def` or normal `def`.
To add a function that should be run before the application starts, declare it with the event `"startup"`:
-```Python hl_lines="8"
-{!../../../docs_src/events/tutorial001.py!}
-```
+{* ../../docs_src/events/tutorial001.py hl[8] *}
In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
@@ -126,9 +116,7 @@ And your application won't start receiving requests until all the `startup` even
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
-```Python hl_lines="6"
-{!../../../docs_src/events/tutorial002.py!}
-```
+{* ../../docs_src/events/tutorial002.py hl[6] *}
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md
index faa7c323f..fe4194ac7 100644
--- a/docs/en/docs/advanced/generate-clients.md
+++ b/docs/en/docs/advanced/generate-clients.md
@@ -32,21 +32,7 @@ There are also several other companies offering similar services that you can se
Let's start with a simple FastAPI application:
-//// tab | Python 3.9+
-
-```Python hl_lines="7-9 12-13 16-17 21"
-{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9-11 14-15 18 19 23"
-{!> ../../../docs_src/generate_clients/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.
@@ -151,21 +137,7 @@ In many cases your FastAPI app will be bigger, and you will probably use tags to
For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:
-//// tab | Python 3.9+
-
-```Python hl_lines="21 26 34"
-{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="23 28 36"
-{!> ../../../docs_src/generate_clients/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
### Generate a TypeScript Client with Tags
@@ -212,21 +184,7 @@ For example, here it is using the first tag (you will probably have only one tag
You can then pass that custom function to **FastAPI** as the `generate_unique_id_function` parameter:
-//// tab | Python 3.9+
-
-```Python hl_lines="6-7 10"
-{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="8-9 12"
-{!> ../../../docs_src/generate_clients/tutorial003.py!}
-```
-
-////
+{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
### Generate a TypeScript Client with Custom Operation IDs
@@ -251,7 +209,7 @@ We could download the OpenAPI JSON to a file `openapi.json` and then we could **
//// tab | Python
```Python
-{!> ../../../docs_src/generate_clients/tutorial004.py!}
+{!> ../../docs_src/generate_clients/tutorial004.py!}
```
////
@@ -259,7 +217,7 @@ We could download the OpenAPI JSON to a file `openapi.json` and then we could **
//// tab | Node.js
```Javascript
-{!> ../../../docs_src/generate_clients/tutorial004.js!}
+{!> ../../docs_src/generate_clients/tutorial004.js!}
```
////
diff --git a/docs/en/docs/advanced/middleware.md b/docs/en/docs/advanced/middleware.md
index 70415adca..1d40b1c8f 100644
--- a/docs/en/docs/advanced/middleware.md
+++ b/docs/en/docs/advanced/middleware.md
@@ -24,7 +24,7 @@ app = SomeASGIApp()
new_app = UnicornMiddleware(app, some_config="rainbow")
```
-But FastAPI (actually Starlette) provides a simpler way to do it that makes sure that the internal middlewares to handle server errors and custom exception handlers work properly.
+But FastAPI (actually Starlette) provides a simpler way to do it that makes sure that the internal middlewares handle server errors and custom exception handlers work properly.
For that, you use `app.add_middleware()` (as in the example for CORS).
@@ -43,7 +43,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
**FastAPI** includes several middlewares for common use cases, we'll see next how to use them.
-/// note | "Technical Details"
+/// note | Technical Details
For the next examples, you could also use `from starlette.middleware.something import SomethingMiddleware`.
@@ -55,19 +55,15 @@ For the next examples, you could also use `from starlette.middleware.something i
Enforces that all incoming requests must either be `https` or `wss`.
-Any incoming requests to `http` or `ws` will be redirected to the secure scheme instead.
+Any incoming request to `http` or `ws` will be redirected to the secure scheme instead.
-```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial001.py!}
-```
+{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
## `TrustedHostMiddleware`
Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.
-```Python hl_lines="2 6-8"
-{!../../../docs_src/advanced_middleware/tutorial002.py!}
-```
+{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
The following arguments are supported:
@@ -81,9 +77,7 @@ Handles GZip responses for any request that includes `"gzip"` in the `Accept-Enc
The middleware will handle both standard and streaming responses.
-```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial003.py!}
-```
+{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
The following arguments are supported:
diff --git a/docs/en/docs/advanced/openapi-callbacks.md b/docs/en/docs/advanced/openapi-callbacks.md
index 7fead2ed9..ca9065a89 100644
--- a/docs/en/docs/advanced/openapi-callbacks.md
+++ b/docs/en/docs/advanced/openapi-callbacks.md
@@ -31,9 +31,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query
This part is pretty normal, most of the code is probably already familiar to you:
-```Python hl_lines="9-13 36-53"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
-```
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
/// tip
@@ -92,9 +90,7 @@ Temporarily adopting this point of view (of the *external developer*) can help y
First create a new `APIRouter` that will contain one or more callbacks.
-```Python hl_lines="3 25"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
-```
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
### Create the callback *path operation*
@@ -105,9 +101,7 @@ It should look just like a normal FastAPI *path operation*:
* It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`.
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.
-```Python hl_lines="16-18 21-22 28-32"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
-```
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
There are 2 main differences from a normal *path operation*:
@@ -175,9 +169,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that
Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:
-```Python hl_lines="35"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
-```
+{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
/// tip
diff --git a/docs/en/docs/advanced/openapi-webhooks.md b/docs/en/docs/advanced/openapi-webhooks.md
index 5ee321e2a..97aaa41af 100644
--- a/docs/en/docs/advanced/openapi-webhooks.md
+++ b/docs/en/docs/advanced/openapi-webhooks.md
@@ -32,9 +32,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0`
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()`.
-```Python hl_lines="9-13 36-53"
-{!../../../docs_src/openapi_webhooks/tutorial001.py!}
-```
+{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.
diff --git a/docs/en/docs/advanced/path-operation-advanced-configuration.md b/docs/en/docs/advanced/path-operation-advanced-configuration.md
index c8874bad9..c4814ebd2 100644
--- a/docs/en/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/en/docs/advanced/path-operation-advanced-configuration.md
@@ -12,9 +12,7 @@ You can set the OpenAPI `operationId` to be used in your *path operation* with t
You would have to make sure that it is unique for each operation.
-```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
### Using the *path operation function* name as the operationId
@@ -22,9 +20,7 @@ If you want to use your APIs' function names as `operationId`s, you can iterate
You should do it after adding all your *path operations*.
-```Python hl_lines="2 12-21 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
/// tip
@@ -44,9 +40,7 @@ Even if they are in different modules (Python files).
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`:
-```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
## Advanced description from docstring
@@ -56,9 +50,7 @@ Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate
It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.
-```Python hl_lines="19-29"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
## Additional Responses
@@ -74,7 +66,7 @@ There's a whole chapter here in the documentation about it, you can read it at [
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.
-/// note | "Technical details"
+/// note | Technical details
In the OpenAPI specification it is called the Operation Object.
@@ -100,9 +92,7 @@ You can extend the OpenAPI schema for a *path operation* using the parameter `op
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):
-```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*.
@@ -149,9 +139,7 @@ For example, you could decide to read and validate the request with your own cod
You could do that with `openapi_extra`:
-```Python hl_lines="20-37 39-40"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
In this example, we didn't declare any Pydantic model. In fact, the request body is not even parsed as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
@@ -167,17 +155,13 @@ For example, in this application we don't use FastAPI's integrated functionality
//// tab | Pydantic v2
-```Python hl_lines="17-22 24"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
////
//// tab | Pydantic v1
-```Python hl_lines="17-22 24"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
////
@@ -195,17 +179,13 @@ And then in our code, we parse that YAML content directly, and then we are again
//// tab | Pydantic v2
-```Python hl_lines="26-33"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
////
//// tab | Pydantic v1
-```Python hl_lines="26-33"
-{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
-```
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
////
diff --git a/docs/en/docs/advanced/response-change-status-code.md b/docs/en/docs/advanced/response-change-status-code.md
index b88d74a8a..6d3f9f3e8 100644
--- a/docs/en/docs/advanced/response-change-status-code.md
+++ b/docs/en/docs/advanced/response-change-status-code.md
@@ -20,9 +20,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set the `status_code` in that *temporal* response object.
-```Python hl_lines="1 9 12"
-{!../../../docs_src/response_change_status_code/tutorial001.py!}
-```
+{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
diff --git a/docs/en/docs/advanced/response-cookies.md b/docs/en/docs/advanced/response-cookies.md
index 85e423f42..f6d17f35d 100644
--- a/docs/en/docs/advanced/response-cookies.md
+++ b/docs/en/docs/advanced/response-cookies.md
@@ -6,9 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set cookies in that *temporal* response object.
-```Python hl_lines="1 8-9"
-{!../../../docs_src/response_cookies/tutorial002.py!}
-```
+{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@@ -26,9 +24,7 @@ To do that, you can create a response as described in [Return a Response Directl
Then set Cookies in it, and then return it:
-```Python hl_lines="10-12"
-{!../../../docs_src/response_cookies/tutorial001.py!}
-```
+{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
/// tip
@@ -42,7 +38,7 @@ And also that you are not sending any data that should have been filtered by a `
### More info
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.responses import Response` or `from starlette.responses import JSONResponse`.
diff --git a/docs/en/docs/advanced/response-directly.md b/docs/en/docs/advanced/response-directly.md
index 2251659c5..691b1e7cd 100644
--- a/docs/en/docs/advanced/response-directly.md
+++ b/docs/en/docs/advanced/response-directly.md
@@ -28,17 +28,15 @@ This gives you a lot of flexibility. You can return any data type, override any
## Using the `jsonable_encoder` in a `Response`
-Because **FastAPI** doesn't do any change to a `Response` you return, you have to make sure its contents are ready for it.
+Because **FastAPI** doesn't make any changes to a `Response` you return, you have to make sure its contents are ready for it.
For example, you cannot put a Pydantic model in a `JSONResponse` without first converting it to a `dict` with all the data types (like `datetime`, `UUID`, etc) converted to JSON-compatible types.
For those cases, you can use the `jsonable_encoder` to convert your data before passing it to a response:
-```Python hl_lines="6-7 21-22"
-{!../../../docs_src/response_directly/tutorial001.py!}
-```
+{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.responses import JSONResponse`.
@@ -56,9 +54,7 @@ Let's say that you want to return an ../../../docs_src/security/tutorial006_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="2 7 11"
-{!> ../../../docs_src/security/tutorial006_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="2 6 10"
-{!> ../../../docs_src/security/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
@@ -68,35 +40,7 @@ To handle that, we first convert the `username` and `password` to `bytes` encodi
Then we can use `secrets.compare_digest()` to ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`.
-//// tab | Python 3.9+
-
-```Python hl_lines="1 12-24"
-{!> ../../../docs_src/security/tutorial007_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1 12-24"
-{!> ../../../docs_src/security/tutorial007_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="1 11-21"
-{!> ../../../docs_src/security/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
This would be similar to:
@@ -144,7 +88,7 @@ And then they can try again knowing that it's probably something more similar to
#### 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 would get just one extra correct letter at a time.
+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.
@@ -160,32 +104,4 @@ That way, using `secrets.compare_digest()` in your application code, it will be
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:
-//// tab | Python 3.9+
-
-```Python hl_lines="26-30"
-{!> ../../../docs_src/security/tutorial007_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="26-30"
-{!> ../../../docs_src/security/tutorial007_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="23-27"
-{!> ../../../docs_src/security/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
diff --git a/docs/en/docs/advanced/security/oauth2-scopes.md b/docs/en/docs/advanced/security/oauth2-scopes.md
index ff52d7bb8..4cb0b39bc 100644
--- a/docs/en/docs/advanced/security/oauth2-scopes.md
+++ b/docs/en/docs/advanced/security/oauth2-scopes.md
@@ -62,71 +62,7 @@ For OAuth2 they are just strings.
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:
-//// tab | Python 3.10+
-
-```Python hl_lines="5 9 13 47 65 106 108-116 122-125 129-135 140 156"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="2 5 9 13 48 66 107 109-117 123-126 130-136 141 157"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="4 8 12 46 64 105 107-115 121-124 128-134 139 155"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:125,129:135,140,156] *}
Now let's review those changes step by step.
@@ -136,71 +72,7 @@ The first change is that now we are declaring the OAuth2 security scheme with tw
The `scopes` parameter receives a `dict` with each scope as a key and the description as the value:
-//// tab | Python 3.10+
-
-```Python hl_lines="63-66"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="63-66"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="64-67"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="62-65"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="63-66"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="63-66"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *}
Because we are now declaring those scopes, they will show up in the API docs when you log-in/authorize.
@@ -226,71 +98,7 @@ But in your application, for security, you should make sure you only add the sco
///
-//// tab | Python 3.10+
-
-```Python hl_lines="156"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="156"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="157"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="155"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="156"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="156"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[156] *}
## Declare scopes in *path operations* and dependencies
@@ -316,73 +124,9 @@ We are doing it here to demonstrate how **FastAPI** handles scopes declared at d
///
-//// tab | Python 3.10+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,140,171] *}
-```Python hl_lines="5 140 171"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="5 140 171"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="5 141 172"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="4 139 168"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="5 140 169"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="5 140 169"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
-
-/// info | "Technical Details"
+/// info | Technical Details
`Security` is actually a subclass of `Depends`, and it has just one extra parameter that we'll see later.
@@ -406,71 +150,7 @@ We also declare a special parameter of type `SecurityScopes`, imported from `fas
This `SecurityScopes` class is similar to `Request` (`Request` was used to get the request object directly).
-//// tab | Python 3.10+
-
-```Python hl_lines="9 106"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="9 106"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9 107"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="8 105"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="9 106"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="9 106"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
## Use the `scopes`
@@ -484,71 +164,7 @@ We create an `HTTPException` that we can reuse (`raise`) later at several points
In this exception, we include the scopes required (if any) as a string separated by spaces (using `scope_str`). We put that string containing the scopes in the `WWW-Authenticate` header (this is part of the spec).
-//// tab | Python 3.10+
-
-```Python hl_lines="106 108-116"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="106 108-116"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="107 109-117"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="105 107-115"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="106 108-116"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="106 108-116"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}
## Verify the `username` and data shape
@@ -564,71 +180,7 @@ 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.
-//// tab | Python 3.10+
-
-```Python hl_lines="47 117-128"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="47 117-128"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="48 118-129"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="46 116-127"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="47 117-128"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="47 117-128"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:128] *}
## Verify the `scopes`
@@ -636,71 +188,7 @@ We now verify that all the scopes required, by this dependency and all the depen
For this, we use `security_scopes.scopes`, that contains a `list` with all these scopes as `str`.
-//// tab | Python 3.10+
-
-```Python hl_lines="129-135"
-{!> ../../../docs_src/security/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="129-135"
-{!> ../../../docs_src/security/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="130-136"
-{!> ../../../docs_src/security/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="128-134"
-{!> ../../../docs_src/security/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="129-135"
-{!> ../../../docs_src/security/tutorial005_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="129-135"
-{!> ../../../docs_src/security/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial005_an_py310.py hl[129:135] *}
## Dependency tree and scopes
@@ -769,7 +257,7 @@ But if you are building an OAuth2 application that others would connect to (i.e.
The most common is the implicit flow.
-The most secure is the code flow, but is more complex to implement as it requires more steps. As it is more complex, many providers end up suggesting the implicit flow.
+The most secure is the code flow, but it's more complex to implement as it requires more steps. As it is more complex, many providers end up suggesting the implicit flow.
/// note
diff --git a/docs/en/docs/advanced/settings.md b/docs/en/docs/advanced/settings.md
index 22bf7de20..01810c438 100644
--- a/docs/en/docs/advanced/settings.md
+++ b/docs/en/docs/advanced/settings.md
@@ -63,7 +63,7 @@ You can use all the same validation features and tools you use for Pydantic mode
//// tab | Pydantic v2
```Python hl_lines="2 5-8 11"
-{!> ../../../docs_src/settings/tutorial001.py!}
+{!> ../../docs_src/settings/tutorial001.py!}
```
////
@@ -77,7 +77,7 @@ In Pydantic v1 you would import `BaseSettings` directly from `pydantic` instead
///
```Python hl_lines="2 5-8 11"
-{!> ../../../docs_src/settings/tutorial001_pv1.py!}
+{!> ../../docs_src/settings/tutorial001_pv1.py!}
```
////
@@ -97,7 +97,7 @@ Next it will convert and validate the data. So, when you use that `settings` obj
Then you can use the new `settings` object in your application:
```Python hl_lines="18-20"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
### Run the server
@@ -133,13 +133,13 @@ You could put those settings in another module file as you saw in [Bigger Applic
For example, you could have a file `config.py` with:
```Python
-{!../../../docs_src/settings/app01/config.py!}
+{!../../docs_src/settings/app01/config.py!}
```
And then use it in a file `main.py`:
```Python hl_lines="3 11-13"
-{!../../../docs_src/settings/app01/main.py!}
+{!../../docs_src/settings/app01/main.py!}
```
/// tip
@@ -159,7 +159,7 @@ This could be especially useful during testing, as it's very easy to override a
Coming from the previous example, your `config.py` file could look like:
```Python hl_lines="10"
-{!../../../docs_src/settings/app02/config.py!}
+{!../../docs_src/settings/app02/config.py!}
```
Notice that now we don't create a default instance `settings = Settings()`.
@@ -171,7 +171,7 @@ Now we create a dependency that returns a new `config.Settings()`.
//// tab | Python 3.9+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -179,7 +179,7 @@ Now we create a dependency that returns a new `config.Settings()`.
//// tab | Python 3.8+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
@@ -193,7 +193,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="5 11-12"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -211,7 +211,7 @@ And then we can require it from the *path operation function* as a dependency an
//// tab | Python 3.9+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -219,7 +219,7 @@ And then we can require it from the *path operation function* as a dependency an
//// tab | Python 3.8+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
@@ -233,7 +233,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="16 18-20"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -243,7 +243,7 @@ Prefer to use the `Annotated` version if possible.
Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
```Python hl_lines="9-10 13 21"
-{!../../../docs_src/settings/app02/test_main.py!}
+{!../../docs_src/settings/app02/test_main.py!}
```
In the dependency override we set a new value for the `admin_email` when creating the new `Settings` object, and then we return that new object.
@@ -288,7 +288,7 @@ And then update your `config.py` with:
//// tab | Pydantic v2
```Python hl_lines="9"
-{!> ../../../docs_src/settings/app03_an/config.py!}
+{!> ../../docs_src/settings/app03_an/config.py!}
```
/// tip
@@ -302,7 +302,7 @@ The `model_config` attribute is used just for Pydantic configuration. You can re
//// tab | Pydantic v1
```Python hl_lines="9-10"
-{!> ../../../docs_src/settings/app03_an/config_pv1.py!}
+{!> ../../docs_src/settings/app03_an/config_pv1.py!}
```
/// tip
@@ -347,7 +347,7 @@ But as we are using the `@lru_cache` decorator on top, the `Settings` object wil
//// tab | Python 3.9+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an_py39/main.py!}
+{!> ../../docs_src/settings/app03_an_py39/main.py!}
```
////
@@ -355,7 +355,7 @@ But as we are using the `@lru_cache` decorator on top, the `Settings` object wil
//// tab | Python 3.8+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an/main.py!}
+{!> ../../docs_src/settings/app03_an/main.py!}
```
////
@@ -369,12 +369,12 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="1 10"
-{!> ../../../docs_src/settings/app03/main.py!}
+{!> ../../docs_src/settings/app03/main.py!}
```
////
-Then for any subsequent calls 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.
+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
diff --git a/docs/en/docs/advanced/sub-applications.md b/docs/en/docs/advanced/sub-applications.md
index 568a9deca..48e329fc1 100644
--- a/docs/en/docs/advanced/sub-applications.md
+++ b/docs/en/docs/advanced/sub-applications.md
@@ -10,9 +10,7 @@ If you need to have two independent FastAPI applications, with their own indepen
First, create the main, top-level, **FastAPI** application, and its *path operations*:
-```Python hl_lines="3 6-8"
-{!../../../docs_src/sub_applications/tutorial001.py!}
-```
+{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
### Sub-application
@@ -20,9 +18,7 @@ Then, create your sub-application, and its *path operations*.
This sub-application is just another standard FastAPI application, but this is the one that will be "mounted":
-```Python hl_lines="11 14-16"
-{!../../../docs_src/sub_applications/tutorial001.py!}
-```
+{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
### Mount the sub-application
@@ -30,9 +26,7 @@ In your top-level application, `app`, mount the sub-application, `subapi`.
In this case, it will be mounted at the path `/subapi`:
-```Python hl_lines="11 19"
-{!../../../docs_src/sub_applications/tutorial001.py!}
-```
+{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
### Check the automatic API docs
diff --git a/docs/en/docs/advanced/templates.md b/docs/en/docs/advanced/templates.md
index 416540ba4..76f0ef1de 100644
--- a/docs/en/docs/advanced/templates.md
+++ b/docs/en/docs/advanced/templates.md
@@ -28,7 +28,7 @@ $ pip install jinja2
* Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
```Python hl_lines="4 11 15-18"
-{!../../../docs_src/templates/tutorial001.py!}
+{!../../docs_src/templates/tutorial001.py!}
```
/// note
@@ -45,7 +45,7 @@ By declaring `response_class=HTMLResponse` the docs UI will be able to know that
///
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.templating import Jinja2Templates`.
@@ -58,7 +58,7 @@ You could also use `from starlette.templating import Jinja2Templates`.
Then you can write a template at `templates/item.html` with, for example:
```jinja hl_lines="7"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
### Template Context Values
@@ -112,13 +112,13 @@ For example, with an ID of `42`, this would render:
You can also use `url_for()` inside of the template, and use it, for example, with the `StaticFiles` you mounted with the `name="static"`.
```jinja hl_lines="4"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
In this example, it would link to a CSS file at `static/styles.css` with:
```CSS hl_lines="4"
-{!../../../docs_src/templates/static/styles.css!}
+{!../../docs_src/templates/static/styles.css!}
```
And because you are using `StaticFiles`, that CSS file would be served automatically by your **FastAPI** application at the URL `/static/styles.css`.
diff --git a/docs/en/docs/advanced/testing-database.md b/docs/en/docs/advanced/testing-database.md
deleted file mode 100644
index 974cf4caa..000000000
--- a/docs/en/docs/advanced/testing-database.md
+++ /dev/null
@@ -1,111 +0,0 @@
-# Testing a Database
-
-/// info
-
-These docs are about to be updated. 🎉
-
-The current version assumes Pydantic v1, and SQLAlchemy versions less than 2.0.
-
-The new docs will include Pydantic v2 and will use SQLModel (which is also based on SQLAlchemy) once it is updated to use Pydantic v2 as well.
-
-///
-
-You can use the same dependency overrides from [Testing Dependencies with Overrides](testing-dependencies.md){.internal-link target=_blank} to alter a database for testing.
-
-You could want to set up a different database for testing, rollback the data after the tests, pre-fill it with some testing data, etc.
-
-The main idea is exactly the same you saw in that previous chapter.
-
-## Add tests for the SQL app
-
-Let's update the example from [SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank} to use a testing database.
-
-All the app code is the same, you can go back to that chapter check how it was.
-
-The only changes here are in the new testing file.
-
-Your normal dependency `get_db()` would return a database session.
-
-In the test, you could use a dependency override to return your *custom* database session instead of the one that would be used normally.
-
-In this example we'll create a temporary database only for the tests.
-
-## File structure
-
-We create a new file at `sql_app/tests/test_sql_app.py`.
-
-So the new file structure looks like:
-
-``` hl_lines="9-11"
-.
-└── sql_app
- ├── __init__.py
- ├── crud.py
- ├── database.py
- ├── main.py
- ├── models.py
- ├── schemas.py
- └── tests
- ├── __init__.py
- └── test_sql_app.py
-```
-
-## Create the new database session
-
-First, we create a new database session with the new database.
-
-We'll use an in-memory database that persists during the tests instead of the local file `sql_app.db`.
-
-But the rest of the session code is more or less the same, we just copy it.
-
-```Python hl_lines="8-13"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-/// tip
-
-You could reduce duplication in that code by putting it in a function and using it from both `database.py` and `tests/test_sql_app.py`.
-
-For simplicity and to focus on the specific testing code, we are just copying it.
-
-///
-
-## Create the database
-
-Because now we are going to use a new database in a new file, we need to make sure we create the database with:
-
-```Python
-Base.metadata.create_all(bind=engine)
-```
-
-That is normally called in `main.py`, but the line in `main.py` uses the database file `sql_app.db`, and we need to make sure we create `test.db` for the tests.
-
-So we add that line here, with the new file.
-
-```Python hl_lines="16"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-## Dependency override
-
-Now we create the dependency override and add it to the overrides for our app.
-
-```Python hl_lines="19-24 27"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-/// tip
-
-The code for `override_get_db()` is almost exactly the same as for `get_db()`, but in `override_get_db()` we use the `TestingSessionLocal` for the testing database instead.
-
-///
-
-## Test the app
-
-Then we can just test the app as normally.
-
-```Python hl_lines="32-47"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-And all the modifications we made in the database during the tests will be in the `test.db` database instead of the main `sql_app.db`.
diff --git a/docs/en/docs/advanced/testing-dependencies.md b/docs/en/docs/advanced/testing-dependencies.md
index 92e25f88d..1cc4313a1 100644
--- a/docs/en/docs/advanced/testing-dependencies.md
+++ b/docs/en/docs/advanced/testing-dependencies.md
@@ -31,7 +31,7 @@ And then **FastAPI** will call that override instead of the original dependency.
//// tab | Python 3.10+
```Python hl_lines="26-27 30"
-{!> ../../../docs_src/dependency_testing/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an_py310.py!}
```
////
@@ -39,7 +39,7 @@ And then **FastAPI** will call that override instead of the original dependency.
//// tab | Python 3.9+
```Python hl_lines="28-29 32"
-{!> ../../../docs_src/dependency_testing/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an_py39.py!}
```
////
@@ -47,7 +47,7 @@ And then **FastAPI** will call that override instead of the original dependency.
//// tab | Python 3.8+
```Python hl_lines="29-30 33"
-{!> ../../../docs_src/dependency_testing/tutorial001_an.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an.py!}
```
////
@@ -61,7 +61,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="24-25 28"
-{!> ../../../docs_src/dependency_testing/tutorial001_py310.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_py310.py!}
```
////
@@ -75,7 +75,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="28-29 32"
-{!> ../../../docs_src/dependency_testing/tutorial001.py!}
+{!> ../../docs_src/dependency_testing/tutorial001.py!}
```
////
diff --git a/docs/en/docs/advanced/testing-events.md b/docs/en/docs/advanced/testing-events.md
index b24a2ccfe..f48907c7c 100644
--- a/docs/en/docs/advanced/testing-events.md
+++ b/docs/en/docs/advanced/testing-events.md
@@ -3,5 +3,5 @@
When you need your event handlers (`startup` and `shutdown`) to run in your tests, you can use the `TestClient` with a `with` statement:
```Python hl_lines="9-12 20-24"
-{!../../../docs_src/app_testing/tutorial003.py!}
+{!../../docs_src/app_testing/tutorial003.py!}
```
diff --git a/docs/en/docs/advanced/testing-websockets.md b/docs/en/docs/advanced/testing-websockets.md
index 6c071bc19..60dfdc343 100644
--- a/docs/en/docs/advanced/testing-websockets.md
+++ b/docs/en/docs/advanced/testing-websockets.md
@@ -4,9 +4,7 @@ You can use the same `TestClient` to test WebSockets.
For this, you use the `TestClient` in a `with` statement, connecting to the WebSocket:
-```Python hl_lines="27-31"
-{!../../../docs_src/app_testing/tutorial002.py!}
-```
+{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
/// note
diff --git a/docs/en/docs/advanced/using-request-directly.md b/docs/en/docs/advanced/using-request-directly.md
index 5473db5cb..2f88c8f20 100644
--- a/docs/en/docs/advanced/using-request-directly.md
+++ b/docs/en/docs/advanced/using-request-directly.md
@@ -29,9 +29,7 @@ Let's imagine you want to get the client's IP address/host inside of your *path
For that you need to access the request directly.
-```Python hl_lines="1 7-8"
-{!../../../docs_src/using_request_directly/tutorial001.py!}
-```
+{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
By declaring a *path operation function* parameter with the type being the `Request` **FastAPI** will know to pass the `Request` in that parameter.
@@ -49,7 +47,7 @@ The same way, you can declare any other parameter as normally, and additionally,
You can read more details about the `Request` object in the official Starlette documentation site.
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.requests import Request`.
diff --git a/docs/en/docs/advanced/websockets.md b/docs/en/docs/advanced/websockets.md
index 44c6c7428..ee8e901df 100644
--- a/docs/en/docs/advanced/websockets.md
+++ b/docs/en/docs/advanced/websockets.md
@@ -38,19 +38,15 @@ In production you would have one of the options above.
But it's the simplest way to focus on the server-side of WebSockets and have a working example:
-```Python hl_lines="2 6-38 41-43"
-{!../../../docs_src/websockets/tutorial001.py!}
-```
+{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
## Create a `websocket`
In your **FastAPI** application, create a `websocket`:
-```Python hl_lines="1 46-47"
-{!../../../docs_src/websockets/tutorial001.py!}
-```
+{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.websockets import WebSocket`.
@@ -62,9 +58,7 @@ You could also use `from starlette.websockets import WebSocket`.
In your WebSocket route you can `await` for messages and send messages.
-```Python hl_lines="48-52"
-{!../../../docs_src/websockets/tutorial001.py!}
-```
+{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
You can receive and send binary, text, and JSON data.
@@ -115,57 +109,7 @@ In WebSocket endpoints you can import from `fastapi` and use:
They work the same way as for other FastAPI endpoints/*path operations*:
-//// tab | Python 3.10+
-
-```Python hl_lines="68-69 82"
-{!> ../../../docs_src/websockets/tutorial002_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="68-69 82"
-{!> ../../../docs_src/websockets/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="69-70 83"
-{!> ../../../docs_src/websockets/tutorial002_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="66-67 79"
-{!> ../../../docs_src/websockets/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="68-69 81"
-{!> ../../../docs_src/websockets/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
/// info
@@ -210,21 +154,7 @@ With that you can connect the WebSocket and then send and receive messages:
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.
-//// tab | Python 3.9+
-
-```Python hl_lines="79-81"
-{!> ../../../docs_src/websockets/tutorial003_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="81-83"
-{!> ../../../docs_src/websockets/tutorial003.py!}
-```
-
-////
+{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
To try it out:
diff --git a/docs/en/docs/advanced/wsgi.md b/docs/en/docs/advanced/wsgi.md
index f07609ed6..296eb1364 100644
--- a/docs/en/docs/advanced/wsgi.md
+++ b/docs/en/docs/advanced/wsgi.md
@@ -12,9 +12,7 @@ Then wrap the WSGI (e.g. Flask) app with the middleware.
And then mount that under a path.
-```Python hl_lines="2-3 23"
-{!../../../docs_src/wsgi/tutorial001.py!}
-```
+{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
## Check it
diff --git a/docs/en/docs/alternatives.md b/docs/en/docs/alternatives.md
index e98c0475a..326f0dbe1 100644
--- a/docs/en/docs/alternatives.md
+++ b/docs/en/docs/alternatives.md
@@ -36,7 +36,7 @@ Django REST Framework was created by Tom Christie. The same creator of Starlette
///
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Have an automatic API documentation web user interface.
@@ -56,7 +56,7 @@ This decoupling of parts, and being a "microframework" that could be extended to
Given the simplicity of Flask, it seemed like a good match for building APIs. The next thing to find was a "Django REST Framework" for Flask.
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Be a micro-framework. Making it easy to mix and match the tools and parts needed.
@@ -98,7 +98,7 @@ def read_url():
See the similarities in `requests.get(...)` and `@app.get(...)`.
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
* Have a simple and intuitive API.
* Use HTTP method names (operations) directly, in a straightforward and intuitive way.
@@ -118,7 +118,7 @@ At some point, Swagger was given to the Linux Foundation, to be renamed OpenAPI.
That's why when talking about version 2.0 it's common to say "Swagger", and for version 3+ "OpenAPI".
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Adopt and use an open standard for API specifications, instead of a custom schema.
@@ -147,7 +147,7 @@ These features are what Marshmallow was built to provide. It is a great library,
But it was created before there existed Python type hints. So, to define every schema you need to use specific utils and classes provided by Marshmallow.
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Use code to define "schemas" that provide data types and validation, automatically.
@@ -169,7 +169,7 @@ Webargs was created by the same Marshmallow developers.
///
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Have automatic validation of incoming request data.
@@ -199,7 +199,7 @@ APISpec was created by the same Marshmallow developers.
///
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Support the open standard for APIs, OpenAPI.
@@ -231,7 +231,7 @@ Flask-apispec was created by the same Marshmallow developers.
///
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Generate the OpenAPI schema automatically, from the same code that defines serialization and validation.
@@ -251,7 +251,7 @@ But as TypeScript data is not preserved after compilation to JavaScript, it cann
It can't handle nested models very well. So, if the JSON body in the request is a JSON object that has inner fields that in turn are nested JSON objects, it cannot be properly documented and validated.
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Use Python types to have great editor support.
@@ -263,7 +263,7 @@ Have a powerful dependency injection system. Find a way to minimize code repetit
It was one of the first extremely fast Python frameworks based on `asyncio`. It was made to be very similar to Flask.
-/// note | "Technical Details"
+/// note | Technical Details
It used `uvloop` instead of the default Python `asyncio` loop. That's what made it so fast.
@@ -271,7 +271,7 @@ It clearly inspired Uvicorn and Starlette, that are currently faster than Sanic
///
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Find a way to have a crazy performance.
@@ -287,7 +287,7 @@ It is designed to have functions that receive two parameters, one "request" and
So, data validation, serialization, and documentation, have to be done in code, not automatically. Or they have to be implemented as a framework on top of Falcon, like Hug. This same distinction happens in other frameworks that are inspired by Falcon's design, of having one request object and one response object as parameters.
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Find ways to get great performance.
@@ -313,7 +313,7 @@ The dependency injection system requires pre-registration of the dependencies an
Routes are declared in a single place, using functions declared in other places (instead of using decorators that can be placed right on top of the function that handles the endpoint). This is closer to how Django does it than to how Flask (and Starlette) does it. It separates in the code things that are relatively tightly coupled.
-/// check | "Inspired **FastAPI** to"
+/// check | Inspired **FastAPI** to
Define extra validations for data types using the "default" value of model attributes. This improves editor support, and it was not available in Pydantic before.
@@ -321,7 +321,7 @@ This actually inspired updating parts of Pydantic, to support the same validatio
///
-### 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.
@@ -341,7 +341,7 @@ Hug was created by Timothy Crosley, the same creator of Platform.sh
* Porter
-* Coherence
+* Coherence
+* Render
diff --git a/docs/en/docs/deployment/concepts.md b/docs/en/docs/deployment/concepts.md
index 69ee71a73..e71a7487a 100644
--- a/docs/en/docs/deployment/concepts.md
+++ b/docs/en/docs/deployment/concepts.md
@@ -257,7 +257,7 @@ But in most cases, you will want to perform these steps only **once**.
So, you will want to have a **single process** to perform those **previous steps**, before starting the application.
-And you will have to make sure that it's a single process running those previous steps *even* if afterwards, you start **multiple processes** (multiple workers) for the application itself. If those steps were run by **multiple processes**, they would **duplicate** the work by running it on **parallel**, and if the steps were something delicate like a database migration, they could cause conflicts with each other.
+And you will have to make sure that it's a single process running those previous steps *even* if afterwards, you start **multiple processes** (multiple workers) for the application itself. If those steps were run by **multiple processes**, they would **duplicate** the work by running it in **parallel**, and if the steps were something delicate like a database migration, they could cause conflicts with each other.
Of course, there are some cases where there's no problem in running the previous steps multiple times, in that case, it's a lot easier to handle.
diff --git a/docs/en/docs/deployment/docker.md b/docs/en/docs/deployment/docker.md
index 2d832a238..b106f7ac3 100644
--- a/docs/en/docs/deployment/docker.md
+++ b/docs/en/docs/deployment/docker.md
@@ -615,6 +615,6 @@ Using container systems (e.g. with **Docker** and **Kubernetes**) it becomes fai
* Memory
* Previous steps before starting
-In most cases, you probably won't want to use any base image, and instead **build a container image from scratch** one based on the official Python Docker image.
+In most cases, you probably won't want to use any base image, and instead **build a container image from scratch** based on the official Python Docker image.
Taking care of the **order** of instructions in the `Dockerfile` and the **Docker cache** you can **minimize build times**, to maximize your productivity (and avoid boredom). 😎
diff --git a/docs/en/docs/deployment/server-workers.md b/docs/en/docs/deployment/server-workers.md
index 5e369e071..622c10a30 100644
--- a/docs/en/docs/deployment/server-workers.md
+++ b/docs/en/docs/deployment/server-workers.md
@@ -139,7 +139,7 @@ From the list of deployment concepts from above, using workers would mainly help
## Containers and Docker
-In the next chapter about [FastAPI in Containers - Docker](docker.md){.internal-link target=_blank} I'll tell some strategies you could use to handle the other **deployment concepts**.
+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**.
diff --git a/docs/en/docs/environment-variables.md b/docs/en/docs/environment-variables.md
index 78e82d5af..43dd06add 100644
--- a/docs/en/docs/environment-variables.md
+++ b/docs/en/docs/environment-variables.md
@@ -243,8 +243,6 @@ This way, when you type `python` in the terminal, the system will find the Pytho
////
-This way, when you type `python` in the terminal, the system will find the Python program in `/opt/custompython/bin` (the last directory) and use that one.
-
So, if you type:
-
-## More info
-
-You can read more about `encode/databases` at its GitHub page.
diff --git a/docs/en/docs/how-to/conditional-openapi.md b/docs/en/docs/how-to/conditional-openapi.md
index add16fbec..bd6cad9a8 100644
--- a/docs/en/docs/how-to/conditional-openapi.md
+++ b/docs/en/docs/how-to/conditional-openapi.md
@@ -29,9 +29,7 @@ You can easily use the same Pydantic settings to configure your generated OpenAP
For example:
-```Python hl_lines="6 11"
-{!../../../docs_src/conditional_openapi/tutorial001.py!}
-```
+{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
Here we declare the setting `openapi_url` with the same default of `"/openapi.json"`.
diff --git a/docs/en/docs/how-to/configure-swagger-ui.md b/docs/en/docs/how-to/configure-swagger-ui.md
index 108afb929..a8a8de48f 100644
--- a/docs/en/docs/how-to/configure-swagger-ui.md
+++ b/docs/en/docs/how-to/configure-swagger-ui.md
@@ -1,6 +1,6 @@
# Configure Swagger UI
-You can configure some extra Swagger UI parameters.
+You can configure some extra Swagger UI parameters.
To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.
@@ -18,9 +18,7 @@ Without changing the settings, syntax highlighting is enabled by default:
But you can disable it by setting `syntaxHighlight` to `False`:
-```Python hl_lines="3"
-{!../../../docs_src/configure_swagger_ui/tutorial001.py!}
-```
+{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
...and then Swagger UI won't show the syntax highlighting anymore:
@@ -30,9 +28,7 @@ But you can disable it by setting `syntaxHighlight` to `False`:
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
-```Python hl_lines="3"
-{!../../../docs_src/configure_swagger_ui/tutorial002.py!}
-```
+{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
That configuration would change the syntax highlighting color theme:
@@ -44,21 +40,17 @@ FastAPI includes some default configuration parameters appropriate for most of t
It includes these default configurations:
-```Python
-{!../../../fastapi/openapi/docs.py[ln:7-23]!}
-```
+{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
-```Python hl_lines="3"
-{!../../../docs_src/configure_swagger_ui/tutorial003.py!}
-```
+{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
## Other Swagger UI Parameters
-To see all the other possible configurations you can use, read the official docs for Swagger UI parameters.
+To see all the other possible configurations you can use, read the official docs for Swagger UI parameters.
## JavaScript-only settings
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 0c766d3e4..f717c98fa 100644
--- a/docs/en/docs/how-to/custom-docs-ui-assets.md
+++ b/docs/en/docs/how-to/custom-docs-ui-assets.md
@@ -18,9 +18,7 @@ The first step is to disable the automatic docs, as by default, those use the de
To disable them, set their URLs to `None` when creating your `FastAPI` app:
-```Python hl_lines="8"
-{!../../../docs_src/custom_docs_ui/tutorial001.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
### Include the custom docs
@@ -36,9 +34,7 @@ You can reuse FastAPI's internal functions to create the HTML pages for the docs
And similarly for ReDoc...
-```Python hl_lines="2-6 11-19 22-24 27-33"
-{!../../../docs_src/custom_docs_ui/tutorial001.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
/// tip
@@ -54,9 +50,7 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
Now, to be able to test that everything works, create a *path operation*:
-```Python hl_lines="36-38"
-{!../../../docs_src/custom_docs_ui/tutorial001.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
### Test it
@@ -124,9 +118,7 @@ After that, your file structure could look like:
* Import `StaticFiles`.
* "Mount" a `StaticFiles()` instance in a specific path.
-```Python hl_lines="7 11"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
### Test the static files
@@ -158,9 +150,7 @@ The same as when using a custom CDN, the first step is to disable the automatic
To disable them, set their URLs to `None` when creating your `FastAPI` app:
-```Python hl_lines="9"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
### Include the custom docs for static files
@@ -176,9 +166,7 @@ Again, you can reuse FastAPI's internal functions to create the HTML pages for t
And similarly for ReDoc...
-```Python hl_lines="2-6 14-22 25-27 30-36"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
/// tip
@@ -194,9 +182,7 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
Now, to be able to test that everything works, create a *path operation*:
-```Python hl_lines="39-41"
-{!../../../docs_src/custom_docs_ui/tutorial002.py!}
-```
+{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
### Test Static Files UI
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 20e1904f1..9b4160d75 100644
--- a/docs/en/docs/how-to/custom-request-and-route.md
+++ b/docs/en/docs/how-to/custom-request-and-route.md
@@ -42,9 +42,7 @@ If there's no `gzip` in the header, it will not try to decompress the body.
That way, the same route class can handle gzip compressed or uncompressed requests.
-```Python hl_lines="8-15"
-{!../../../docs_src/custom_request_and_route/tutorial001.py!}
-```
+{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
### Create a custom `GzipRoute` class
@@ -56,11 +54,9 @@ This method returns a function. And that function is what will receive a request
Here we use it to create a `GzipRequest` from the original request.
-```Python hl_lines="18-26"
-{!../../../docs_src/custom_request_and_route/tutorial001.py!}
-```
+{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
-/// note | "Technical Details"
+/// note | Technical Details
A `Request` has a `request.scope` attribute, that's just a Python `dict` containing the metadata related to the request.
@@ -96,26 +92,18 @@ We can also use this same approach to access the request body in an exception ha
All we need to do is handle the request inside a `try`/`except` block:
-```Python hl_lines="13 15"
-{!../../../docs_src/custom_request_and_route/tutorial002.py!}
-```
+{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
If an exception occurs, the`Request` instance will still be in scope, so we can read and make use of the request body when handling the error:
-```Python hl_lines="16-18"
-{!../../../docs_src/custom_request_and_route/tutorial002.py!}
-```
+{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
## Custom `APIRoute` class in a router
You can also set the `route_class` parameter of an `APIRouter`:
-```Python hl_lines="26"
-{!../../../docs_src/custom_request_and_route/tutorial003.py!}
-```
+{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:
-```Python hl_lines="13-20"
-{!../../../docs_src/custom_request_and_route/tutorial003.py!}
-```
+{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
diff --git a/docs/en/docs/how-to/extending-openapi.md b/docs/en/docs/how-to/extending-openapi.md
index 9909f778c..26c742c20 100644
--- a/docs/en/docs/how-to/extending-openapi.md
+++ b/docs/en/docs/how-to/extending-openapi.md
@@ -43,25 +43,19 @@ For example, let's add Strawberry documentation.
diff --git a/docs/en/docs/how-to/nosql-databases-couchbase.md b/docs/en/docs/how-to/nosql-databases-couchbase.md
deleted file mode 100644
index a0abfe21d..000000000
--- a/docs/en/docs/how-to/nosql-databases-couchbase.md
+++ /dev/null
@@ -1,178 +0,0 @@
-# ~~NoSQL (Distributed / Big Data) Databases with Couchbase~~ (deprecated)
-
-/// info
-
-These docs are about to be updated. 🎉
-
-The current version assumes Pydantic v1.
-
-The new docs will hopefully use Pydantic v2 and will use ODMantic with MongoDB.
-
-///
-
-/// warning | "Deprecated"
-
-This tutorial is deprecated and will be removed in a future version.
-
-///
-
-**FastAPI** can also be integrated with any NoSQL.
-
-Here we'll see an example using **Couchbase**, a document based NoSQL database.
-
-You can adapt it to any other NoSQL database like:
-
-* **MongoDB**
-* **Cassandra**
-* **CouchDB**
-* **ArangoDB**
-* **ElasticSearch**, etc.
-
-/// tip
-
-There is an official project generator with **FastAPI** and **Couchbase**, all based on **Docker**, including a frontend and more tools: https://github.com/tiangolo/full-stack-fastapi-couchbase
-
-///
-
-## Import Couchbase components
-
-For now, don't pay attention to the rest, only the imports:
-
-```Python hl_lines="3-5"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-## Define a constant to use as a "document type"
-
-We will use it later as a fixed field `type` in our documents.
-
-This is not required by Couchbase, but is a good practice that will help you afterwards.
-
-```Python hl_lines="9"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-## Add a function to get a `Bucket`
-
-In **Couchbase**, a bucket is a set of documents, that can be of different types.
-
-They are generally all related to the same application.
-
-The analogy in the relational database world would be a "database" (a specific database, not the database server).
-
-The analogy in **MongoDB** would be a "collection".
-
-In the code, a `Bucket` represents the main entrypoint of communication with the database.
-
-This utility function will:
-
-* Connect to a **Couchbase** cluster (that might be a single machine).
- * Set defaults for timeouts.
-* Authenticate in the cluster.
-* Get a `Bucket` instance.
- * Set defaults for timeouts.
-* Return it.
-
-```Python hl_lines="12-21"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-## Create Pydantic models
-
-As **Couchbase** "documents" are actually just "JSON objects", we can model them with Pydantic.
-
-### `User` model
-
-First, let's create a `User` model:
-
-```Python hl_lines="24-28"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-We will use this model in our *path operation function*, so, we don't include in it the `hashed_password`.
-
-### `UserInDB` model
-
-Now, let's create a `UserInDB` model.
-
-This will have the data that is actually stored in the database.
-
-We don't create it as a subclass of Pydantic's `BaseModel` but as a subclass of our own `User`, because it will have all the attributes in `User` plus a couple more:
-
-```Python hl_lines="31-33"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-/// note
-
-Notice that we have a `hashed_password` and a `type` field that will be stored in the database.
-
-But it is not part of the general `User` model (the one we will return in the *path operation*).
-
-///
-
-## Get the user
-
-Now create a function that will:
-
-* Take a username.
-* Generate a document ID from it.
-* Get the document with that ID.
-* Put the contents of the document in a `UserInDB` model.
-
-By creating a function that is only dedicated to getting your user from a `username` (or any other parameter) independent of your *path operation function*, you can more easily reuse it in multiple parts and also add unit tests for it:
-
-```Python hl_lines="36-42"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-### f-strings
-
-If you are not familiar with the `f"userprofile::{username}"`, it is a Python "f-string".
-
-Any variable that is put inside of `{}` in an f-string will be expanded / injected in the string.
-
-### `dict` unpacking
-
-If you are not familiar with the `UserInDB(**result.value)`, it is using `dict` "unpacking".
-
-It will take the `dict` at `result.value`, and take each of its keys and values and pass them as key-values to `UserInDB` as keyword arguments.
-
-So, if the `dict` contains:
-
-```Python
-{
- "username": "johndoe",
- "hashed_password": "some_hash",
-}
-```
-
-It will be passed to `UserInDB` as:
-
-```Python
-UserInDB(username="johndoe", hashed_password="some_hash")
-```
-
-## Create your **FastAPI** code
-
-### Create the `FastAPI` app
-
-```Python hl_lines="46"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-### Create the *path operation function*
-
-As our code is calling Couchbase and we are not using the experimental Python await support, we should declare our function with normal `def` instead of `async def`.
-
-Also, Couchbase recommends not using a single `Bucket` object in multiple "threads", so, we can just get the bucket directly and pass it to our utility functions:
-
-```Python hl_lines="49-53"
-{!../../../docs_src/nosql_databases/tutorial001.py!}
-```
-
-## Recap
-
-You can integrate any third party NoSQL database, just using their standard packages.
-
-The same applies to any other external tool, system or API.
diff --git a/docs/en/docs/how-to/separate-openapi-schemas.md b/docs/en/docs/how-to/separate-openapi-schemas.md
index 0ab5b1337..9a27638fe 100644
--- a/docs/en/docs/how-to/separate-openapi-schemas.md
+++ b/docs/en/docs/how-to/separate-openapi-schemas.md
@@ -10,123 +10,13 @@ Let's see how that works and how to change it if you need to do that.
Let's say you have a Pydantic model with default values, like this one:
-//// tab | Python 3.10+
-
-```Python hl_lines="7"
-{!> ../../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
-
-# Code below omitted 👇
-```
-
-
+get operation
-/// info | "`@decorator` Info"
+/// info | `@decorator` Info
That `@something` syntax in Python is called a "decorator".
@@ -300,9 +292,7 @@ This is our "**path operation function**":
* **operation**: is `get`.
* **function**: is the function below the "decorator" (below `@app.get("/")`).
-```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
This is a Python function.
@@ -314,9 +304,7 @@ In this case, it is an `async` function.
You could also define it as a normal function instead of `async def`:
-```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
-```
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
/// note
@@ -326,9 +314,7 @@ If you don't know the difference, check the [Async: *"In a hurry?"*](../async.md
### Step 5: return the content
-```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
You can return a `dict`, `list`, singular values as `str`, `int`, etc.
diff --git a/docs/en/docs/tutorial/handling-errors.md b/docs/en/docs/tutorial/handling-errors.md
index 14a3cf998..537cb3e72 100644
--- a/docs/en/docs/tutorial/handling-errors.md
+++ b/docs/en/docs/tutorial/handling-errors.md
@@ -26,7 +26,7 @@ To return HTTP responses with errors to the client you use `HTTPException`.
### Import `HTTPException`
```Python hl_lines="1"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### Raise an `HTTPException` in your code
@@ -42,7 +42,7 @@ The benefit of raising an exception over `return`ing a value will be more eviden
In this example, when the client requests an item by an ID that doesn't exist, raise an exception with a status code of `404`:
```Python hl_lines="11"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### The resulting response
@@ -82,7 +82,7 @@ You probably won't need to use it directly in your code.
But in case you needed it for an advanced scenario, you can add custom headers:
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial002.py!}
+{!../../docs_src/handling_errors/tutorial002.py!}
```
## Install custom exception handlers
@@ -96,7 +96,7 @@ And you want to handle this exception globally with FastAPI.
You could add a custom exception handler with `@app.exception_handler()`:
```Python hl_lines="5-7 13-18 24"
-{!../../../docs_src/handling_errors/tutorial003.py!}
+{!../../docs_src/handling_errors/tutorial003.py!}
```
Here, if you request `/unicorns/yolo`, the *path operation* will `raise` a `UnicornException`.
@@ -109,7 +109,7 @@ So, you will receive a clean error, with an HTTP status code of `418` and a JSON
{"message": "Oops! yolo did something. There goes a rainbow..."}
```
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.requests import Request` and `from starlette.responses import JSONResponse`.
@@ -136,7 +136,7 @@ To override it, import the `RequestValidationError` and use it with `@app.except
The exception handler will receive a `Request` and the exception.
```Python hl_lines="2 14-16"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
Now, if you go to `/items/foo`, instead of getting the default JSON error with:
@@ -189,10 +189,10 @@ The same way, you can override the `HTTPException` handler.
For example, you could want to return a plain text response instead of JSON for these errors:
```Python hl_lines="3-4 9-11 22"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
-/// note | "Technical Details"
+/// note | Technical Details
You could also use `from starlette.responses import PlainTextResponse`.
@@ -207,7 +207,7 @@ The `RequestValidationError` contains the `body` it received with invalid data.
You could use it while developing your app to log the body and debug it, return it to the user, etc.
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial005.py!}
+{!../../docs_src/handling_errors/tutorial005.py!}
```
Now try sending an invalid item like:
@@ -265,7 +265,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
If you want to use the exception along with the same default exception handlers from **FastAPI**, you can import and reuse the default exception handlers from `fastapi.exception_handlers`:
```Python hl_lines="2-5 15 21"
-{!../../../docs_src/handling_errors/tutorial006.py!}
+{!../../docs_src/handling_errors/tutorial006.py!}
```
In this example you are just `print`ing the error with a very expressive message, but you get the idea. You can use the exception and then just reuse the default exception handlers.
diff --git a/docs/en/docs/tutorial/header-param-models.md b/docs/en/docs/tutorial/header-param-models.md
new file mode 100644
index 000000000..78517e498
--- /dev/null
+++ b/docs/en/docs/tutorial/header-param-models.md
@@ -0,0 +1,184 @@
+# Header Parameter Models
+
+If you have a group of related **header parameters**, you can create a **Pydantic model** to declare them.
+
+This would allow you to **re-use the model** in **multiple places** and also to declare validations and metadata for all the parameters at once. 😎
+
+/// note
+
+This is supported since FastAPI version `0.115.0`. 🤓
+
+///
+
+## Header Parameters with a Pydantic Model
+
+Declare the **header parameters** that you need in a **Pydantic model**, and then declare the parameter as `Header`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="9-14 18"
+{!> ../../docs_src/header_param_models/tutorial001_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="9-14 18"
+{!> ../../docs_src/header_param_models/tutorial001_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="10-15 19"
+{!> ../../docs_src/header_param_models/tutorial001_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip
+
+Prefer to use the `Annotated` version if possible.
+
+///
+
+```Python hl_lines="7-12 16"
+{!> ../../docs_src/header_param_models/tutorial001_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip
+
+Prefer to use the `Annotated` version if possible.
+
+///
+
+```Python hl_lines="9-14 18"
+{!> ../../docs_src/header_param_models/tutorial001_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip
+
+Prefer to use the `Annotated` version if possible.
+
+///
+
+```Python hl_lines="7-12 16"
+{!> ../../docs_src/header_param_models/tutorial001_py310.py!}
+```
+
+////
+
+**FastAPI** will **extract** the data for **each field** from the **headers** in the request and give you the Pydantic model you defined.
+
+## Check the Docs
+
+You can see the required headers in the docs UI at `/docs`:
+
+
+kwargs. Even if they don't have a default value.
-```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
### Better with `Annotated`
Keep in mind that if you use `Annotated`, as you are not using function parameter default values, you won't have this problem, and you probably won't need to use `*`.
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
## Number validations: greater than or equal
@@ -239,35 +107,7 @@ With `Query` and `Path` (and others you'll see later) you can declare number con
Here, with `ge=1`, `item_id` will need to be an integer number "`g`reater than or `e`qual" to `1`.
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
## Number validations: greater than and less than or equal
@@ -276,35 +116,7 @@ The same applies for:
* `gt`: `g`reater `t`han
* `le`: `l`ess than or `e`qual
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
## Number validations: floats, greater than and less than
@@ -316,35 +128,7 @@ So, `0.5` would be a valid value. But `0.0` or `0` would not.
And the same for lt.
-//// tab | Python 3.9+
-
-```Python hl_lines="13"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="12"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
## Recap
@@ -365,7 +149,7 @@ All of them share the same parameters for additional validation and metadata you
///
-/// note | "Technical Details"
+/// note | Technical Details
When you import `Query`, `Path` and others from `fastapi`, they are actually functions.
diff --git a/docs/en/docs/tutorial/path-params.md b/docs/en/docs/tutorial/path-params.md
index a87a29e08..7e83d3ae5 100644
--- a/docs/en/docs/tutorial/path-params.md
+++ b/docs/en/docs/tutorial/path-params.md
@@ -2,9 +2,7 @@
You can declare path "parameters" or "variables" with the same syntax used by Python format strings:
-```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
-```
+{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
The value of the path parameter `item_id` will be passed to your function as the argument `item_id`.
@@ -18,9 +16,7 @@ So, if you run this example and go to
+
+
+
-/// check | "Authorize button!"
+/// check | Authorize button!
You already have a shiny new "Authorize" button.
@@ -160,35 +132,7 @@ In that case, **FastAPI** also provides you with the tools to build it.
When we create an instance of the `OAuth2PasswordBearer` class we pass in the `tokenUrl` parameter. This parameter contains the URL that the client (the frontend running in the user's browser) will use to send the `username` and `password` in order to get a token.
-//// tab | Python 3.9+
-
-```Python hl_lines="8"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="7"
-{!> ../../../docs_src/security/tutorial001_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="6"
-{!> ../../../docs_src/security/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
/// tip
@@ -226,41 +170,13 @@ So, it can be used with `Depends`.
Now you can pass that `oauth2_scheme` in a dependency with `Depends`.
-//// tab | Python 3.9+
-
-```Python hl_lines="12"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="11"
-{!> ../../../docs_src/security/tutorial001_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="10"
-{!> ../../../docs_src/security/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
This dependency will provide a `str` that is assigned to the parameter `token` of the *path operation function*.
**FastAPI** will know that it can use this dependency to define a "security scheme" in the OpenAPI schema (and the automatic API docs).
-/// info | "Technical Details"
+/// info | Technical Details
**FastAPI** will know that it can use the class `OAuth2PasswordBearer` (declared in a dependency) to define the security scheme in OpenAPI because it inherits from `fastapi.security.oauth2.OAuth2`, which in turn inherits from `fastapi.security.base.SecurityBase`.
diff --git a/docs/en/docs/tutorial/security/get-current-user.md b/docs/en/docs/tutorial/security/get-current-user.md
index 7faaa3e13..5de3a8e7d 100644
--- a/docs/en/docs/tutorial/security/get-current-user.md
+++ b/docs/en/docs/tutorial/security/get-current-user.md
@@ -2,35 +2,7 @@
In the previous chapter the security system (which is based on the dependency injection system) was giving the *path operation function* a `token` as a `str`:
-//// tab | Python 3.9+
-
-```Python hl_lines="12"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="11"
-{!> ../../../docs_src/security/tutorial001_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="10"
-{!> ../../../docs_src/security/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
But that is still not that useful.
@@ -42,57 +14,7 @@ First, let's create a Pydantic user model.
The same way we use Pydantic to declare bodies, we can use it anywhere else:
-//// tab | Python 3.10+
-
-```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="5 13-17"
-{!> ../../../docs_src/security/tutorial002_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="3 10-14"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
## Create a `get_current_user` dependency
@@ -104,169 +26,19 @@ Remember that dependencies can have sub-dependencies?
The same as we were doing before in the *path operation* directly, our new dependency `get_current_user` will receive a `token` as a `str` from the sub-dependency `oauth2_scheme`:
-//// tab | Python 3.10+
-
-```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="26"
-{!> ../../../docs_src/security/tutorial002_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="23"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
## Get the user
`get_current_user` will use a (fake) utility function we created, that takes a token as a `str` and returns our Pydantic `User` model:
-//// tab | Python 3.10+
-
-```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="20-23 27-28"
-{!> ../../../docs_src/security/tutorial002_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="17-20 24-25"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
## Inject the current user
So now we can use the same `Depends` with our `get_current_user` in the *path operation*:
-//// tab | Python 3.10+
-
-```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="32"
-{!> ../../../docs_src/security/tutorial002_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="29"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
Notice that we declare the type of `current_user` as the Pydantic model `User`.
@@ -320,57 +92,7 @@ And all of them (or any portion of them that you want) can take advantage of re-
And all these thousands of *path operations* can be as small as 3 lines:
-//// tab | Python 3.10+
-
-```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="31-33"
-{!> ../../../docs_src/security/tutorial002_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="28-30"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
## Recap
diff --git a/docs/en/docs/tutorial/security/oauth2-jwt.md b/docs/en/docs/tutorial/security/oauth2-jwt.md
index ba2bfef29..6ae1507dc 100644
--- a/docs/en/docs/tutorial/security/oauth2-jwt.md
+++ b/docs/en/docs/tutorial/security/oauth2-jwt.md
@@ -72,7 +72,7 @@ It supports many secure hashing algorithms and utilities to work with them.
The recommended algorithm is "Bcrypt".
-Make sure you create a [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and then install PassLib with Bcrypt:
+Make sure you create a [virtual environment](../../virtual-environments.md){.internal-link target=_blank}, activate it, and then install PassLib with Bcrypt:
+
+We shouldn't let that happen, they could overwrite an `id` we already have assigned in the DB. Deciding the `id` should be done by the **backend** or the **database**, **not by the client**.
-You can also use an online SQLite browser like SQLite Viewer or ExtendsClass.
+Additionally, we create a `secret_name` for the hero, but so far, we are returning it everywhere, that's not very **secret**... 😅
-## Alternative DB session with middleware
+We'll fix these things by adding a few **extra models**. Here's where SQLModel will shine. ✨
-If you can't use dependencies with `yield` -- for example, if you are not using **Python 3.7** and can't install the "backports" mentioned above for **Python 3.6** -- you can set up the session in a "middleware" in a similar way.
+### Create Multiple Models
-A "middleware" is basically a function that is always executed for each request, with some code executed before, and some code executed after the endpoint function.
+In **SQLModel**, any model class that has `table=True` is a **table model**.
-### Create a middleware
+And any model class that doesn't have `table=True` is a **data model**, these ones are actually just Pydantic models (with a couple of small extra features). 🤓
-The middleware we'll add (just a function) will create a new SQLAlchemy `SessionLocal` for each request, add it to the request and then close it once the request is finished.
+With SQLModel, we can use **inheritance** to **avoid duplicating** all the fields in all the cases.
-//// tab | Python 3.9+
+#### `HeroBase` - the base class
-```Python hl_lines="12-20"
-{!> ../../../docs_src/sql_databases/sql_app_py39/alt_main.py!}
-```
+Let's start with a `HeroBase` model that has all the **fields that are shared** by all the models:
-////
+* `name`
+* `age`
-//// tab | Python 3.8+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *}
-```Python hl_lines="14-22"
-{!> ../../../docs_src/sql_databases/sql_app/alt_main.py!}
-```
+#### `Hero` - the *table model*
-////
+Then let's create `Hero`, the actual *table model*, with the **extra fields** that are not always in the other models:
-/// info
+* `id`
+* `secret_name`
-We put the creation of the `SessionLocal()` and handling of the requests in a `try` block.
+Because `Hero` inherits form `HeroBase`, it **also** has the **fields** declared in `HeroBase`, so all the fields for `Hero` are:
-And then we close it in the `finally` block.
+* `id`
+* `name`
+* `age`
+* `secret_name`
-This way we make sure the database session is always closed after the request. Even if there was an exception while processing the request.
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *}
-///
+#### `HeroPublic` - the public *data model*
-### About `request.state`
+Next, we create a `HeroPublic` model, this is the one that will be **returned** to the clients of the API.
-`request.state` is a property of each `Request` object. It is there to store arbitrary objects attached to the request itself, like the database session in this case. You can read more about it in Starlette's docs about `Request` state.
+It has the same fields as `HeroBase`, so it won't include `secret_name`.
-For us in this case, it helps us ensure a single database session is used through all the request, and then closed afterwards (in the middleware).
+Finally, the identity of our heroes is protected! 🥷
-### Dependencies with `yield` or middleware
-
-Adding a **middleware** here is similar to what a dependency with `yield` does, with some differences:
-
-* It requires more code and is a bit more complex.
-* The middleware has to be an `async` function.
- * If there is code in it that has to "wait" for the network, it could "block" your application there and degrade performance a bit.
- * Although it's probably not very problematic here with the way `SQLAlchemy` works.
- * But if you added more code to the middleware that had a lot of I/O waiting, it could then be problematic.
-* A middleware is run for *every* request.
- * So, a connection will be created for every request.
- * Even when the *path operation* that handles that request didn't need the DB.
+It also re-declares `id: int`. By doing this, we are making a **contract** with the API clients, so that they can always expect the `id` to be there and to be an `int` (it will never be `None`).
/// tip
-It's probably better to use dependencies with `yield` when they are enough for the use case.
+Having the return model ensure that a value is always available and always `int` (not `None`) is very useful for the API clients, they can write much simpler code having this certainty.
+
+Also, **automatically generated clients** will have simpler interfaces, so that the developers communicating with your API can have a much better time working with your API. 😎
///
-/// info
+All the fields in `HeroPublic` are the same as in `HeroBase`, with `id` declared as `int` (not `None`):
-Dependencies with `yield` were added recently to **FastAPI**.
+* `id`
+* `name`
+* `age`
+* `secret_name`
-A previous version of this tutorial only had the examples with a middleware and there are probably several applications using the middleware for database session management.
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *}
+
+#### `HeroCreate` - the *data model* to create a hero
+
+Now we create a `HeroCreate` model, this is the one that will **validate** the data from the clients.
+
+It has the same fields as `HeroBase`, and it also has `secret_name`.
+
+Now, when the clients **create a new hero**, they will send the `secret_name`, it will be stored in the database, but those secret names won't be returned in the API to the clients.
+
+/// tip
+
+This is how you would handle **passwords**. Receive them, but don't return them in the API.
+
+You would also **hash** the values of the passwords before storing them, **never store them in plain text**.
///
+
+The fields of `HeroCreate` are:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *}
+
+#### `HeroUpdate` - the *data model* to update a hero
+
+We didn't have a way to **update a hero** in the previous version of the app, but now with **multiple models**, we can do it. 🎉
+
+The `HeroUpdate` *data model* is somewhat special, it has **all the same fields** that would be needed to create a new hero, but all the fields are **optional** (they all have a default value). This way, when you update a hero, you can send just the fields that you want to update.
+
+Because all the **fields actually change** (the type now includes `None` and they now have a default value of `None`), we need to **re-declare** them.
+
+We don't really need to inherit from `HeroBase` because we are re-declaring all the fields. I'll leave it inheriting just for consistency, but this is not necessary. It's more a matter of personal taste. 🤷
+
+The fields of `HeroUpdate` are:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *}
+
+### Create with `HeroCreate` and return a `HeroPublic`
+
+Now that we have **multiple models**, we can update the parts of the app that use them.
+
+We receive in the request a `HeroCreate` *data model*, and from it, we create a `Hero` *table model*.
+
+This new *table model* `Hero` will have the fields sent by the client, and will also have an `id` generated by the database.
+
+Then we return the same *table model* `Hero` as is from the function. But as we declare the `response_model` with the `HeroPublic` *data model*, **FastAPI** will use `HeroPublic` to validate and serialize the data.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *}
+
+/// tip
+
+Now we use `response_model=HeroPublic` instead of the **return type annotation** `-> HeroPublic` because the value that we are returning is actually *not* a `HeroPublic`.
+
+If we had declared `-> HeroPublic`, your editor and linter would complain (rightfully so) that you are returning a `Hero` instead of a `HeroPublic`.
+
+By declaring it in `response_model` we are telling **FastAPI** to do its thing, without interfering with the type annotations and the help from your editor and other tools.
+
+///
+
+### Read Heroes with `HeroPublic`
+
+We can do the same as before to **read** `Hero`s, again, we use `response_model=list[HeroPublic]` to ensure that the data is validated and serialized correctly.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *}
+
+### Read One Hero with `HeroPublic`
+
+We can **read** a single hero:
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *}
+
+### Update a Hero with `HeroUpdate`
+
+We can **update a hero**. For this we use an HTTP `PATCH` operation.
+
+And in the code, we get a `dict` with all the data sent by the client, **only the data sent by the client**, excluding any values that would be there just for being the default values. To do it we use `exclude_unset=True`. This is the main trick. 🪄
+
+Then we use `hero_db.sqlmodel_update(hero_data)` to update the `hero_db` with the data from `hero_data`.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *}
+
+### Delete a Hero Again
+
+**Deleting** a hero stays pretty much the same.
+
+We won't satisfy the desire to refactor everything in this one. 😅
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *}
+
+### Run the App Again
+
+You can run the app again:
+
+
+
-
- get
-/// info | "`@décorateur` Info"
+/// info | `@décorateur` Info
Cette syntaxe `@something` en Python est appelée un "décorateur".
@@ -286,7 +276,7 @@ Tout comme celles les plus exotiques :
* `@app.patch()`
* `@app.trace()`
-/// tip | "Astuce"
+/// tip | Astuce
Vous êtes libres d'utiliser chaque opération (méthode HTTP) comme vous le désirez.
@@ -306,9 +296,7 @@ Voici notre "**fonction de chemin**" (ou fonction d'opération de chemin) :
* **opération** : `get`.
* **fonction** : la fonction sous le "décorateur" (sous `@app.get("/")`).
-```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
C'est une fonction Python.
@@ -320,9 +308,7 @@ Ici, c'est une fonction asynchrone (définie avec `async def`).
Vous pourriez aussi la définir comme une fonction classique plutôt qu'avec `async def` :
-```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
-```
+{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
/// note
@@ -332,9 +318,7 @@ Si vous ne connaissez pas la différence, allez voir la section [Concurrence : *
### Étape 5 : retourner le contenu
-```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
Vous pouvez retourner un dictionnaire (`dict`), une liste (`list`), des valeurs seules comme des chaines de caractères (`str`) et des entiers (`int`), etc.
diff --git a/docs/fr/docs/tutorial/path-params-numeric-validations.md b/docs/fr/docs/tutorial/path-params-numeric-validations.md
index eedd59f91..3f3280e64 100644
--- a/docs/fr/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/fr/docs/tutorial/path-params-numeric-validations.md
@@ -6,57 +6,7 @@ De la même façon que vous pouvez déclarer plus de validations et de métadonn
Tout d'abord, importez `Path` de `fastapi`, et importez `Annotated` :
-//// tab | Python 3.10+
-
-```Python hl_lines="1 3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="1 3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="3-4"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="1"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
/// info
@@ -74,57 +24,7 @@ Vous pouvez déclarer les mêmes paramètres que pour `Query`.
Par exemple, pour déclarer une valeur de métadonnée `title` pour le paramètre de chemin `item_id`, vous pouvez écrire :
-//// tab | Python 3.10+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
/// note
@@ -154,37 +54,11 @@ Cela n'a pas d'importance pour **FastAPI**. Il détectera les paramètres par le
Ainsi, vous pouvez déclarer votre fonction comme suit :
-//// tab | Python 3.8 non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="7"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
Mais gardez à l'esprit que si vous utilisez `Annotated`, vous n'aurez pas ce problème, cela n'aura pas d'importance car vous n'utilisez pas les valeurs par défaut des paramètres de fonction pour `Query()` ou `Path()`.
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py hl[10] *}
## Ordonnez les paramètres comme vous le souhaitez (astuces)
@@ -209,29 +83,13 @@ Passez `*`, comme premier paramètre de la fonction.
Python ne fera rien avec ce `*`, mais il saura que tous les paramètres suivants doivent être appelés comme arguments "mots-clés" (paires clé-valeur), également connus sous le nom de kwargs. Même s'ils n'ont pas de valeur par défaut.
-```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
-```
+{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
# Avec `Annotated`
Gardez à l'esprit que si vous utilisez `Annotated`, comme vous n'utilisez pas les valeurs par défaut des paramètres de fonction, vous n'aurez pas ce problème, et vous n'aurez probablement pas besoin d'utiliser `*`.
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
## Validations numériques : supérieur ou égal
@@ -239,35 +97,7 @@ Avec `Query` et `Path` (et d'autres que vous verrez plus tard) vous pouvez décl
Ici, avec `ge=1`, `item_id` devra être un nombre entier "`g`reater than or `e`qual" à `1`.
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Prefer to use the `Annotated` version if possible.
-
-///
-
-```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
## Validations numériques : supérieur ou égal et inférieur ou égal
@@ -276,35 +106,7 @@ La même chose s'applique pour :
* `gt` : `g`reater `t`han
* `le` : `l`ess than or `e`qual
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
## Validations numériques : supérieur et inférieur ou égal
@@ -313,35 +115,7 @@ La même chose s'applique pour :
* `gt` : `g`reater `t`han
* `le` : `l`ess than or `e`qual
-//// tab | Python 3.9+
-
-```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
## Validations numériques : flottants, supérieur et inférieur
@@ -353,35 +127,7 @@ Ainsi, `0.5` serait une valeur valide. Mais `0.0` ou `0` ne le serait pas.
Et la même chose pour lt.
-//// tab | Python 3.9+
-
-```Python hl_lines="13"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="12"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip
-
-Préférez utiliser la version `Annotated` si possible.
-
-///
-
-```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
## Pour résumer
@@ -402,7 +148,7 @@ Tous partagent les mêmes paramètres pour des validations supplémentaires et d
///
-/// note | "Détails techniques"
+/// note | Détails techniques
Lorsque vous importez `Query`, `Path` et d'autres de `fastapi`, ce sont en fait des fonctions.
diff --git a/docs/fr/docs/tutorial/path-params.md b/docs/fr/docs/tutorial/path-params.md
index 94c36a20d..71c96b18e 100644
--- a/docs/fr/docs/tutorial/path-params.md
+++ b/docs/fr/docs/tutorial/path-params.md
@@ -4,9 +4,7 @@ Vous pouvez déclarer des "paramètres" ou "variables" de chemin avec la même s
formatage de chaîne Python :
-```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
-```
+{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
La valeur du paramètre `item_id` sera transmise à la fonction dans l'argument `item_id`.
@@ -22,13 +20,11 @@ vous verrez comme réponse :
Vous pouvez déclarer le type d'un paramètre de chemin dans la fonction, en utilisant les annotations de type Python :
-```Python hl_lines="7"
-{!../../../docs_src/path_params/tutorial002.py!}
-```
+{* ../../docs_src/path_params/tutorial002.py hl[7] *}
Ici, `item_id` est déclaré comme `int`.
-/// check | "vérifier"
+/// check | vérifier
Ceci vous permettra d'obtenir des fonctionnalités de l'éditeur dans votre fonction, telles
que des vérifications d'erreur, de l'auto-complétion, etc.
@@ -43,7 +39,7 @@ Si vous exécutez cet exemple et allez sur http://127.0.0.1:8000/items/4.2.
-/// check | "vérifier"
+/// check | vérifier
Donc, avec ces mêmes déclarations de type Python, **FastAPI** vous fournit de la validation de données.
@@ -131,9 +127,7 @@ Et vous avez un second chemin : `/users/{user_id}` pour récupérer de la donné
Les *fonctions de chemin* étant évaluées dans l'ordre, il faut s'assurer que la fonction correspondant à `/users/me` est déclarée avant celle de `/users/{user_id}` :
-```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
-```
+{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
Sinon, le chemin `/users/{user_id}` correspondrait aussi à `/users/me`, la fonction "croyant" qu'elle a reçu un paramètre `user_id` avec pour valeur `"me"`.
@@ -149,9 +143,7 @@ En héritant de `str` la documentation sera capable de savoir que les valeurs do
Créez ensuite des attributs de classe avec des valeurs fixes, qui seront les valeurs autorisées pour cette énumération.
-```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
/// info
@@ -159,7 +151,7 @@ Créez ensuite des attributs de classe avec des valeurs fixes, qui seront les va
///
-/// tip | "Astuce"
+/// tip | Astuce
Pour ceux qui se demandent, "AlexNet", "ResNet", et "LeNet" sont juste des noms de modèles de Machine Learning.
@@ -169,9 +161,7 @@ Pour ceux qui se demandent, "AlexNet", "ResNet", et "LeNet" sont juste des noms
Créez ensuite un *paramètre de chemin* avec une annotation de type désignant l'énumération créée précédemment (`ModelName`) :
-```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[16] *}
### Documentation
@@ -187,19 +177,15 @@ La valeur du *paramètre de chemin* sera un des "membres" de l'énumération.
Vous pouvez comparer ce paramètre avec les membres de votre énumération `ModelName` :
-```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[17] *}
#### Récupérer la *valeur de l'énumération*
Vous pouvez obtenir la valeur réel d'un membre (une chaîne de caractères ici), avec `model_name.value`, ou en général, `votre_membre_d'enum.value` :
-```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[20] *}
-/// tip | "Astuce"
+/// tip | Astuce
Vous pouvez aussi accéder la valeur `"lenet"` avec `ModelName.lenet.value`.
@@ -211,9 +197,7 @@ Vous pouvez retourner des *membres d'énumération* dans vos *fonctions de chemi
Ils seront convertis vers leurs valeurs correspondantes (chaînes de caractères ici) avant d'être transmis au client :
-```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
-```
+{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
Le client recevra une réponse JSON comme celle-ci :
@@ -252,11 +236,9 @@ Dans ce cas, le nom du paramètre est `file_path`, et la dernière partie, `:pat
Vous pouvez donc l'utilisez comme tel :
-```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
-```
+{* ../../docs_src/path_params/tutorial004.py hl[6] *}
-/// tip | "Astuce"
+/// tip | Astuce
Vous pourriez avoir besoin que le paramètre contienne `/home/johndoe/myfile.txt`, avec un slash au début (`/`).
diff --git a/docs/fr/docs/tutorial/query-params-str-validations.md b/docs/fr/docs/tutorial/query-params-str-validations.md
index 63578ec40..c54c0c717 100644
--- a/docs/fr/docs/tutorial/query-params-str-validations.md
+++ b/docs/fr/docs/tutorial/query-params-str-validations.md
@@ -4,9 +4,7 @@
Commençons avec cette application pour exemple :
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial001.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial001.py hl[9] *}
Le paramètre de requête `q` a pour type `Union[str, None]` (ou `str | None` en Python 3.10), signifiant qu'il est de type `str` mais pourrait aussi être égal à `None`, et bien sûr, la valeur par défaut est `None`, donc **FastAPI** saura qu'il n'est pas requis.
@@ -26,17 +24,13 @@ Nous allons imposer que bien que `q` soit un paramètre optionnel, dès qu'il es
Pour cela, importez d'abord `Query` depuis `fastapi` :
-```Python hl_lines="3"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial002.py hl[3] *}
## Utiliser `Query` comme valeur par défaut
Construisez ensuite la valeur par défaut de votre paramètre avec `Query`, en choisissant 50 comme `max_length` :
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial002.py hl[9] *}
Comme nous devons remplacer la valeur par défaut `None` dans la fonction par `Query()`, nous pouvons maintenant définir la valeur par défaut avec le paramètre `Query(default=None)`, il sert le même objectif qui est de définir cette valeur par défaut.
@@ -86,17 +80,13 @@ Cela va valider les données, montrer une erreur claire si ces dernières ne son
Vous pouvez aussi rajouter un second paramètre `min_length` :
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial003.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial003.py hl[9] *}
## Ajouter des validations par expressions régulières
On peut définir une expression régulière à laquelle le paramètre doit correspondre :
-```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial004.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial004.py hl[10] *}
Cette expression régulière vérifie que la valeur passée comme paramètre :
@@ -114,11 +104,9 @@ De la même façon que vous pouvez passer `None` comme premier argument pour l'u
Disons que vous déclarez le paramètre `q` comme ayant une longueur minimale de `3`, et une valeur par défaut étant `"fixedquery"` :
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial005.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial005.py hl[7] *}
-/// note | "Rappel"
+/// note | Rappel
Avoir une valeur par défaut rend le paramètre optionnel.
@@ -146,9 +134,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
Donc pour déclarer une valeur comme requise tout en utilisant `Query`, il faut utiliser `...` comme premier argument :
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial006.py hl[7] *}
/// info
@@ -164,9 +150,7 @@ Quand on définit un paramètre de requête explicitement avec `Query` on peut a
Par exemple, pour déclarer un paramètre de requête `q` qui peut apparaître plusieurs fois dans une URL, on écrit :
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial011.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial011.py hl[9] *}
Ce qui fait qu'avec une URL comme :
@@ -187,7 +171,7 @@ Donc la réponse de cette URL serait :
}
```
-/// tip | "Astuce"
+/// tip | Astuce
Pour déclarer un paramètre de requête de type `list`, comme dans l'exemple ci-dessus, il faut explicitement utiliser `Query`, sinon cela sera interprété comme faisant partie du corps de la requête.
@@ -201,9 +185,7 @@ La documentation sera donc mise à jour automatiquement pour autoriser plusieurs
Et l'on peut aussi définir une liste de valeurs par défaut si aucune n'est fournie :
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial012.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial012.py hl[9] *}
Si vous allez à :
@@ -228,9 +210,7 @@ et la réponse sera :
Il est aussi possible d'utiliser directement `list` plutôt que `List[str]` :
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial013.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial013.py hl[7] *}
/// note
@@ -256,15 +236,11 @@ Il se peut donc que certains d'entre eux n'utilisent pas toutes les métadonnée
Vous pouvez ajouter un `title` :
-```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial007.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial007.py hl[10] *}
Et une `description` :
-```Python hl_lines="13"
-{!../../../docs_src/query_params_str_validations/tutorial008.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial008.py hl[13] *}
## Alias de paramètres
@@ -284,9 +260,7 @@ Mais vous avez vraiment envie que ce soit exactement `item-query`...
Pour cela vous pouvez déclarer un `alias`, et cet alias est ce qui sera utilisé pour trouver la valeur du paramètre :
-```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial009.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial009.py hl[9] *}
## Déprécier des paramètres
@@ -296,9 +270,7 @@ Il faut qu'il continue à exister pendant un certain temps car vos clients l'uti
On utilise alors l'argument `deprecated=True` de `Query` :
-```Python hl_lines="18"
-{!../../../docs_src/query_params_str_validations/tutorial010.py!}
-```
+{* ../../docs_src/query_params_str_validations/tutorial010.py hl[18] *}
La documentation le présentera comme il suit :
diff --git a/docs/fr/docs/tutorial/query-params.md b/docs/fr/docs/tutorial/query-params.md
index b9f1540c9..b87c26c78 100644
--- a/docs/fr/docs/tutorial/query-params.md
+++ b/docs/fr/docs/tutorial/query-params.md
@@ -2,9 +2,7 @@
Quand vous déclarez des paramètres dans votre fonction de chemin qui ne font pas partie des paramètres indiqués dans le chemin associé, ces paramètres sont automatiquement considérés comme des paramètres de "requête".
-```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
-```
+{* ../../docs_src/query_params/tutorial001.py hl[9] *}
La partie appelée requête (ou **query**) dans une URL est l'ensemble des paires clés-valeurs placées après le `?` , séparées par des `&`.
@@ -63,13 +61,11 @@ Les valeurs des paramètres de votre fonction seront :
De la même façon, vous pouvez définir des paramètres de requête comme optionnels, en leur donnant comme valeur par défaut `None` :
-```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial002.py!}
-```
+{* ../../docs_src/query_params/tutorial002.py hl[9] *}
Ici, le paramètre `q` sera optionnel, et aura `None` comme valeur par défaut.
-/// check | "Remarque"
+/// check | Remarque
On peut voir que **FastAPI** est capable de détecter que le paramètre de chemin `item_id` est un paramètre de chemin et que `q` n'en est pas un, c'est donc un paramètre de requête.
@@ -87,9 +83,7 @@ Le `Optional` dans `Optional[str]` n'est pas utilisé par **FastAPI** (**FastAPI
Vous pouvez aussi déclarer des paramètres de requête comme booléens (`bool`), **FastAPI** les convertira :
-```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial003.py!}
-```
+{* ../../docs_src/query_params/tutorial003.py hl[9] *}
Avec ce code, en allant sur :
@@ -131,9 +125,7 @@ Et vous n'avez pas besoin de les déclarer dans un ordre spécifique.
Ils seront détectés par leurs noms :
-```Python hl_lines="8 10"
-{!../../../docs_src/query_params/tutorial004.py!}
-```
+{* ../../docs_src/query_params/tutorial004.py hl[8,10] *}
## Paramètres de requête requis
@@ -143,9 +135,7 @@ Si vous ne voulez pas leur donner de valeur par défaut mais juste les rendre op
Mais si vous voulez rendre un paramètre de requête obligatoire, vous pouvez juste ne pas y affecter de valeur par défaut :
-```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
-```
+{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
Ici le paramètre `needy` est un paramètre requis (ou obligatoire) de type `str`.
@@ -189,9 +179,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
Et bien sur, vous pouvez définir certains paramètres comme requis, certains avec des valeurs par défaut et certains entièrement optionnels :
-```Python hl_lines="10"
-{!../../../docs_src/query_params/tutorial006.py!}
-```
+{* ../../docs_src/query_params/tutorial006.py hl[10] *}
Ici, on a donc 3 paramètres de requête :
@@ -199,7 +187,7 @@ Ici, on a donc 3 paramètres de requête :
* `skip`, un `int` avec comme valeur par défaut `0`.
* `limit`, un `int` optionnel.
-/// tip | "Astuce"
+/// tip | Astuce
Vous pouvez utiliser les `Enum`s de la même façon qu'avec les [Paramètres de chemin](path-params.md#valeurs-predefinies){.internal-link target=_blank}.
diff --git a/docs/he/docs/index.md b/docs/he/docs/index.md
index 23a2eb824..6498d15e1 100644
--- a/docs/he/docs/index.md
+++ b/docs/he/docs/index.md
@@ -94,7 +94,7 @@ FastAPI היא תשתית רשת מודרנית ומהירה (ביצועים ג
"_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._"
-
+
---
diff --git a/docs/hu/docs/index.md b/docs/hu/docs/index.md
index 8e326a78b..c6f596650 100644
--- a/docs/hu/docs/index.md
+++ b/docs/hu/docs/index.md
@@ -87,7 +87,7 @@ Kulcs funkciók:
"_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._"
-
+
---
diff --git a/docs/id/docs/tutorial/index.md b/docs/id/docs/tutorial/index.md
index f0dee3d73..c01ec9a89 100644
--- a/docs/id/docs/tutorial/index.md
+++ b/docs/id/docs/tutorial/index.md
@@ -52,7 +52,7 @@ $ pip install "fastapi[all]"
...yang juga termasuk `uvicorn`, yang dapat kamu gunakan sebagai server yang menjalankan kodemu.
-/// note | "Catatan"
+/// note | Catatan
Kamu juga dapat meng-installnya bagian demi bagian.
diff --git a/docs/it/docs/index.md b/docs/it/docs/index.md
index 57940f0ed..8a1039bc5 100644
--- a/docs/it/docs/index.md
+++ b/docs/it/docs/index.md
@@ -1,6 +1,3 @@
-{!../../../docs/missing-translation.md!}
-
-
@@ -87,7 +84,7 @@ Le sue caratteristiche principali sono:
"_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._"
-
+
---
diff --git a/docs/ja/docs/advanced/additional-status-codes.md b/docs/ja/docs/advanced/additional-status-codes.md
index 622affa6e..fb3164328 100644
--- a/docs/ja/docs/advanced/additional-status-codes.md
+++ b/docs/ja/docs/advanced/additional-status-codes.md
@@ -15,10 +15,10 @@
これを達成するには、 `JSONResponse` をインポートし、 `status_code` を設定して直接内容を返します。
```Python hl_lines="4 25"
-{!../../../docs_src/additional_status_codes/tutorial001.py!}
+{!../../docs_src/additional_status_codes/tutorial001.py!}
```
-/// warning | "注意"
+/// warning | 注意
上記の例のように `Response` を明示的に返す場合、それは直接返されます。
@@ -28,7 +28,7 @@
///
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.responses import JSONResponse` を利用することもできます。
diff --git a/docs/ja/docs/advanced/custom-response.md b/docs/ja/docs/advanced/custom-response.md
index a7ce6b54d..15edc11ad 100644
--- a/docs/ja/docs/advanced/custom-response.md
+++ b/docs/ja/docs/advanced/custom-response.md
@@ -12,7 +12,7 @@
そしてもし、`Response` が、`JSONResponse` や `UJSONResponse` の場合のようにJSONメディアタイプ (`application/json`) ならば、データは *path operationデコレータ* に宣言したPydantic `response_model` により自動的に変換 (もしくはフィルタ) されます。
-/// note | "備考"
+/// note | 備考
メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIは何もコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。
@@ -25,10 +25,10 @@
使いたい `Response` クラス (サブクラス) をインポートし、 *path operationデコレータ* に宣言します。
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001b.py!}
+{!../../docs_src/custom_response/tutorial001b.py!}
```
-/// info | "情報"
+/// info | 情報
パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用することもできます。
@@ -38,7 +38,7 @@
///
-/// tip | "豆知識"
+/// tip | 豆知識
`ORJSONResponse` は、現在はFastAPIのみで利用可能で、Starletteでは利用できません。
@@ -52,10 +52,10 @@
* *path operation* のパラメータ `content_type` に `HTMLResponse` を渡す。
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial002.py!}
+{!../../docs_src/custom_response/tutorial002.py!}
```
-/// info | "情報"
+/// info | 情報
パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用されます。
@@ -72,16 +72,16 @@
上記と同じ例において、 `HTMLResponse` を返すと、このようになります:
```Python hl_lines="2 7 19"
-{!../../../docs_src/custom_response/tutorial003.py!}
+{!../../docs_src/custom_response/tutorial003.py!}
```
-/// warning | "注意"
+/// warning | 注意
*path operation関数* から直接返される `Response` は、OpenAPIにドキュメントされず (例えば、 `Content-Type` がドキュメントされない) 、自動的な対話的ドキュメントからも閲覧できません。
///
-/// info | "情報"
+/// info | 情報
もちろん、実際の `Content-Type` ヘッダーやステータスコードなどは、返された `Response` オブジェクトに由来しています。
@@ -98,7 +98,7 @@
例えば、このようになります:
```Python hl_lines="7 21 23"
-{!../../../docs_src/custom_response/tutorial004.py!}
+{!../../docs_src/custom_response/tutorial004.py!}
```
この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく `Response` を生成して返しています。
@@ -115,7 +115,7 @@
`Response` を使って他の何かを返せますし、カスタムのサブクラスも作れることを覚えておいてください。
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.responses import HTMLResponse` も利用できます。
@@ -139,7 +139,7 @@
FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含みます。また、media_typeに基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。
```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
+{!../../docs_src/response_directly/tutorial002.py!}
```
### `HTMLResponse`
@@ -151,7 +151,7 @@ FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含
テキストやバイトを受け取り、プレーンテキストのレスポンスを返します。
```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial005.py!}
+{!../../docs_src/custom_response/tutorial005.py!}
```
### `JSONResponse`
@@ -168,17 +168,17 @@ FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含
`ujson`を使った、代替のJSONレスポンスです。
-/// warning | "注意"
+/// warning | 注意
`ujson` は、いくつかのエッジケースの取り扱いについて、Pythonにビルトインされた実装よりも作りこまれていません。
///
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001.py!}
+{!../../docs_src/custom_response/tutorial001.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
`ORJSONResponse` のほうが高速な代替かもしれません。
@@ -189,7 +189,7 @@ FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含
HTTPリダイレクトを返します。デフォルトでは307ステータスコード (Temporary Redirect) となります。
```Python hl_lines="2 9"
-{!../../../docs_src/custom_response/tutorial006.py!}
+{!../../docs_src/custom_response/tutorial006.py!}
```
### `StreamingResponse`
@@ -197,7 +197,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
非同期なジェネレータか通常のジェネレータ・イテレータを受け取り、レスポンスボディをストリームします。
```Python hl_lines="2 14"
-{!../../../docs_src/custom_response/tutorial007.py!}
+{!../../docs_src/custom_response/tutorial007.py!}
```
#### `StreamingResponse` をファイルライクなオブジェクトとともに使う
@@ -207,10 +207,10 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
これにはクラウドストレージとの連携や映像処理など、多くのライブラリが含まれています。
```Python hl_lines="2 10-12 14"
-{!../../../docs_src/custom_response/tutorial008.py!}
+{!../../docs_src/custom_response/tutorial008.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
ここでは `async` や `await` をサポートしていない標準の `open()` を使っているので、通常の `def` でpath operationを宣言していることに注意してください。
@@ -230,7 +230,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
ファイルレスポンスには、適切な `Content-Length` 、 `Last-Modified` 、 `ETag` ヘッダーが含まれます。
```Python hl_lines="2 10"
-{!../../../docs_src/custom_response/tutorial009.py!}
+{!../../docs_src/custom_response/tutorial009.py!}
```
## デフォルトレスポンスクラス
@@ -242,10 +242,10 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
以下の例では、 **FastAPI** は、全ての *path operation* で `JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして利用します。
```Python hl_lines="2 4"
-{!../../../docs_src/custom_response/tutorial010.py!}
+{!../../docs_src/custom_response/tutorial010.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
前に見たように、 *path operation* の中で `response_class` をオーバーライドできます。
diff --git a/docs/ja/docs/advanced/index.md b/docs/ja/docs/advanced/index.md
index da3c2a2bf..22eaf6eb8 100644
--- a/docs/ja/docs/advanced/index.md
+++ b/docs/ja/docs/advanced/index.md
@@ -6,7 +6,7 @@
以降のセクションでは、チュートリアルでは説明しきれなかったオプションや設定、および機能について説明します。
-/// tip | "豆知識"
+/// tip | 豆知識
以降のセクションは、 **必ずしも"応用編"ではありません**。
diff --git a/docs/ja/docs/advanced/path-operation-advanced-configuration.md b/docs/ja/docs/advanced/path-operation-advanced-configuration.md
index ae60126cb..99428bcbe 100644
--- a/docs/ja/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/ja/docs/advanced/path-operation-advanced-configuration.md
@@ -2,7 +2,7 @@
## OpenAPI operationId
-/// warning | "注意"
+/// warning | 注意
あなたがOpenAPIの「エキスパート」でなければ、これは必要ないかもしれません。
@@ -13,7 +13,7 @@
`operation_id` は各オペレーションで一意にする必要があります。
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### *path operation関数* の名前をoperationIdとして使用する
@@ -23,16 +23,16 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
そうする場合は、すべての *path operation* を追加した後に行う必要があります。
```Python hl_lines="2 12-21 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
`app.openapi()` を手動でコールする場合、その前に`operationId`を更新する必要があります。
///
-/// warning | "注意"
+/// warning | 注意
この方法をとる場合、各 *path operation関数* が一意な名前である必要があります。
@@ -45,7 +45,7 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
生成されるOpenAPIスキーマ (つまり、自動ドキュメント生成の仕組み) から *path operation* を除外するには、 `include_in_schema` パラメータを `False` にします。
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## docstringによる説明の高度な設定
@@ -57,5 +57,5 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
ドキュメントには表示されませんが、他のツール (例えばSphinx) では残りの部分を利用できるでしょう。
```Python hl_lines="19-29"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```
diff --git a/docs/ja/docs/advanced/response-directly.md b/docs/ja/docs/advanced/response-directly.md
index 5c25471b1..dc66e238c 100644
--- a/docs/ja/docs/advanced/response-directly.md
+++ b/docs/ja/docs/advanced/response-directly.md
@@ -14,7 +14,7 @@
実際は、`Response` やそのサブクラスを返すことができます。
-/// tip | "豆知識"
+/// tip | 豆知識
`JSONResponse` それ自体は、 `Response` のサブクラスです。
@@ -35,10 +35,10 @@
このようなケースでは、レスポンスにデータを含める前に `jsonable_encoder` を使ってデータを変換できます。
```Python hl_lines="6-7 21-22"
-{!../../../docs_src/response_directly/tutorial001.py!}
+{!../../docs_src/response_directly/tutorial001.py!}
```
-/// note | "技術詳細"
+/// note | 技術詳細
また、`from starlette.responses import JSONResponse` も利用できます。
@@ -57,7 +57,7 @@
XMLを文字列にし、`Response` に含め、それを返します。
```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
+{!../../docs_src/response_directly/tutorial002.py!}
```
## 備考
diff --git a/docs/ja/docs/advanced/websockets.md b/docs/ja/docs/advanced/websockets.md
index 615f9d17c..365ceca9d 100644
--- a/docs/ja/docs/advanced/websockets.md
+++ b/docs/ja/docs/advanced/websockets.md
@@ -39,7 +39,7 @@ $ pip install websockets
しかし、これはWebSocketのサーバーサイドに焦点を当て、実用的な例を示す最も簡単な方法です。
```Python hl_lines="2 6-38 41-43"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
## `websocket` を作成する
@@ -47,10 +47,10 @@ $ pip install websockets
**FastAPI** アプリケーションで、`websocket` を作成します。
```Python hl_lines="1 46-47"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.websockets import WebSocket` を使用しても構いません.
@@ -63,7 +63,7 @@ $ pip install websockets
WebSocketルートでは、 `await` を使ってメッセージの送受信ができます。
```Python hl_lines="48-52"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
バイナリやテキストデータ、JSONデータを送受信できます。
@@ -116,10 +116,10 @@ WebSocketエンドポイントでは、`fastapi` から以下をインポート
これらは、他のFastAPI エンドポイント/*path operation* の場合と同じように機能します。
```Python hl_lines="58-65 68-83"
-{!../../../docs_src/websockets/tutorial002.py!}
+{!../../docs_src/websockets/tutorial002.py!}
```
-/// info | "情報"
+/// info | 情報
WebSocket で `HTTPException` を発生させることはあまり意味がありません。したがって、WebSocketの接続を直接閉じる方がよいでしょう。
@@ -150,7 +150,7 @@ $ uvicorn main:app --reload
* パスで使用される「Item ID」
* クエリパラメータとして使用される「Token」
-/// tip | "豆知識"
+/// tip | 豆知識
クエリ `token` は依存パッケージによって処理されることに注意してください。
@@ -165,7 +165,7 @@ $ uvicorn main:app --reload
WebSocket接続が閉じられると、 `await websocket.receive_text()` は例外 `WebSocketDisconnect` を発生させ、この例のようにキャッチして処理することができます。
```Python hl_lines="81-83"
-{!../../../docs_src/websockets/tutorial003.py!}
+{!../../docs_src/websockets/tutorial003.py!}
```
試してみるには、
@@ -180,7 +180,7 @@ WebSocket接続が閉じられると、 `await websocket.receive_text()` は例
Client #1596980209979 left the chat
```
-/// tip | "豆知識"
+/// tip | 豆知識
上記のアプリは、複数の WebSocket 接続に対してメッセージを処理し、ブロードキャストする方法を示すための最小限のシンプルな例です。
diff --git a/docs/ja/docs/alternatives.md b/docs/ja/docs/alternatives.md
index 343ae4ed8..8129a7002 100644
--- a/docs/ja/docs/alternatives.md
+++ b/docs/ja/docs/alternatives.md
@@ -30,13 +30,13 @@ Mozilla、Red Hat、Eventbrite など多くの企業で利用されています
これは**自動的なAPIドキュメント生成**の最初の例であり、これは**FastAPI**に向けた「調査」を触発した最初のアイデアの一つでした。
-/// note | "備考"
+/// note | 備考
Django REST Framework は Tom Christie によって作成されました。StarletteとUvicornの生みの親であり、**FastAPI**のベースとなっています。
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
自動でAPIドキュメントを生成するWebユーザーインターフェースを持っている点。
@@ -56,7 +56,7 @@ Flask は「マイクロフレームワーク」であり、データベース
Flaskのシンプルさを考えると、APIを構築するのに適しているように思えました。次に見つけるべきは、Flask 用の「Django REST Framework」でした。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
マイクロフレームワークであること。ツールやパーツを目的に合うように簡単に組み合わせられる点。
@@ -98,7 +98,7 @@ def read_url():
`requests.get(...)` と`@app.get(...)` には類似点が見受けられます。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
* シンプルで直感的なAPIを持っている点。
* HTTPメソッド名を直接利用し、単純で直感的である。
@@ -118,7 +118,7 @@ def read_url():
そのため、バージョン2.0では「Swagger」、バージョン3以上では「OpenAPI」と表記するのが一般的です。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
独自のスキーマの代わりに、API仕様のオープンな標準を採用しました。
@@ -147,7 +147,7 @@ APIが必要とするもう一つの大きな機能はデータのバリデー
しかし、それはPythonの型ヒントが存在する前に作られたものです。そのため、すべてのスキーマを定義するためには、Marshmallowが提供する特定のユーティリティやクラスを使用する必要があります。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
コードで「スキーマ」を定義し、データの型やバリデーションを自動で提供する点。
@@ -163,13 +163,13 @@ WebargsはFlaskをはじめとするいくつかのフレームワークの上
素晴らしいツールで、私も**FastAPI**を持つ前はよく使っていました。
-/// info | "情報"
+/// info | 情報
Webargsは、Marshmallowと同じ開発者により作られました。
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
受信したデータに対する自動的なバリデーションを持っている点。
@@ -193,13 +193,13 @@ Flask, Starlette, Responderなどにおいてはそのように動作します
エディタでは、この問題を解決することはできません。また、パラメータやMarshmallowスキーマを変更したときに、YAMLのdocstringを変更するのを忘れてしまうと、生成されたスキーマが古くなってしまいます。
-/// info | "情報"
+/// info | 情報
APISpecは、Marshmallowと同じ開発者により作成されました。
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
OpenAPIという、APIについてのオープンな標準をサポートしている点。
@@ -225,13 +225,13 @@ Flask、Flask-apispec、Marshmallow、Webargsの組み合わせは、**FastAPI**
そして、これらのフルスタックジェネレーターは、[**FastAPI** Project Generators](project-generation.md){.internal-link target=_blank}の元となっていました。
-/// info | "情報"
+/// info | 情報
Flask-apispecはMarshmallowと同じ開発者により作成されました。
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
シリアライゼーションとバリデーションを定義したコードから、OpenAPIスキーマを自動的に生成する点。
@@ -251,7 +251,7 @@ Angular 2にインスピレーションを受けた、統合された依存性
入れ子になったモデルをうまく扱えません。そのため、リクエストのJSONボディが内部フィールドを持つJSONオブジェクトで、それが順番にネストされたJSONオブジェクトになっている場合、適切にドキュメント化やバリデーションをすることができません。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
素晴らしいエディターの補助を得るために、Pythonの型ヒントを利用している点。
@@ -263,7 +263,7 @@ Angular 2にインスピレーションを受けた、統合された依存性
`asyncio`に基づいた、Pythonのフレームワークの中でも非常に高速なものの一つです。Flaskと非常に似た作りになっています。
-/// note | "技術詳細"
+/// note | 技術詳細
Pythonの`asyncio`ループの代わりに、`uvloop`が利用されています。それにより、非常に高速です。
@@ -271,7 +271,7 @@ Pythonの`asyncio`ループの代わりに、`uvloop`が利用されています
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
物凄い性能を出す方法を見つけた点。
@@ -289,7 +289,7 @@ Pythonのウェブフレームワーク標準規格 (WSGI) を使用していま
そのため、データのバリデーション、シリアライゼーション、ドキュメント化は、自動的にできずコードの中で行わなければなりません。あるいは、HugのようにFalconの上にフレームワークとして実装されなければなりません。このような分断は、パラメータとして1つのリクエストオブジェクトと1つのレスポンスオブジェクトを持つというFalconのデザインにインスピレーションを受けた他のフレームワークでも起こります。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
素晴らしい性能を得るための方法を見つけた点。
@@ -315,7 +315,7 @@ Pydanticのようなデータのバリデーション、シリアライゼーシ
ルーティングは一つの場所で宣言され、他の場所で宣言された関数を使用します (エンドポイントを扱う関数のすぐ上に配置できるデコレータを使用するのではなく) 。これはFlask (やStarlette) よりも、Djangoに近いです。これは、比較的緊密に結合されているものをコードの中で分離しています。
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
モデルの属性の「デフォルト」値を使用したデータ型の追加バリデーションを定義します。これはエディタの補助を改善するもので、以前はPydanticでは利用できませんでした。
@@ -337,13 +337,13 @@ OpenAPIやJSON Schemaのような標準に基づいたものではありませ
以前のPythonの同期型Webフレームワーク標準 (WSGI) をベースにしているため、Websocketなどは扱えませんが、それでも高性能です。
-/// info | "情報"
+/// info | 情報
HugはTimothy Crosleyにより作成されました。彼は`isort`など、Pythonのファイル内のインポートの並び替えを自動的におこうなう素晴らしいツールの開発者です。
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
HugはAPIStarに部分的なインスピレーションを与えており、私が発見した中ではAPIStarと同様に最も期待の持てるツールの一つでした。
@@ -377,7 +377,7 @@ Hugは、**FastAPI**がヘッダーやクッキーを設定するために関数
今ではAPIStarはOpenAPI仕様を検証するためのツールセットであり、ウェブフレームワークではありません。
-/// info | "情報"
+/// info | 情報
APIStarはTom Christieにより開発されました。以下の開発者でもあります:
@@ -387,7 +387,7 @@ APIStarはTom Christieにより開発されました。以下の開発者でも
///
-/// check | "**FastAPI**へ与えたインスピレーション"
+/// check | **FastAPI**へ与えたインスピレーション
存在そのもの。
@@ -411,7 +411,7 @@ Pydanticは、Pythonの型ヒントを元にデータのバリデーション、
Marshmallowに匹敵しますが、ベンチマークではMarshmallowよりも高速です。また、Pythonの型ヒントを元にしているので、エディタの補助が素晴らしいです。
-/// check | "**FastAPI**での使用用途"
+/// check | **FastAPI**での使用用途
データのバリデーション、データのシリアライゼーション、自動的なモデルの (JSON Schemaに基づいた) ドキュメント化の全てを扱えます。
@@ -447,7 +447,7 @@ Starletteは基本的なWebマイクロフレームワークの機能をすべ
これは **FastAPI** が追加する主な機能の一つで、すべての機能は Pythonの型ヒントに基づいています (Pydanticを使用しています) 。これに加えて、依存性注入の仕組み、セキュリティユーティリティ、OpenAPIスキーマ生成などがあります。
-/// note | "技術詳細"
+/// note | 技術詳細
ASGIはDjangoのコアチームメンバーにより開発された新しい「標準」です。まだ「Pythonの標準 (PEP) 」ではありませんが、現在そうなるように進めています。
@@ -455,7 +455,7 @@ ASGIはDjangoのコアチームメンバーにより開発された新しい「
///
-/// check | "**FastAPI**での使用用途"
+/// check | **FastAPI**での使用用途
webに関するコアな部分を全て扱います。その上に機能を追加します。
@@ -473,7 +473,7 @@ Uvicornは非常に高速なASGIサーバーで、uvloopとhttptoolsにより構
Starletteや**FastAPI**のサーバーとして推奨されています。
-/// check | "**FastAPI**が推奨する理由"
+/// check | **FastAPI**が推奨する理由
**FastAPI**アプリケーションを実行するメインのウェブサーバーである点。
diff --git a/docs/ja/docs/async.md b/docs/ja/docs/async.md
index ce9dac56f..d1da1f82d 100644
--- a/docs/ja/docs/async.md
+++ b/docs/ja/docs/async.md
@@ -21,7 +21,7 @@ async def read_results():
return results
```
-/// note | "備考"
+/// note | 備考
`async def` を使用して作成された関数の内部でしか `await` は使用できません。
@@ -358,7 +358,7 @@ async def read_burgers():
## 非常に発展的な技術的詳細
-/// warning | "注意"
+/// warning | 注意
恐らくスキップしても良いでしょう。
diff --git a/docs/ja/docs/contributing.md b/docs/ja/docs/contributing.md
index 86926b213..3ee742ec2 100644
--- a/docs/ja/docs/contributing.md
+++ b/docs/ja/docs/contributing.md
@@ -95,7 +95,7 @@ some/directory/fastapi/env/bin/pip
`env/bin/pip`に`pip`バイナリが表示される場合は、正常に機能しています。🎉
-/// tip | "豆知識"
+/// tip | 豆知識
この環境で`pip`を使って新しいパッケージをインストールするたびに、仮想環境を再度有効化します。
@@ -165,7 +165,7 @@ $ bash scripts/format-imports.sh
そして、翻訳を処理するためのツール/スクリプトが、`./scripts/docs.py`に用意されています。
-/// tip | "豆知識"
+/// tip | 豆知識
`./scripts/docs.py`のコードを見る必要はなく、コマンドラインからただ使うだけです。
@@ -254,7 +254,7 @@ Uvicornはデフォルトでポート`8000`を使用するため、ポート`800
* あなたの言語の今あるプルリクエストを確認し、変更や承認をするレビューを追加します。
-/// tip | "豆知識"
+/// tip | 豆知識
すでにあるプルリクエストに修正提案つきのコメントを追加できます。
@@ -282,7 +282,7 @@ Uvicornはデフォルトでポート`8000`を使用するため、ポート`800
スペイン語の場合、2文字のコードは`es`です。したがって、スペイン語のディレクトリは`docs/es/`です。
-/// tip | "豆知識"
+/// tip | 豆知識
メイン (「公式」) 言語は英語で、`docs/en/`にあります。
@@ -323,7 +323,7 @@ docs/en/docs/features.md
docs/es/docs/features.md
```
-/// tip | "豆知識"
+/// tip | 豆知識
パスとファイル名の変更は、`en`から`es`への言語コードだけであることに注意してください。
@@ -398,7 +398,7 @@ Updating en
これで、新しく作成された`docs/ht/`ディレクトリをコードエディターから確認できます。
-/// tip | "豆知識"
+/// tip | 豆知識
翻訳を追加する前に、これだけで最初のプルリクエストを作成し、新しい言語の設定をセットアップします。
diff --git a/docs/ja/docs/deployment/manually.md b/docs/ja/docs/deployment/manually.md
index c17e63728..4ea6bd8ff 100644
--- a/docs/ja/docs/deployment/manually.md
+++ b/docs/ja/docs/deployment/manually.md
@@ -20,7 +20,7 @@ $ pip install "uvicorn[standard]"
////
-/// tip | "豆知識"
+/// tip | 豆知識
`standard` を加えることで、Uvicornがインストールされ、いくつかの推奨される依存関係を利用するようになります。
diff --git a/docs/ja/docs/deployment/versions.md b/docs/ja/docs/deployment/versions.md
index 941ddb71b..7575fc4f7 100644
--- a/docs/ja/docs/deployment/versions.md
+++ b/docs/ja/docs/deployment/versions.md
@@ -42,7 +42,7 @@ PoetryやPipenvなど、他のインストール管理ツールを使用して
FastAPIでは「パッチ」バージョンはバグ修正と非破壊的な変更に留めるという規約に従っています。
-/// tip | "豆知識"
+/// tip | 豆知識
「パッチ」は最後の数字を指します。例えば、`0.2.3` ではパッチバージョンは `3` です。
@@ -56,7 +56,7 @@ fastapi>=0.45.0,<0.46.0
破壊的な変更と新機能実装は「マイナー」バージョンで加えられます。
-/// tip | "豆知識"
+/// tip | 豆知識
「マイナー」は真ん中の数字です。例えば、`0.2.3` ではマイナーバージョンは `2` です。
diff --git a/docs/ja/docs/features.md b/docs/ja/docs/features.md
index 73c0192c7..4024590cf 100644
--- a/docs/ja/docs/features.md
+++ b/docs/ja/docs/features.md
@@ -62,7 +62,7 @@ second_user_data = {
my_second_user: User = User(**second_user_data)
```
-/// info | "情報"
+/// info | 情報
`**second_user_data` は以下を意味します:
diff --git a/docs/ja/docs/how-to/conditional-openapi.md b/docs/ja/docs/how-to/conditional-openapi.md
index b892ed6c6..053d481f7 100644
--- a/docs/ja/docs/how-to/conditional-openapi.md
+++ b/docs/ja/docs/how-to/conditional-openapi.md
@@ -30,7 +30,7 @@
例えば、
```Python hl_lines="6 11"
-{!../../../docs_src/conditional_openapi/tutorial001.py!}
+{!../../docs_src/conditional_openapi/tutorial001.py!}
```
ここでは `openapi_url` の設定を、デフォルトの `"/openapi.json"` のまま宣言しています。
diff --git a/docs/ja/docs/index.md b/docs/ja/docs/index.md
index 72a0e98bc..682c94e83 100644
--- a/docs/ja/docs/index.md
+++ b/docs/ja/docs/index.md
@@ -91,7 +91,7 @@ FastAPI は、Pythonの標準である型ヒントに基づいてPython 以降
"_正直、超堅実で洗練されているように見えます。いろんな意味で、それは私がハグしたかったものです。_"
-
+
---
diff --git a/docs/ja/docs/python-types.md b/docs/ja/docs/python-types.md
index 730a209ab..77ddf4654 100644
--- a/docs/ja/docs/python-types.md
+++ b/docs/ja/docs/python-types.md
@@ -12,7 +12,7 @@
しかしたとえまったく **FastAPI** を使用しない場合でも、それらについて少し学ぶことで利点を得ることができるでしょう。
-/// note | "備考"
+/// note | 備考
もしあなたがPythonの専門家で、すでに型ヒントについてすべて知っているのであれば、次の章まで読み飛ばしてください。
@@ -23,7 +23,7 @@
簡単な例から始めてみましょう:
```Python
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
このプログラムを実行すると以下が出力されます:
@@ -39,7 +39,7 @@ John Doe
* 真ん中にスペースを入れて連結します。
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
### 編集
@@ -83,7 +83,7 @@ John Doe
それが「型ヒント」です:
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
+{!../../docs_src/python_types/tutorial002.py!}
```
これは、以下のようにデフォルト値を宣言するのと同じではありません:
@@ -113,7 +113,7 @@ John Doe
この関数を見てください。すでに型ヒントを持っています:
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
+{!../../docs_src/python_types/tutorial003.py!}
```
エディタは変数の型を知っているので、補完だけでなく、エラーチェックをすることもできます。
@@ -123,7 +123,7 @@ John Doe
これで`age`を`str(age)`で文字列に変換して修正する必要があることがわかります:
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
+{!../../docs_src/python_types/tutorial004.py!}
```
## 型の宣言
@@ -144,7 +144,7 @@ John Doe
* `bytes`
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
+{!../../docs_src/python_types/tutorial005.py!}
```
### 型パラメータを持つジェネリック型
@@ -162,7 +162,7 @@ John Doe
`typing`から`List`をインポートします(大文字の`L`を含む):
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial006.py!}
+{!../../docs_src/python_types/tutorial006.py!}
```
同じようにコロン(`:`)の構文で変数を宣言します。
@@ -172,10 +172,10 @@ John Doe
リストはいくつかの内部の型を含む型なので、それらを角括弧で囲んでいます。
```Python hl_lines="4"
-{!../../../docs_src/python_types/tutorial006.py!}
+{!../../docs_src/python_types/tutorial006.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
角括弧内の内部の型は「型パラメータ」と呼ばれています。
@@ -200,7 +200,7 @@ John Doe
`tuple`と`set`の宣言も同様です:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial007.py!}
+{!../../docs_src/python_types/tutorial007.py!}
```
つまり:
@@ -218,7 +218,7 @@ John Doe
2番目の型パラメータは`dict`の値です。
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial008.py!}
+{!../../docs_src/python_types/tutorial008.py!}
```
つまり:
@@ -232,7 +232,7 @@ John Doe
また、`Optional`を使用して、変数が`str`のような型を持つことを宣言することもできますが、それは「オプション」であり、`None`にすることもできます。
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009.py!}
```
ただの`str`の代わりに`Optional[str]`を使用することで、エディタは値が常に`str`であると仮定している場合に実際には`None`である可能性があるエラーを検出するのに役立ちます。
@@ -257,13 +257,13 @@ John Doe
例えば、`Person`クラスという名前のクラスがあるとしましょう:
```Python hl_lines="1 2 3"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
変数の型を`Person`として宣言することができます:
```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
そして、再び、すべてのエディタのサポートを得ることができます:
@@ -285,10 +285,10 @@ John Doe
Pydanticの公式ドキュメントから引用:
```Python
-{!../../../docs_src/python_types/tutorial011.py!}
+{!../../docs_src/python_types/tutorial011.py!}
```
-/// info | "情報"
+/// info | 情報
Pydanticについてより学びたい方はドキュメントを参照してください.
@@ -320,7 +320,7 @@ Pydanticについてより学びたい方は`mypy`のチートシートを参照してください
diff --git a/docs/ja/docs/tutorial/background-tasks.md b/docs/ja/docs/tutorial/background-tasks.md
index 6094c370f..6f9340817 100644
--- a/docs/ja/docs/tutorial/background-tasks.md
+++ b/docs/ja/docs/tutorial/background-tasks.md
@@ -16,7 +16,7 @@
まず初めに、`BackgroundTasks` をインポートし、` BackgroundTasks` の型宣言と共に、*path operation 関数* のパラメーターを定義します:
```Python hl_lines="1 13"
-{!../../../docs_src/background_tasks/tutorial001.py!}
+{!../../docs_src/background_tasks/tutorial001.py!}
```
**FastAPI** は、`BackgroundTasks` 型のオブジェクトを作成し、そのパラメーターに渡します。
@@ -34,7 +34,7 @@
また、書き込み操作では `async` と `await` を使用しないため、通常の `def` で関数を定義します。
```Python hl_lines="6-9"
-{!../../../docs_src/background_tasks/tutorial001.py!}
+{!../../docs_src/background_tasks/tutorial001.py!}
```
## バックグラウンドタスクの追加
@@ -42,7 +42,7 @@
*path operations 関数* 内で、`.add_task()` メソッドを使用してタスク関数を *background tasks* オブジェクトに渡します。
```Python hl_lines="14"
-{!../../../docs_src/background_tasks/tutorial001.py!}
+{!../../docs_src/background_tasks/tutorial001.py!}
```
`.add_task()` は以下の引数を受け取ります:
@@ -58,7 +58,7 @@
**FastAPI** は、それぞれの場合の処理方法と同じオブジェクトの再利用方法を知っているため、すべてのバックグラウンドタスクがマージされ、バックグラウンドで後で実行されます。
```Python hl_lines="13 15 22 25"
-{!../../../docs_src/background_tasks/tutorial002.py!}
+{!../../docs_src/background_tasks/tutorial002.py!}
```
この例では、レスポンスが送信された *後* にメッセージが `log.txt` ファイルに書き込まれます。
diff --git a/docs/ja/docs/tutorial/body-fields.md b/docs/ja/docs/tutorial/body-fields.md
index b9f6d694b..5b3b3622b 100644
--- a/docs/ja/docs/tutorial/body-fields.md
+++ b/docs/ja/docs/tutorial/body-fields.md
@@ -7,10 +7,10 @@
まず、以下のようにインポートします:
```Python hl_lines="4"
-{!../../../docs_src/body_fields/tutorial001.py!}
+{!../../docs_src/body_fields/tutorial001.py!}
```
-/// warning | "注意"
+/// warning | 注意
`Field`は他の全てのもの(`Query`、`Path`、`Body`など)とは違い、`fastapi`からではなく、`pydantic`から直接インポートされていることに注意してください。
@@ -21,12 +21,12 @@
以下のように`Field`をモデルの属性として使用することができます:
```Python hl_lines="11 12 13 14"
-{!../../../docs_src/body_fields/tutorial001.py!}
+{!../../docs_src/body_fields/tutorial001.py!}
```
`Field`は`Query`や`Path`、`Body`と同じように動作し、全く同様のパラメータなどを持ちます。
-/// note | "技術詳細"
+/// note | 技術詳細
実際には次に見る`Query`や`Path`などは、共通の`Param`クラスのサブクラスのオブジェクトを作成しますが、それ自体はPydanticの`FieldInfo`クラスのサブクラスです。
@@ -38,7 +38,7 @@
///
-/// tip | "豆知識"
+/// tip | 豆知識
型、デフォルト値、`Field`を持つ各モデルの属性が、`Path`や`Query`、`Body`の代わりに`Field`を持つ、*path operation 関数の*パラメータと同じ構造になっていることに注目してください。
diff --git a/docs/ja/docs/tutorial/body-multiple-params.md b/docs/ja/docs/tutorial/body-multiple-params.md
index c051fde24..982c23565 100644
--- a/docs/ja/docs/tutorial/body-multiple-params.md
+++ b/docs/ja/docs/tutorial/body-multiple-params.md
@@ -9,10 +9,10 @@
また、デフォルトの`None`を設定することで、ボディパラメータをオプションとして宣言することもできます:
```Python hl_lines="19 20 21"
-{!../../../docs_src/body_multiple_params/tutorial001.py!}
+{!../../docs_src/body_multiple_params/tutorial001.py!}
```
-/// note | "備考"
+/// note | 備考
この場合、ボディから取得する`item`はオプションであることに注意してください。デフォルト値は`None`です。
@@ -34,7 +34,7 @@
しかし、`item`と`user`のように複数のボディパラメータを宣言することもできます:
```Python hl_lines="22"
-{!../../../docs_src/body_multiple_params/tutorial002.py!}
+{!../../docs_src/body_multiple_params/tutorial002.py!}
```
この場合、**FastAPI**は関数内に複数のボディパラメータ(Pydanticモデルである2つのパラメータ)があることに気付きます。
@@ -56,7 +56,7 @@
}
```
-/// note | "備考"
+/// note | 備考
以前と同じように`item`が宣言されていたにもかかわらず、`item`はキー`item`を持つボディの内部にあることが期待されていることに注意してください。
@@ -78,7 +78,7 @@
```Python hl_lines="23"
-{!../../../docs_src/body_multiple_params/tutorial003.py!}
+{!../../docs_src/body_multiple_params/tutorial003.py!}
```
この場合、**FastAPI** は以下のようなボディを期待します:
@@ -115,10 +115,10 @@ q: str = None
以下において:
```Python hl_lines="27"
-{!../../../docs_src/body_multiple_params/tutorial004.py!}
+{!../../docs_src/body_multiple_params/tutorial004.py!}
```
-/// info | "情報"
+/// info | 情報
`Body`もまた、後述する `Query` や `Path` などと同様に、すべての検証パラメータとメタデータパラメータを持っています。
@@ -139,7 +139,7 @@ item: Item = Body(..., embed=True)
以下において:
```Python hl_lines="17"
-{!../../../docs_src/body_multiple_params/tutorial005.py!}
+{!../../docs_src/body_multiple_params/tutorial005.py!}
```
この場合、**FastAPI** は以下のようなボディを期待します:
diff --git a/docs/ja/docs/tutorial/body-nested-models.md b/docs/ja/docs/tutorial/body-nested-models.md
index 59ee67295..dc2d5e81a 100644
--- a/docs/ja/docs/tutorial/body-nested-models.md
+++ b/docs/ja/docs/tutorial/body-nested-models.md
@@ -7,7 +7,7 @@
属性をサブタイプとして定義することができます。例えば、Pythonの`list`は以下のように定義できます:
```Python hl_lines="12"
-{!../../../docs_src/body_nested_models/tutorial001.py!}
+{!../../docs_src/body_nested_models/tutorial001.py!}
```
これにより、各項目の型は宣言されていませんが、`tags`はある項目のリストになります。
@@ -21,7 +21,7 @@
まず、Pythonの標準の`typing`モジュールから`List`をインポートします:
```Python hl_lines="1"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
+{!../../docs_src/body_nested_models/tutorial002.py!}
```
### タイプパラメータを持つ`List`の宣言
@@ -44,7 +44,7 @@ my_list: List[str]
そのため、以下の例では`tags`を具体的な「文字列のリスト」にすることができます:
```Python hl_lines="14"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
+{!../../docs_src/body_nested_models/tutorial002.py!}
```
## セット型
@@ -56,7 +56,7 @@ my_list: List[str]
そのため、以下のように、`Set`をインポートして`str`の`set`として`tags`を宣言することができます:
```Python hl_lines="1 14"
-{!../../../docs_src/body_nested_models/tutorial003.py!}
+{!../../docs_src/body_nested_models/tutorial003.py!}
```
これを使えば、データが重複しているリクエストを受けた場合でも、ユニークな項目のセットに変換されます。
@@ -80,7 +80,7 @@ Pydanticモデルの各属性には型があります。
例えば、`Image`モデルを定義することができます:
```Python hl_lines="9 10 11"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
+{!../../docs_src/body_nested_models/tutorial004.py!}
```
### サブモデルを型として使用
@@ -88,7 +88,7 @@ Pydanticモデルの各属性には型があります。
そして、それを属性の型として使用することができます:
```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
+{!../../docs_src/body_nested_models/tutorial004.py!}
```
これは **FastAPI** が以下のようなボディを期待することを意味します:
@@ -123,7 +123,7 @@ Pydanticモデルの各属性には型があります。
例えば、`Image`モデルのように`url`フィールドがある場合、`str`の代わりにPydanticの`HttpUrl`を指定することができます:
```Python hl_lines="4 10"
-{!../../../docs_src/body_nested_models/tutorial005.py!}
+{!../../docs_src/body_nested_models/tutorial005.py!}
```
文字列は有効なURLであることが確認され、そのようにJSONスキーマ・OpenAPIで文書化されます。
@@ -133,7 +133,7 @@ Pydanticモデルの各属性には型があります。
Pydanticモデルを`list`や`set`などのサブタイプとして使用することもできます:
```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial006.py!}
+{!../../docs_src/body_nested_models/tutorial006.py!}
```
これは、次のようなJSONボディを期待します(変換、検証、ドキュメントなど):
@@ -162,7 +162,7 @@ Pydanticモデルを`list`や`set`などのサブタイプとして使用する
}
```
-/// info | "情報"
+/// info | 情報
`images`キーが画像オブジェクトのリストを持つようになったことに注目してください。
@@ -173,10 +173,10 @@ Pydanticモデルを`list`や`set`などのサブタイプとして使用する
深くネストされた任意のモデルを定義することができます:
```Python hl_lines="9 14 20 23 27"
-{!../../../docs_src/body_nested_models/tutorial007.py!}
+{!../../docs_src/body_nested_models/tutorial007.py!}
```
-/// info | "情報"
+/// info | 情報
`Offer`は`Item`のリストであり、オプションの`Image`のリストを持っていることに注目してください。
@@ -193,7 +193,7 @@ images: List[Image]
以下のように:
```Python hl_lines="15"
-{!../../../docs_src/body_nested_models/tutorial008.py!}
+{!../../docs_src/body_nested_models/tutorial008.py!}
```
## あらゆる場所でのエディタサポート
@@ -225,10 +225,10 @@ Pydanticモデルではなく、`dict`を直接使用している場合はこの
この場合、`int`のキーと`float`の値を持つものであれば、どんな`dict`でも受け入れることができます:
```Python hl_lines="15"
-{!../../../docs_src/body_nested_models/tutorial009.py!}
+{!../../docs_src/body_nested_models/tutorial009.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
JSONはキーとして`str`しかサポートしていないことに注意してください。
diff --git a/docs/ja/docs/tutorial/body-updates.md b/docs/ja/docs/tutorial/body-updates.md
index 672a03a64..fcaeb0d16 100644
--- a/docs/ja/docs/tutorial/body-updates.md
+++ b/docs/ja/docs/tutorial/body-updates.md
@@ -7,7 +7,7 @@
`jsonable_encoder`を用いて、入力データをJSON形式で保存できるデータに変換することができます(例:NoSQLデータベース)。例えば、`datetime`を`str`に変換します。
```Python hl_lines="30 31 32 33 34 35"
-{!../../../docs_src/body_updates/tutorial001.py!}
+{!../../docs_src/body_updates/tutorial001.py!}
```
既存のデータを置き換えるべきデータを受け取るために`PUT`は使用されます。
@@ -34,7 +34,7 @@
つまり、更新したいデータだけを送信して、残りはそのままにしておくことができます。
-/// note | "備考"
+/// note | 備考
`PATCH`は`PUT`よりもあまり使われておらず、知られていません。
@@ -57,7 +57,7 @@
これを使うことで、デフォルト値を省略して、設定された(リクエストで送られた)データのみを含む`dict`を生成することができます:
```Python hl_lines="34"
-{!../../../docs_src/body_updates/tutorial002.py!}
+{!../../docs_src/body_updates/tutorial002.py!}
```
### Pydanticの`update`パラメータ
@@ -67,7 +67,7 @@
`stored_item_model.copy(update=update_data)`のように:
```Python hl_lines="35"
-{!../../../docs_src/body_updates/tutorial002.py!}
+{!../../docs_src/body_updates/tutorial002.py!}
```
### 部分的更新のまとめ
@@ -86,10 +86,10 @@
* 更新されたモデルを返します。
```Python hl_lines="30 31 32 33 34 35 36 37"
-{!../../../docs_src/body_updates/tutorial002.py!}
+{!../../docs_src/body_updates/tutorial002.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
実際には、HTTPの`PUT`操作でも同じテクニックを使用することができます。
@@ -97,7 +97,7 @@
///
-/// note | "備考"
+/// note | 備考
入力モデルがまだ検証されていることに注目してください。
diff --git a/docs/ja/docs/tutorial/body.md b/docs/ja/docs/tutorial/body.md
index 017ff8986..277ee79c8 100644
--- a/docs/ja/docs/tutorial/body.md
+++ b/docs/ja/docs/tutorial/body.md
@@ -8,7 +8,7 @@ APIはほとんどの場合 **レスポンス** ボディを送らなければ
**リクエスト** ボディを宣言するために Pydantic モデルを使用します。そして、その全てのパワーとメリットを利用します。
-/// info | "情報"
+/// info | 情報
データを送るには、`POST` (もっともよく使われる)、`PUT`、`DELETE` または `PATCH` を使うべきです。
@@ -23,7 +23,7 @@ GET リクエストでボディを送信することは、仕様では未定義
ます初めに、 `pydantic` から `BaseModel` をインポートする必要があります:
```Python hl_lines="2"
-{!../../../docs_src/body/tutorial001.py!}
+{!../../docs_src/body/tutorial001.py!}
```
## データモデルの作成
@@ -33,7 +33,7 @@ GET リクエストでボディを送信することは、仕様では未定義
すべての属性にpython標準の型を使用します:
```Python hl_lines="5-9"
-{!../../../docs_src/body/tutorial001.py!}
+{!../../docs_src/body/tutorial001.py!}
```
クエリパラメータの宣言と同様に、モデル属性がデフォルト値をもつとき、必須な属性ではなくなります。それ以外は必須になります。オプショナルな属性にしたい場合は `None` を使用してください。
@@ -63,7 +63,7 @@ GET リクエストでボディを送信することは、仕様では未定義
*パスオペレーション* に加えるために、パスパラメータやクエリパラメータと同じ様に宣言します:
```Python hl_lines="16"
-{!../../../docs_src/body/tutorial001.py!}
+{!../../docs_src/body/tutorial001.py!}
```
...そして、作成したモデル `Item` で型を宣言します。
@@ -113,7 +113,7 @@ GET リクエストでボディを送信することは、仕様では未定義
-/// tip | "豆知識"
+/// tip | 豆知識
PyCharmエディタを使用している場合は、Pydantic PyCharm Pluginが使用可能です。
@@ -132,7 +132,7 @@ GET リクエストでボディを送信することは、仕様では未定義
関数内部で、モデルの全ての属性に直接アクセスできます:
```Python hl_lines="19"
-{!../../../docs_src/body/tutorial002.py!}
+{!../../docs_src/body/tutorial002.py!}
```
## リクエストボディ + パスパラメータ
@@ -142,7 +142,7 @@ GET リクエストでボディを送信することは、仕様では未定義
**FastAPI** はパスパラメータである関数パラメータは**パスから受け取り**、Pydanticモデルによって宣言された関数パラメータは**リクエストボディから受け取る**ということを認識します。
```Python hl_lines="15-16"
-{!../../../docs_src/body/tutorial003.py!}
+{!../../docs_src/body/tutorial003.py!}
```
## リクエストボディ + パスパラメータ + クエリパラメータ
@@ -152,7 +152,7 @@ GET リクエストでボディを送信することは、仕様では未定義
**FastAPI** はそれぞれを認識し、適切な場所からデータを取得します。
```Python hl_lines="16"
-{!../../../docs_src/body/tutorial004.py!}
+{!../../docs_src/body/tutorial004.py!}
```
関数パラメータは以下の様に認識されます:
@@ -161,7 +161,7 @@ GET リクエストでボディを送信することは、仕様では未定義
* パラメータが**単数型** (`int`、`float`、`str`、`bool` など)の場合は**クエリ**パラメータとして解釈されます。
* パラメータが **Pydantic モデル**型で宣言された場合、リクエスト**ボディ**として解釈されます。
-/// note | "備考"
+/// note | 備考
FastAPIは、`= None`があるおかげで、`q`がオプショナルだとわかります。
diff --git a/docs/ja/docs/tutorial/cookie-params.md b/docs/ja/docs/tutorial/cookie-params.md
index 212885209..7f029b483 100644
--- a/docs/ja/docs/tutorial/cookie-params.md
+++ b/docs/ja/docs/tutorial/cookie-params.md
@@ -7,7 +7,7 @@
まず、`Cookie`をインポートします:
```Python hl_lines="3"
-{!../../../docs_src/cookie_params/tutorial001.py!}
+{!../../docs_src/cookie_params/tutorial001.py!}
```
## `Cookie`のパラメータを宣言
@@ -17,10 +17,10 @@
最初の値がデフォルト値で、追加の検証パラメータや注釈パラメータをすべて渡すことができます:
```Python hl_lines="9"
-{!../../../docs_src/cookie_params/tutorial001.py!}
+{!../../docs_src/cookie_params/tutorial001.py!}
```
-/// note | "技術詳細"
+/// note | 技術詳細
`Cookie`は`Path`と`Query`の「姉妹」クラスです。また、同じ共通の`Param`クラスを継承しています。
@@ -28,7 +28,7 @@
///
-/// info | "情報"
+/// info | 情報
クッキーを宣言するには、`Cookie`を使う必要があります。なぜなら、そうしないとパラメータがクエリのパラメータとして解釈されてしまうからです。
diff --git a/docs/ja/docs/tutorial/cors.md b/docs/ja/docs/tutorial/cors.md
index 738240342..9834a460b 100644
--- a/docs/ja/docs/tutorial/cors.md
+++ b/docs/ja/docs/tutorial/cors.md
@@ -47,7 +47,7 @@
* 特定のHTTPヘッダー、またはワイルドカード `"*"`を使用してすべて許可。
```Python hl_lines="2 6-11 13-19"
-{!../../../docs_src/cors/tutorial001.py!}
+{!../../docs_src/cors/tutorial001.py!}
```
`CORSMiddleware` 実装のデフォルトのパラメータはCORSに関して制限を与えるものになっているので、ブラウザにドメインを跨いで特定のオリジン、メソッド、またはヘッダーを使用可能にするためには、それらを明示的に有効にする必要があります
@@ -78,7 +78,7 @@
CORSについてより詳しい情報は、Mozilla CORS documentation を参照して下さい。
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.middleware.cors import CORSMiddleware` も使用できます。
diff --git a/docs/ja/docs/tutorial/debugging.md b/docs/ja/docs/tutorial/debugging.md
index 06b8ad277..7413332a8 100644
--- a/docs/ja/docs/tutorial/debugging.md
+++ b/docs/ja/docs/tutorial/debugging.md
@@ -7,7 +7,7 @@ Visual Studio CodeやPyCharmなどを使用して、エディター上でデバ
FastAPIアプリケーション上で、`uvicorn` を直接インポートして実行します:
```Python hl_lines="1 15"
-{!../../../docs_src/debugging/tutorial001.py!}
+{!../../docs_src/debugging/tutorial001.py!}
```
### `__name__ == "__main__"` について
@@ -74,7 +74,7 @@ from myapp import app
は実行されません。
-/// info | "情報"
+/// info | 情報
より詳しい情報は、公式Pythonドキュメントを参照してください。
diff --git a/docs/ja/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/ja/docs/tutorial/dependencies/classes-as-dependencies.md
index 69b67d042..55885a61f 100644
--- a/docs/ja/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/ja/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -7,7 +7,7 @@
前の例では、依存関係("dependable")から`dict`を返していました:
```Python hl_lines="9"
-{!../../../docs_src/dependencies/tutorial001.py!}
+{!../../docs_src/dependencies/tutorial001.py!}
```
しかし、*path operation関数*のパラメータ`commons`に`dict`が含まれています。
@@ -72,19 +72,19 @@ FastAPIが実際にチェックしているのは、それが「呼び出し可
そこで、上で紹介した依存関係の`common_parameters`を`CommonQueryParams`クラスに変更します:
```Python hl_lines="11 12 13 14 15"
-{!../../../docs_src/dependencies/tutorial002.py!}
+{!../../docs_src/dependencies/tutorial002.py!}
```
クラスのインスタンスを作成するために使用される`__init__`メソッドに注目してください:
```Python hl_lines="12"
-{!../../../docs_src/dependencies/tutorial002.py!}
+{!../../docs_src/dependencies/tutorial002.py!}
```
...以前の`common_parameters`と同じパラメータを持っています:
```Python hl_lines="8"
-{!../../../docs_src/dependencies/tutorial001.py!}
+{!../../docs_src/dependencies/tutorial001.py!}
```
これらのパラメータは **FastAPI** が依存関係を「解決」するために使用するものです。
@@ -102,7 +102,7 @@ FastAPIが実際にチェックしているのは、それが「呼び出し可
これで、このクラスを使用して依存関係を宣言することができます。
```Python hl_lines="19"
-{!../../../docs_src/dependencies/tutorial002.py!}
+{!../../docs_src/dependencies/tutorial002.py!}
```
**FastAPI** は`CommonQueryParams`クラスを呼び出します。これにより、そのクラスの「インスタンス」が作成され、インスタンスはパラメータ`commons`として関数に渡されます。
@@ -144,7 +144,7 @@ commons = Depends(CommonQueryParams)
以下にあるように:
```Python hl_lines="19"
-{!../../../docs_src/dependencies/tutorial003.py!}
+{!../../docs_src/dependencies/tutorial003.py!}
```
しかし、型を宣言することは推奨されています。そうすれば、エディタは`commons`のパラメータとして何が渡されるかを知ることができ、コードの補完や型チェックなどを行うのに役立ちます:
@@ -180,12 +180,12 @@ commons: CommonQueryParams = Depends()
同じ例では以下のようになります:
```Python hl_lines="19"
-{!../../../docs_src/dependencies/tutorial004.py!}
+{!../../docs_src/dependencies/tutorial004.py!}
```
...そして **FastAPI** は何をすべきか知っています。
-/// tip | "豆知識"
+/// tip | 豆知識
役に立つというよりも、混乱するようであれば無視してください。それをする*必要*はありません。
diff --git a/docs/ja/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/ja/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
index c6472cab5..3b78f4e0b 100644
--- a/docs/ja/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
+++ b/docs/ja/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -15,12 +15,12 @@
それは`Depends()`の`list`であるべきです:
```Python hl_lines="17"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
これらの依存関係は、通常の依存関係と同様に実行・解決されます。しかし、それらの値(何かを返す場合)は*path operation関数*には渡されません。
-/// tip | "豆知識"
+/// tip | 豆知識
エディタによっては、未使用の関数パラメータをチェックしてエラーとして表示するものもあります。
@@ -39,7 +39,7 @@
これらはリクエストの要件(ヘッダのようなもの)やその他のサブ依存関係を宣言することができます:
```Python hl_lines="6 11"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
### 例外の発生
@@ -47,7 +47,7 @@
これらの依存関係は通常の依存関係と同じように、例外を`raise`発生させることができます:
```Python hl_lines="8 13"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
### 戻り値
@@ -57,7 +57,7 @@
つまり、すでにどこかで使っている通常の依存関係(値を返すもの)を再利用することができ、値は使われなくても依存関係は実行されます:
```Python hl_lines="9 14"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
## *path operations*のグループに対する依存関係
diff --git a/docs/ja/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/ja/docs/tutorial/dependencies/dependencies-with-yield.md
index 3f22a7a7b..bd4e689bf 100644
--- a/docs/ja/docs/tutorial/dependencies/dependencies-with-yield.md
+++ b/docs/ja/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -4,13 +4,13 @@ FastAPIは、いくつかのしてカスタムの独自ヘッダーを追加できます。
@@ -43,7 +43,7 @@
///
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.requests import Request` を使用することもできます。
@@ -60,7 +60,7 @@
例えば、リクエストの処理とレスポンスの生成にかかった秒数を含むカスタムヘッダー `X-Process-Time` を追加できます:
```Python hl_lines="10 12-13"
-{!../../../docs_src/middleware/tutorial001.py!}
+{!../../docs_src/middleware/tutorial001.py!}
```
## その他のミドルウェア
diff --git a/docs/ja/docs/tutorial/path-operation-configuration.md b/docs/ja/docs/tutorial/path-operation-configuration.md
index def12bd08..36223d35d 100644
--- a/docs/ja/docs/tutorial/path-operation-configuration.md
+++ b/docs/ja/docs/tutorial/path-operation-configuration.md
@@ -2,7 +2,7 @@
*path operationデコレータ*を設定するためのパラメータがいくつかあります。
-/// warning | "注意"
+/// warning | 注意
これらのパラメータは*path operation関数*ではなく、*path operationデコレータ*に直接渡されることに注意してください。
@@ -17,12 +17,12 @@
しかし、それぞれの番号コードが何のためのものか覚えていない場合は、`status`のショートカット定数を使用することができます:
```Python hl_lines="3 17"
-{!../../../docs_src/path_operation_configuration/tutorial001.py!}
+{!../../docs_src/path_operation_configuration/tutorial001.py!}
```
そのステータスコードはレスポンスで使用され、OpenAPIスキーマに追加されます。
-/// note | "技術詳細"
+/// note | 技術詳細
また、`from starlette import status`を使用することもできます。
@@ -35,7 +35,7 @@
`tags`パラメータを`str`の`list`(通常は1つの`str`)と一緒に渡すと、*path operation*にタグを追加できます:
```Python hl_lines="17 22 27"
-{!../../../docs_src/path_operation_configuration/tutorial002.py!}
+{!../../docs_src/path_operation_configuration/tutorial002.py!}
```
これらはOpenAPIスキーマに追加され、自動ドキュメントのインターフェースで使用されます:
@@ -47,7 +47,7 @@
`summary`と`description`を追加できます:
```Python hl_lines="20-21"
-{!../../../docs_src/path_operation_configuration/tutorial003.py!}
+{!../../docs_src/path_operation_configuration/tutorial003.py!}
```
## docstringを用いた説明
@@ -57,7 +57,7 @@
docstringにMarkdownを記述すれば、正しく解釈されて表示されます。(docstringのインデントを考慮して)
```Python hl_lines="19-27"
-{!../../../docs_src/path_operation_configuration/tutorial004.py!}
+{!../../docs_src/path_operation_configuration/tutorial004.py!}
```
これは対話的ドキュメントで使用されます:
@@ -69,16 +69,16 @@ docstringにdeprecatedとしてマークする必要があるが、それを削除しない場合は、`deprecated`パラメータを渡します:
```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_configuration/tutorial006.py!}
```
対話的ドキュメントでは非推奨と明記されます:
diff --git a/docs/ja/docs/tutorial/path-params-numeric-validations.md b/docs/ja/docs/tutorial/path-params-numeric-validations.md
index 9f0b72585..7d55ad30c 100644
--- a/docs/ja/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/ja/docs/tutorial/path-params-numeric-validations.md
@@ -7,7 +7,7 @@
まず初めに、`fastapi`から`Path`をインポートします:
```Python hl_lines="1"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
## メタデータの宣言
@@ -17,10 +17,10 @@
例えば、パスパラメータ`item_id`に対して`title`のメタデータを宣言するには以下のようにします:
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
-/// note | "備考"
+/// note | 備考
パスの一部でなければならないので、パスパラメータは常に必須です。
@@ -47,7 +47,7 @@ Pythonは「デフォルト」を持たない値の前に「デフォルト」
そのため、以下のように関数を宣言することができます:
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
## 必要に応じてパラメータを並び替えるトリック
@@ -59,7 +59,7 @@ Pythonは「デフォルト」を持たない値の前に「デフォルト」
Pythonはその`*`で何かをすることはありませんが、それ以降のすべてのパラメータがキーワード引数(キーと値のペア)として呼ばれるべきものであると知っているでしょう。それはkwargsとしても知られています。たとえデフォルト値がなくても。
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
## 数値の検証: 以上
@@ -69,7 +69,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
ここで、`ge=1`の場合、`item_id`は`1`「より大きい`g`か、同じ`e`」整数でなれけばなりません。
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
## 数値の検証: より大きいと小なりイコール
@@ -80,7 +80,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
* `le`: 小なりイコール(`l`ess than or `e`qual)
```Python hl_lines="9"
-{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
## 数値の検証: 浮動小数点、 大なり小なり
@@ -94,7 +94,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
これはltも同じです。
```Python hl_lines="11"
-{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
## まとめ
@@ -108,7 +108,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
* `lt`: より小さい(`l`ess `t`han)
* `le`: 以下(`l`ess than or `e`qual)
-/// info | "情報"
+/// info | 情報
`Query`、`Path`などは後に共通の`Param`クラスのサブクラスを見ることになります。(使う必要はありません)
@@ -116,7 +116,7 @@ Pythonはその`*`で何かをすることはありませんが、それ以降
///
-/// note | "技術詳細"
+/// note | 技術詳細
`fastapi`から`Query`、`Path`などをインポートすると、これらは実際には関数です。
diff --git a/docs/ja/docs/tutorial/path-params.md b/docs/ja/docs/tutorial/path-params.md
index 0a7916012..d86a27cb4 100644
--- a/docs/ja/docs/tutorial/path-params.md
+++ b/docs/ja/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
Pythonのformat文字列と同様のシンタックスで「パスパラメータ」や「パス変数」を宣言できます:
```Python hl_lines="6 7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
パスパラメータ `item_id` の値は、引数 `item_id` として関数に渡されます。
@@ -19,12 +19,12 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
標準のPythonの型アノテーションを使用して、関数内のパスパラメータの型を宣言できます:
```Python hl_lines="7"
-{!../../../docs_src/path_params/tutorial002.py!}
+{!../../docs_src/path_params/tutorial002.py!}
```
ここでは、 `item_id` は `int` として宣言されています。
-/// check | "確認"
+/// check | 確認
これにより、関数内でのエディターサポート (エラーチェックや補完など) が提供されます。
@@ -38,7 +38,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
{"item_id":3}
```
-/// check | "確認"
+/// check | 確認
関数が受け取った(および返した)値は、文字列の `"3"` ではなく、Pythonの `int` としての `3` であることに注意してください。
@@ -69,7 +69,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
http://127.0.0.1:8000/items/4.2 で見られるように、intのかわりに `float` が与えられた場合にも同様なエラーが表示されます。
-/// check | "確認"
+/// check | 確認
したがって、Pythonの型宣言を使用することで、**FastAPI**はデータのバリデーションを行います。
@@ -85,7 +85,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
-/// check | "確認"
+/// check | 確認
繰り返しになりますが、Python型宣言を使用するだけで、**FastAPI**は対話的なAPIドキュメントを自動的に生成します(Swagger UIを統合)。
@@ -122,7 +122,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
*path operations* は順に評価されるので、 `/users/me` が `/users/{user_id}` よりも先に宣言されているか確認する必要があります:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
+{!../../docs_src/path_params/tutorial003.py!}
```
それ以外の場合、 `/users/{users_id}` は `/users/me` としてもマッチします。値が「"me"」であるパラメータ `user_id` を受け取ると「考え」ます。
@@ -140,16 +140,16 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
そして、固定値のクラス属性を作ります。すると、その値が使用可能な値となります:
```Python hl_lines="1 6 7 8 9"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// info | "情報"
+/// info | 情報
Enumerations (もしくは、enums)はPython 3.4以降で利用できます。
///
-/// tip | "豆知識"
+/// tip | 豆知識
"AlexNet"、"ResNet"そして"LeNet"は機械学習モデルの名前です。
@@ -160,7 +160,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
次に、作成したenumクラスである`ModelName`を使用した型アノテーションをもつ*パスパラメータ*を作成します:
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### ドキュメントの確認
@@ -178,7 +178,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
これは、作成した列挙型 `ModelName` の*列挙型メンバ*と比較できます:
```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
#### *列挙値*の取得
@@ -186,10 +186,10 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
`model_name.value` 、もしくは一般に、 `your_enum_member.value` を使用して実際の値 (この場合は `str`) を取得できます。
```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
`ModelName.lenet.value` でも `"lenet"` 値にアクセスできます。
@@ -202,7 +202,7 @@ Pythonのformat文字列と同様のシンタックスで「パスパラメー
それらはクライアントに返される前に適切な値 (この場合は文字列) に変換されます。
```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
クライアントは以下の様なJSONレスポンスを得ます:
@@ -243,10 +243,10 @@ Starletteのオプションを直接使用することで、以下のURLの様
したがって、以下の様に使用できます:
```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
+{!../../docs_src/path_params/tutorial004.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
最初のスラッシュ (`/`)が付いている `/home/johndoe/myfile.txt` をパラメータが含んでいる必要があります。
diff --git a/docs/ja/docs/tutorial/query-params-str-validations.md b/docs/ja/docs/tutorial/query-params-str-validations.md
index ada048844..6450c91c4 100644
--- a/docs/ja/docs/tutorial/query-params-str-validations.md
+++ b/docs/ja/docs/tutorial/query-params-str-validations.md
@@ -5,12 +5,12 @@
以下のアプリケーションを例にしてみましょう:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial001.py!}
+{!../../docs_src/query_params_str_validations/tutorial001.py!}
```
クエリパラメータ `q` は `Optional[str]` 型で、`None` を許容する `str` 型を意味しており、デフォルトは `None` です。そのため、FastAPIはそれが必須ではないと理解します。
-/// note | "備考"
+/// note | 備考
FastAPIは、 `q` はデフォルト値が `=None` であるため、必須ではないと理解します。
@@ -27,7 +27,7 @@ FastAPIは、 `q` はデフォルト値が `=None` であるため、必須で
そのために、まずは`fastapi`から`Query`をインポートします:
```Python hl_lines="3"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!../../docs_src/query_params_str_validations/tutorial002.py!}
```
## デフォルト値として`Query`を使用
@@ -35,7 +35,7 @@ FastAPIは、 `q` はデフォルト値が `=None` であるため、必須で
パラメータのデフォルト値として使用し、パラメータ`max_length`を50に設定します:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!../../docs_src/query_params_str_validations/tutorial002.py!}
```
デフォルト値`None`を`Query(default=None)`に置き換える必要があるので、`Query`の最初の引数はデフォルト値を定義するのと同じです。
@@ -54,7 +54,7 @@ q: Optional[str] = None
しかし、これはクエリパラメータとして明示的に宣言しています。
-/// info | "情報"
+/// info | 情報
FastAPIは以下の部分を気にすることを覚えておいてください:
@@ -87,7 +87,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
パラメータ`min_length`も追加することができます:
```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial003.py!}
+{!../../docs_src/query_params_str_validations/tutorial003.py!}
```
## 正規表現の追加
@@ -95,7 +95,7 @@ q: Union[str, None] = Query(default=None, max_length=50)
パラメータが一致するべき正規表現を定義することができます:
```Python hl_lines="11"
-{!../../../docs_src/query_params_str_validations/tutorial004.py!}
+{!../../docs_src/query_params_str_validations/tutorial004.py!}
```
この特定の正規表現は受け取ったパラメータの値をチェックします:
@@ -115,10 +115,10 @@ q: Union[str, None] = Query(default=None, max_length=50)
クエリパラメータ`q`の`min_length`を`3`とし、デフォルト値を`fixedquery`としてみましょう:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial005.py!}
+{!../../docs_src/query_params_str_validations/tutorial005.py!}
```
-/// note | "備考"
+/// note | 備考
デフォルト値を指定すると、パラメータは任意になります。
@@ -147,10 +147,10 @@ q: Union[str, None] = Query(default=None, min_length=3)
そのため、`Query`を使用して必須の値を宣言する必要がある場合は、第一引数に`...`を使用することができます:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006.py!}
+{!../../docs_src/query_params_str_validations/tutorial006.py!}
```
-/// info | "情報"
+/// info | 情報
これまで`...`を見たことがない方へ: これは特殊な単一値です。Pythonの一部であり、"Ellipsis"と呼ばれています。
@@ -165,7 +165,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
例えば、URL内に複数回出現するクエリパラメータ`q`を宣言するには以下のように書きます:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial011.py!}
+{!../../docs_src/query_params_str_validations/tutorial011.py!}
```
そしてURLは以下です:
@@ -187,7 +187,7 @@ http://localhost:8000/items/?q=foo&q=bar
}
```
-/// tip | "豆知識"
+/// tip | 豆知識
上述の例のように、`list`型のクエリパラメータを宣言するには明示的に`Query`を使用する必要があります。そうしない場合、リクエストボディと解釈されます。
@@ -202,7 +202,7 @@ http://localhost:8000/items/?q=foo&q=bar
また、値が指定されていない場合はデフォルトの`list`を定義することもできます。
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial012.py!}
+{!../../docs_src/query_params_str_validations/tutorial012.py!}
```
以下のURLを開くと:
@@ -227,10 +227,10 @@ http://localhost:8000/items/
`List[str]`の代わりに直接`list`を使うこともできます:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial013.py!}
+{!../../docs_src/query_params_str_validations/tutorial013.py!}
```
-/// note | "備考"
+/// note | 備考
この場合、FastAPIはリストの内容をチェックしないことを覚えておいてください。
@@ -244,7 +244,7 @@ http://localhost:8000/items/
その情報は、生成されたOpenAPIに含まれ、ドキュメントのユーザーインターフェースや外部のツールで使用されます。
-/// note | "備考"
+/// note | 備考
ツールによってOpenAPIのサポートのレベルが異なる可能性があることを覚えておいてください。
@@ -255,13 +255,13 @@ http://localhost:8000/items/
`title`を追加できます:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial007.py!}
+{!../../docs_src/query_params_str_validations/tutorial007.py!}
```
`description`を追加できます:
```Python hl_lines="13"
-{!../../../docs_src/query_params_str_validations/tutorial008.py!}
+{!../../docs_src/query_params_str_validations/tutorial008.py!}
```
## エイリアスパラメータ
@@ -283,7 +283,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
それならば、`alias`を宣言することができます。エイリアスはパラメータの値を見つけるのに使用されます:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial009.py!}
+{!../../docs_src/query_params_str_validations/tutorial009.py!}
```
## 非推奨パラメータ
@@ -295,7 +295,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
その場合、`Query`にパラメータ`deprecated=True`を渡します:
```Python hl_lines="18"
-{!../../../docs_src/query_params_str_validations/tutorial010.py!}
+{!../../docs_src/query_params_str_validations/tutorial010.py!}
```
ドキュメントは以下のようになります:
diff --git a/docs/ja/docs/tutorial/query-params.md b/docs/ja/docs/tutorial/query-params.md
index c0eb2d096..71f78eca5 100644
--- a/docs/ja/docs/tutorial/query-params.md
+++ b/docs/ja/docs/tutorial/query-params.md
@@ -3,7 +3,7 @@
パスパラメータではない関数パラメータを宣言すると、それらは自動的に "クエリ" パラメータとして解釈されます。
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
+{!../../docs_src/query_params/tutorial001.py!}
```
クエリはURL内で `?` の後に続くキーとバリューの組で、 `&` で区切られています。
@@ -64,12 +64,12 @@ http://127.0.0.1:8000/items/?skip=20
同様に、デフォルト値を `None` とすることで、オプショナルなクエリパラメータを宣言できます:
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial002.py!}
+{!../../docs_src/query_params/tutorial002.py!}
```
この場合、関数パラメータ `q` はオプショナルとなり、デフォルトでは `None` になります。
-/// check | "確認"
+/// check | 確認
パスパラメータ `item_id` はパスパラメータであり、`q` はそれとは違ってクエリパラメータであると判別できるほど**FastAPI** が賢いということにも注意してください。
@@ -80,7 +80,7 @@ http://127.0.0.1:8000/items/?skip=20
`bool` 型も宣言できます。これは以下の様に変換されます:
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial003.py!}
+{!../../docs_src/query_params/tutorial003.py!}
```
この場合、以下にアクセスすると:
@@ -124,7 +124,7 @@ http://127.0.0.1:8000/items/foo?short=yes
名前で判別されます:
```Python hl_lines="8 10"
-{!../../../docs_src/query_params/tutorial004.py!}
+{!../../docs_src/query_params/tutorial004.py!}
```
## 必須のクエリパラメータ
@@ -136,7 +136,7 @@ http://127.0.0.1:8000/items/foo?short=yes
しかしクエリパラメータを必須にしたい場合は、ただデフォルト値を宣言しなければよいです:
```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
+{!../../docs_src/query_params/tutorial005.py!}
```
ここで、クエリパラメータ `needy` は `str` 型の必須のクエリパラメータです
@@ -182,7 +182,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
そして当然、あるパラメータを必須に、別のパラメータにデフォルト値を設定し、また別のパラメータをオプショナルにできます:
```Python hl_lines="10"
-{!../../../docs_src/query_params/tutorial006.py!}
+{!../../docs_src/query_params/tutorial006.py!}
```
この場合、3つのクエリパラメータがあります。:
@@ -191,7 +191,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
* `skip`、デフォルト値を `0` とする `int` 。
* `limit`、オプショナルな `int` 。
-/// tip | "豆知識"
+/// tip | 豆知識
[パスパラメータ](path-params.md#_8){.internal-link target=_blank}と同様に `Enum` を使用できます。
diff --git a/docs/ja/docs/tutorial/request-forms-and-files.md b/docs/ja/docs/tutorial/request-forms-and-files.md
index d8effc219..1e4237b20 100644
--- a/docs/ja/docs/tutorial/request-forms-and-files.md
+++ b/docs/ja/docs/tutorial/request-forms-and-files.md
@@ -2,7 +2,7 @@
`File`と`Form`を同時に使うことでファイルとフォームフィールドを定義することができます。
-/// info | "情報"
+/// info | 情報
アップロードされたファイルやフォームデータを受信するには、まず`python-multipart`をインストールします。
@@ -13,7 +13,7 @@
## `File`と`Form`のインポート
```Python hl_lines="1"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!../../docs_src/request_forms_and_files/tutorial001.py!}
```
## `File`と`Form`のパラメータの定義
@@ -21,14 +21,14 @@
ファイルやフォームのパラメータは`Body`や`Query`の場合と同じように作成します:
```Python hl_lines="8"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!../../docs_src/request_forms_and_files/tutorial001.py!}
```
ファイルとフォームフィールドがフォームデータとしてアップロードされ、ファイルとフォームフィールドを受け取ります。
また、いくつかのファイルを`bytes`として、いくつかのファイルを`UploadFile`として宣言することができます。
-/// warning | "注意"
+/// warning | 注意
*path operation*で複数の`File`と`Form`パラメータを宣言することができますが、JSONとして受け取ることを期待している`Body`フィールドを宣言することはできません。なぜなら、リクエストのボディは`application/json`の代わりに`multipart/form-data`を使ってエンコードされているからです。
diff --git a/docs/ja/docs/tutorial/request-forms.md b/docs/ja/docs/tutorial/request-forms.md
index d04dc810b..f130c067f 100644
--- a/docs/ja/docs/tutorial/request-forms.md
+++ b/docs/ja/docs/tutorial/request-forms.md
@@ -2,7 +2,7 @@
JSONの代わりにフィールドを受け取る場合は、`Form`を使用します。
-/// info | "情報"
+/// info | 情報
フォームを使うためには、まず`python-multipart`をインストールします。
@@ -15,7 +15,7 @@ JSONの代わりにフィールドを受け取る場合は、`Form`を使用し
`fastapi`から`Form`をインポートします:
```Python hl_lines="1"
-{!../../../docs_src/request_forms/tutorial001.py!}
+{!../../docs_src/request_forms/tutorial001.py!}
```
## `Form`のパラメータの定義
@@ -23,7 +23,7 @@ JSONの代わりにフィールドを受け取る場合は、`Form`を使用し
`Body`や`Query`の場合と同じようにフォームパラメータを作成します:
```Python hl_lines="7"
-{!../../../docs_src/request_forms/tutorial001.py!}
+{!../../docs_src/request_forms/tutorial001.py!}
```
例えば、OAuth2仕様が使用できる方法の1つ(「パスワードフロー」と呼ばれる)では、フォームフィールドとして`username`と`password`を送信する必要があります。
@@ -32,13 +32,13 @@ JSONの代わりにフィールドを受け取る場合は、`Form`を使用し
`Form`では`Body`(および`Query`や`Path`、`Cookie`)と同じメタデータとバリデーションを宣言することができます。
-/// info | "情報"
+/// info | 情報
`Form`は`Body`を直接継承するクラスです。
///
-/// tip | "豆知識"
+/// tip | 豆知識
フォームのボディを宣言するには、明示的に`Form`を使用する必要があります。なぜなら、これを使わないと、パラメータはクエリパラメータやボディ(JSON)パラメータとして解釈されるからです。
@@ -50,7 +50,7 @@ HTMLフォーム(``)がサーバにデータを送信する方
**FastAPI** は、JSONの代わりにそのデータを適切な場所から読み込むようにします。
-/// note | "技術詳細"
+/// note | 技術詳細
フォームからのデータは通常、`application/x-www-form-urlencoded`の「media type」を使用してエンコードされます。
@@ -60,7 +60,7 @@ HTMLフォーム(``)がサーバにデータを送信する方
///
-/// warning | "注意"
+/// warning | 注意
*path operation*で複数の`Form`パラメータを宣言することができますが、JSONとして受け取ることを期待している`Body`フィールドを宣言することはできません。なぜなら、リクエストは`application/json`の代わりに`application/x-www-form-urlencoded`を使ってボディをエンコードするからです。
diff --git a/docs/ja/docs/tutorial/response-model.md b/docs/ja/docs/tutorial/response-model.md
index 7bb5e2825..97821f125 100644
--- a/docs/ja/docs/tutorial/response-model.md
+++ b/docs/ja/docs/tutorial/response-model.md
@@ -9,10 +9,10 @@
* など。
```Python hl_lines="17"
-{!../../../docs_src/response_model/tutorial001.py!}
+{!../../docs_src/response_model/tutorial001.py!}
```
-/// note | "備考"
+/// note | 備考
`response_model`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation関数* のパラメータではありません。
@@ -31,7 +31,7 @@ FastAPIは`response_model`を使って以下のことをします:
* 出力データをモデルのデータに限定します。これがどのように重要なのか以下で見ていきましょう。
-/// note | "技術詳細"
+/// note | 技術詳細
レスポンスモデルは、関数の戻り値のアノテーションではなく、このパラメータで宣言されています。なぜなら、パス関数は実際にはそのレスポンスモデルを返すのではなく、`dict`やデータベースオブジェクト、あるいは他のモデルを返し、`response_model`を使用してフィールドの制限やシリアライズを行うからです。
@@ -42,13 +42,13 @@ FastAPIは`response_model`を使って以下のことをします:
ここでは`UserIn`モデルを宣言しています。それには平文のパスワードが含まれています:
```Python hl_lines="9 11"
-{!../../../docs_src/response_model/tutorial002.py!}
+{!../../docs_src/response_model/tutorial002.py!}
```
そして、このモデルを使用して入力を宣言し、同じモデルを使って出力を宣言しています:
```Python hl_lines="17 18"
-{!../../../docs_src/response_model/tutorial002.py!}
+{!../../docs_src/response_model/tutorial002.py!}
```
これで、ブラウザがパスワードを使ってユーザーを作成する際に、APIがレスポンスで同じパスワードを返すようになりました。
@@ -57,7 +57,7 @@ FastAPIは`response_model`を使って以下のことをします:
しかし、同じモデルを別の*path operation*に使用すると、すべてのクライアントにユーザーのパスワードを送信してしまうことになります。
-/// danger | "危険"
+/// danger | 危険
ユーザーの平文のパスワードを保存したり、レスポンスで送信したりすることは絶対にしないでください。
@@ -68,19 +68,19 @@ FastAPIは`response_model`を使って以下のことをします:
代わりに、平文のパスワードを持つ入力モデルと、パスワードを持たない出力モデルを作成することができます:
```Python hl_lines="9 11 16"
-{!../../../docs_src/response_model/tutorial003.py!}
+{!../../docs_src/response_model/tutorial003.py!}
```
ここでは、*path operation関数*がパスワードを含む同じ入力ユーザーを返しているにもかかわらず:
```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial003.py!}
+{!../../docs_src/response_model/tutorial003.py!}
```
...`response_model`を`UserOut`と宣言したことで、パスワードが含まれていません:
```Python hl_lines="22"
-{!../../../docs_src/response_model/tutorial003.py!}
+{!../../docs_src/response_model/tutorial003.py!}
```
そのため、**FastAPI** は出力モデルで宣言されていない全てのデータをフィルタリングしてくれます(Pydanticを使用)。
@@ -100,7 +100,7 @@ FastAPIは`response_model`を使って以下のことをします:
レスポンスモデルにはデフォルト値を設定することができます:
```Python hl_lines="11 13 14"
-{!../../../docs_src/response_model/tutorial004.py!}
+{!../../docs_src/response_model/tutorial004.py!}
```
* `description: str = None`は`None`がデフォルト値です。
@@ -116,7 +116,7 @@ FastAPIは`response_model`を使って以下のことをします:
*path operation デコレータ*に`response_model_exclude_unset=True`パラメータを設定することができます:
```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial004.py!}
+{!../../docs_src/response_model/tutorial004.py!}
```
そして、これらのデフォルト値はレスポンスに含まれず、実際に設定された値のみが含まれます。
@@ -130,13 +130,13 @@ FastAPIは`response_model`を使って以下のことをします:
}
```
-/// info | "情報"
+/// info | 情報
FastAPIはこれをするために、Pydanticモデルの`.dict()`をその`exclude_unset`パラメータで使用しています。
///
-/// info | "情報"
+/// info | 情報
以下も使用することができます:
@@ -180,7 +180,7 @@ FastAPIは十分に賢いので(実際には、Pydanticが十分に賢い)`d
そのため、それらはJSONレスポンスに含まれることになります。
-/// tip | "豆知識"
+/// tip | 豆知識
デフォルト値は`None`だけでなく、なんでも良いことに注意してください。
例えば、リスト(`[]`)や`10.5`の`float`などです。
@@ -195,7 +195,7 @@ FastAPIは十分に賢いので(実際には、Pydanticが十分に賢い)`d
これは、Pydanticモデルが1つしかなく、出力からいくつかのデータを削除したい場合のクイックショートカットとして使用することができます。
-/// tip | "豆知識"
+/// tip | 豆知識
それでも、これらのパラメータではなく、複数のクラスを使用して、上記のようなアイデアを使うことをおすすめします。
@@ -206,10 +206,10 @@ FastAPIは十分に賢いので(実際には、Pydanticが十分に賢い)`d
///
```Python hl_lines="31 37"
-{!../../../docs_src/response_model/tutorial005.py!}
+{!../../docs_src/response_model/tutorial005.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
`{"name", "description"}`の構文はこれら2つの値をもつ`set`を作成します。
@@ -222,7 +222,7 @@ FastAPIは十分に賢いので(実際には、Pydanticが十分に賢い)`d
もし`set`を使用することを忘れて、代わりに`list`や`tuple`を使用しても、FastAPIはそれを`set`に変換して正しく動作します:
```Python hl_lines="31 37"
-{!../../../docs_src/response_model/tutorial006.py!}
+{!../../docs_src/response_model/tutorial006.py!}
```
## まとめ
diff --git a/docs/ja/docs/tutorial/response-status-code.md b/docs/ja/docs/tutorial/response-status-code.md
index 945767894..56bcdaf6c 100644
--- a/docs/ja/docs/tutorial/response-status-code.md
+++ b/docs/ja/docs/tutorial/response-status-code.md
@@ -9,10 +9,10 @@
* など。
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
-/// note | "備考"
+/// note | 備考
`status_code`は「デコレータ」メソッド(`get`、`post`など)のパラメータであることに注意してください。すべてのパラメータやボディのように、*path operation関数*のものではありません。
@@ -20,7 +20,7 @@
`status_code`パラメータはHTTPステータスコードを含む数値を受け取ります。
-/// info | "情報"
+/// info | 情報
`status_code`は代わりに、Pythonの`http.HTTPStatus`のように、`IntEnum`を受け取ることもできます。
@@ -33,7 +33,7 @@
-/// note | "備考"
+/// note | 備考
いくつかのレスポンスコード(次のセクションを参照)は、レスポンスにボディがないことを示しています。
@@ -43,7 +43,7 @@ FastAPIはこれを知っていて、レスポンスボディがないというO
## HTTPステータスコードについて
-/// note | "備考"
+/// note | 備考
すでにHTTPステータスコードが何であるかを知っている場合は、次のセクションにスキップしてください。
@@ -66,7 +66,7 @@ HTTPでは、レスポンスの一部として3桁の数字のステータス
* クライアントからの一般的なエラーについては、`400`を使用することができます。
* `500`以上はサーバーエラーのためのものです。これらを直接使うことはほとんどありません。アプリケーションコードやサーバーのどこかで何か問題が発生した場合、これらのステータスコードのいずれかが自動的に返されます。
-/// tip | "豆知識"
+/// tip | 豆知識
それぞれのステータスコードとどのコードが何のためのコードなのかについて詳細はMDN HTTP レスポンスステータスコードについてのドキュメントを参照してください。
@@ -77,7 +77,7 @@ HTTPでは、レスポンスの一部として3桁の数字のステータス
先ほどの例をもう一度見てみましょう:
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
`201`は「作成完了」のためのステータスコードです。
@@ -87,14 +87,14 @@ HTTPでは、レスポンスの一部として3桁の数字のステータス
`fastapi.status`の便利な変数を利用することができます。
```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
+{!../../docs_src/response_status_code/tutorial002.py!}
```
それらは便利です。それらは同じ番号を保持しており、その方法ではエディタの自動補完を使用してそれらを見つけることができます。
-/// note | "技術詳細"
+/// note | 技術詳細
また、`from starlette import status`を使うこともできます。
diff --git a/docs/ja/docs/tutorial/schema-extra-example.md b/docs/ja/docs/tutorial/schema-extra-example.md
index a3cd5eb54..44dfad737 100644
--- a/docs/ja/docs/tutorial/schema-extra-example.md
+++ b/docs/ja/docs/tutorial/schema-extra-example.md
@@ -11,7 +11,7 @@ JSON Schemaの追加情報を宣言する方法はいくつかあります。
Pydanticのドキュメント: スキーマのカスタマイズで説明されているように、`Config`と`schema_extra`を使ってPydanticモデルの例を宣言することができます:
```Python hl_lines="15 16 17 18 19 20 21 22 23"
-{!../../../docs_src/schema_extra_example/tutorial001.py!}
+{!../../docs_src/schema_extra_example/tutorial001.py!}
```
その追加情報はそのまま出力され、JSON Schemaに追加されます。
@@ -21,10 +21,10 @@ JSON Schemaの追加情報を宣言する方法はいくつかあります。
後述する`Field`、`Path`、`Query`、`Body`などでは、任意の引数を関数に渡すことでJSON Schemaの追加情報を宣言することもできます:
```Python hl_lines="4 10 11 12 13"
-{!../../../docs_src/schema_extra_example/tutorial002.py!}
+{!../../docs_src/schema_extra_example/tutorial002.py!}
```
-/// warning | "注意"
+/// warning | 注意
これらの追加引数が渡されても、文書化のためのバリデーションは追加されず、注釈だけが追加されることを覚えておいてください。
@@ -37,7 +37,7 @@ JSON Schemaの追加情報を宣言する方法はいくつかあります。
例えば、`Body`にボディリクエストの`example`を渡すことができます:
```Python hl_lines="21 22 23 24 25 26"
-{!../../../docs_src/schema_extra_example/tutorial003.py!}
+{!../../docs_src/schema_extra_example/tutorial003.py!}
```
## ドキュメントのUIの例
diff --git a/docs/ja/docs/tutorial/security/first-steps.md b/docs/ja/docs/tutorial/security/first-steps.md
index c78a3755e..6ace1b542 100644
--- a/docs/ja/docs/tutorial/security/first-steps.md
+++ b/docs/ja/docs/tutorial/security/first-steps.md
@@ -21,12 +21,12 @@
`main.py`に、下記の例をコピーします:
```Python
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
## 実行
-/// info | "情報"
+/// info | 情報
まず`python-multipart`をインストールします。
@@ -56,7 +56,7 @@ $ uvicorn main:app --reload
-/// check | "Authorizeボタン!"
+/// check | Authorizeボタン!
すでにピカピカの新しい「Authorize」ボタンがあります。
@@ -68,7 +68,7 @@ $ uvicorn main:app --reload
-/// note | "備考"
+/// note | 備考
フォームに何を入力しても、まだうまくいきません。ですが、これから動くようになります。
@@ -114,7 +114,7 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
この例では、**Bearer**トークンを使用して**OAuth2**を**パスワード**フローで使用します。これには`OAuth2PasswordBearer`クラスを使用します。
-/// info | "情報"
+/// info | 情報
「bearer」トークンが、唯一の選択肢ではありません。
@@ -129,10 +129,10 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
`OAuth2PasswordBearer` クラスのインスタンスを作成する時に、パラメーター`tokenUrl`を渡します。このパラメーターには、クライアント (ユーザーのブラウザで動作するフロントエンド) がトークンを取得するために`ユーザー名`と`パスワード`を送信するURLを指定します。
```Python hl_lines="6"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
ここで、`tokenUrl="token"`は、まだ作成していない相対URL`token`を指します。相対URLなので、`./token`と同じです。
@@ -146,7 +146,7 @@ OAuth2は、バックエンドやAPIがユーザーを認証するサーバー
実際のpath operationもすぐに作ります。
-/// info | "情報"
+/// info | 情報
非常に厳格な「Pythonista」であれば、パラメーター名のスタイルが`token_url`ではなく`tokenUrl`であることを気に入らないかもしれません。
@@ -169,14 +169,14 @@ oauth2_scheme(some, parameters)
これで`oauth2_scheme`を`Depends`で依存関係に渡すことができます。
```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
この依存関係は、*path operation function*のパラメーター`token`に代入される`str`を提供します。
**FastAPI**は、この依存関係を使用してOpenAPIスキーマ (および自動APIドキュメント) で「セキュリティスキーム」を定義できることを知っています。
-/// info | "技術詳細"
+/// info | 技術詳細
**FastAPI**は、`OAuth2PasswordBearer` クラス (依存関係で宣言されている) を使用してOpenAPIのセキュリティスキームを定義できることを知っています。これは`fastapi.security.oauth2.OAuth2`、`fastapi.security.base.SecurityBase`を継承しているからです。
diff --git a/docs/ja/docs/tutorial/security/get-current-user.md b/docs/ja/docs/tutorial/security/get-current-user.md
index 250f66b81..898bbd797 100644
--- a/docs/ja/docs/tutorial/security/get-current-user.md
+++ b/docs/ja/docs/tutorial/security/get-current-user.md
@@ -3,7 +3,7 @@
一つ前の章では、(依存性注入システムに基づいた)セキュリティシステムは、 *path operation関数* に `str` として `token` を与えていました:
```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
しかし、それはまだそんなに有用ではありません。
@@ -17,7 +17,7 @@
ボディを宣言するのにPydanticを使用するのと同じやり方で、Pydanticを別のどんなところでも使うことができます:
```Python hl_lines="5 12-16"
-{!../../../docs_src/security/tutorial002.py!}
+{!../../docs_src/security/tutorial002.py!}
```
## 依存関係 `get_current_user` を作成
@@ -31,7 +31,7 @@
以前直接 *path operation* の中でしていたのと同じように、新しい依存関係である `get_current_user` は `str` として `token` を受け取るようになります:
```Python hl_lines="25"
-{!../../../docs_src/security/tutorial002.py!}
+{!../../docs_src/security/tutorial002.py!}
```
## ユーザーの取得
@@ -39,7 +39,7 @@
`get_current_user` は作成した(偽物の)ユーティリティ関数を使って、 `str` としてトークンを受け取り、先ほどのPydanticの `User` モデルを返却します:
```Python hl_lines="19-22 26-27"
-{!../../../docs_src/security/tutorial002.py!}
+{!../../docs_src/security/tutorial002.py!}
```
## 現在のユーザーの注入
@@ -47,14 +47,14 @@
ですので、 `get_current_user` に対して同様に *path operation* の中で `Depends` を利用できます。
```Python hl_lines="31"
-{!../../../docs_src/security/tutorial002.py!}
+{!../../docs_src/security/tutorial002.py!}
```
Pydanticモデルの `User` として、 `current_user` の型を宣言することに注意してください。
その関数の中ですべての入力補完や型チェックを行う際に役に立ちます。
-/// tip | "豆知識"
+/// tip | 豆知識
リクエストボディはPydanticモデルでも宣言できることを覚えているかもしれません。
@@ -62,7 +62,7 @@ Pydanticモデルの `User` として、 `current_user` の型を宣言するこ
///
-/// check | "確認"
+/// check | 確認
依存関係システムがこのように設計されているおかげで、 `User` モデルを返却する別の依存関係(別の"dependables")を持つことができます。
@@ -104,7 +104,7 @@ Pydanticモデルの `User` として、 `current_user` の型を宣言するこ
さらに、こうした何千もの *path operations* は、たった3行で表現できるのです:
```Python hl_lines="30-32"
-{!../../../docs_src/security/tutorial002.py!}
+{!../../docs_src/security/tutorial002.py!}
```
## まとめ
diff --git a/docs/ja/docs/tutorial/security/index.md b/docs/ja/docs/tutorial/security/index.md
index c68e7e7f2..37b8bb958 100644
--- a/docs/ja/docs/tutorial/security/index.md
+++ b/docs/ja/docs/tutorial/security/index.md
@@ -32,7 +32,7 @@ OAuth 1というものもありましたが、これはOAuth2とは全く異な
OAuth2は、通信を暗号化する方法を指定せず、アプリケーションがHTTPSで提供されることを想定しています。
-/// tip | "豆知識"
+/// tip | 豆知識
**デプロイ**のセクションでは、TraefikとLet's Encryptを使用して、無料でHTTPSを設定する方法が紹介されています。
@@ -89,7 +89,7 @@ OpenAPIでは、以下のセキュリティスキームを定義しています:
* この自動検出メカニズムは、OpenID Connectの仕様で定義されているものです。
-/// tip | "豆知識"
+/// tip | 豆知識
Google、Facebook、Twitter、GitHubなど、他の認証/認可プロバイダを統合することも可能で、比較的簡単です。
diff --git a/docs/ja/docs/tutorial/security/oauth2-jwt.md b/docs/ja/docs/tutorial/security/oauth2-jwt.md
index 4f6aebd4c..825a1b2b3 100644
--- a/docs/ja/docs/tutorial/security/oauth2-jwt.md
+++ b/docs/ja/docs/tutorial/security/oauth2-jwt.md
@@ -44,7 +44,7 @@ $ pip install python-jose[cryptography]
ここでは、推奨されているものを使用します:pyca/cryptography。
-/// tip | "豆知識"
+/// tip | 豆知識
このチュートリアルでは以前、PyJWTを使用していました。
@@ -86,7 +86,7 @@ $ pip install passlib[bcrypt]
-/// tip | "豆知識"
+/// tip | 豆知識
`passlib`を使用すると、**Django**や**Flask**のセキュリティプラグインなどで作成されたパスワードを読み取れるように設定できます。
@@ -102,7 +102,7 @@ $ pip install passlib[bcrypt]
PassLib の「context」を作成します。これは、パスワードのハッシュ化と検証に使用されるものです。
-/// tip | "豆知識"
+/// tip | 豆知識
PassLibのcontextには、検証だけが許された非推奨の古いハッシュアルゴリズムを含む、様々なハッシュアルゴリズムを使用した検証機能もあります。
@@ -119,10 +119,10 @@ PassLibのcontextには、検証だけが許された非推奨の古いハッシ
さらに、ユーザーを認証して返す関数も作成します。
```Python hl_lines="7 48 55-56 59-60 69-75"
-{!../../../docs_src/security/tutorial004.py!}
+{!../../docs_src/security/tutorial004.py!}
```
-/// note | "備考"
+/// note | 備考
新しい(偽の)データベース`fake_users_db`を確認すると、ハッシュ化されたパスワードが次のようになっていることがわかります:`"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`
@@ -157,7 +157,7 @@ JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定し
新しいアクセストークンを生成するユーティリティ関数を作成します。
```Python hl_lines="6 12-14 28-30 78-86"
-{!../../../docs_src/security/tutorial004.py!}
+{!../../docs_src/security/tutorial004.py!}
```
## 依存関係の更新
@@ -169,7 +169,7 @@ JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定し
トークンが無効な場合は、すぐにHTTPエラーを返します。
```Python hl_lines="89-106"
-{!../../../docs_src/security/tutorial004.py!}
+{!../../docs_src/security/tutorial004.py!}
```
## `/token` パスオペレーションの更新
@@ -179,7 +179,7 @@ JWTトークンの署名に使用するアルゴリズム`"HS256"`を指定し
JWTアクセストークンを作成し、それを返します。
```Python hl_lines="115-130"
-{!../../../docs_src/security/tutorial004.py!}
+{!../../docs_src/security/tutorial004.py!}
```
### JWTの"subject" `sub` についての技術的な詳細
@@ -219,7 +219,7 @@ IDの衝突を回避するために、ユーザーのJWTトークンを作成す
Username: `johndoe`
Password: `secret`
-/// check | "確認"
+/// check | 確認
コードのどこにも平文のパスワード"`secret`"はなく、ハッシュ化されたものしかないことを確認してください。
@@ -244,7 +244,7 @@ Password: `secret`
-/// note | "備考"
+/// note | 備考
ヘッダーの`Authorization`には、`Bearer`で始まる値があります。
diff --git a/docs/ja/docs/tutorial/static-files.md b/docs/ja/docs/tutorial/static-files.md
index c9d95bc34..37ea22dd7 100644
--- a/docs/ja/docs/tutorial/static-files.md
+++ b/docs/ja/docs/tutorial/static-files.md
@@ -8,10 +8,10 @@
* `StaticFiles()` インスタンスを生成し、特定のパスに「マウント」。
```Python hl_lines="2 6"
-{!../../../docs_src/static_files/tutorial001.py!}
+{!../../docs_src/static_files/tutorial001.py!}
```
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.staticfiles import StaticFiles` も使用できます。
diff --git a/docs/ja/docs/tutorial/testing.md b/docs/ja/docs/tutorial/testing.md
index 3ed03ebea..b7e80cb8d 100644
--- a/docs/ja/docs/tutorial/testing.md
+++ b/docs/ja/docs/tutorial/testing.md
@@ -19,10 +19,10 @@
チェックしたい Python の標準的な式と共に、シンプルに `assert` 文を記述します。
```Python hl_lines="2 12 15-18"
-{!../../../docs_src/app_testing/tutorial001.py!}
+{!../../docs_src/app_testing/tutorial001.py!}
```
-/// tip | "豆知識"
+/// tip | 豆知識
テスト関数は `async def` ではなく、通常の `def` であることに注意してください。
@@ -32,7 +32,7 @@
///
-/// note | "技術詳細"
+/// note | 技術詳細
`from starlette.testclient import TestClient` も使用できます。
@@ -40,7 +40,7 @@
///
-/// tip | "豆知識"
+/// tip | 豆知識
FastAPIアプリケーションへのリクエストの送信とは別に、テストで `async` 関数 (非同期データベース関数など) を呼び出したい場合は、高度なチュートリアルの[Async Tests](../advanced/async-tests.md){.internal-link target=_blank} を参照してください。
@@ -57,7 +57,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
**FastAPI** アプリに `main.py` ファイルがあるとします:
```Python
-{!../../../docs_src/app_testing/main.py!}
+{!../../docs_src/app_testing/main.py!}
```
### テストファイル
@@ -65,7 +65,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
次に、テストを含む `test_main.py` ファイルを作成し、`main` モジュール (`main.py`) から `app` をインポートします:
```Python
-{!../../../docs_src/app_testing/test_main.py!}
+{!../../docs_src/app_testing/test_main.py!}
```
## テスト: 例の拡張
@@ -86,7 +86,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
//// tab | Python 3.10+
```Python
-{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
+{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
@@ -94,7 +94,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
//// tab | Python 3.6+
```Python
-{!> ../../../docs_src/app_testing/app_b/main.py!}
+{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
@@ -104,7 +104,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
次に、先程のものに拡張版のテストを加えた、`test_main_b.py` を作成します。
```Python
-{!> ../../../docs_src/app_testing/app_b/test_main.py!}
+{!> ../../docs_src/app_testing/app_b/test_main.py!}
```
リクエストに情報を渡せるクライアントが必要で、その方法がわからない場合はいつでも、`httpx` での実現方法を検索 (Google) できます。
@@ -121,7 +121,7 @@ FastAPIアプリケーションへのリクエストの送信とは別に、テ
(`httpx` または `TestClient` を使用して) バックエンドにデータを渡す方法の詳細は、HTTPXのドキュメントを確認してください。
-/// info | "情報"
+/// info | 情報
`TestClient` は、Pydanticモデルではなく、JSONに変換できるデータを受け取ることに注意してください。
diff --git a/docs/ko/docs/advanced/advanced-dependencies.md b/docs/ko/docs/advanced/advanced-dependencies.md
new file mode 100644
index 000000000..aa5a332f8
--- /dev/null
+++ b/docs/ko/docs/advanced/advanced-dependencies.md
@@ -0,0 +1,179 @@
+# 고급 의존성
+
+## 매개변수화된 의존성
+
+지금까지 본 모든 의존성은 고정된 함수 또는 클래스입니다.
+
+하지만 여러 개의 함수나 클래스를 선언하지 않고도 의존성에 매개변수를 설정해야 하는 경우가 있을 수 있습니다.
+
+예를 들어, `q` 쿼리 매개변수가 특정 고정된 내용을 포함하고 있는지 확인하는 의존성을 원한다고 가정해 봅시다.
+
+이때 해당 고정된 내용을 매개변수화할 수 있길 바랍니다.
+
+## "호출 가능한" 인스턴스
+
+Python에는 클래스의 인스턴스를 "호출 가능"하게 만드는 방법이 있습니다.
+
+클래스 자체(이미 호출 가능함)가 아니라 해당 클래스의 인스턴스에 대해 호출 가능하게 하는 것입니다.
+
+이를 위해 `__call__` 메서드를 선언합니다:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="12"
+{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="11"
+{!> ../../docs_src/dependencies/tutorial011_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | 참고
+
+가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
+
+///
+
+```Python hl_lines="10"
+{!> ../../docs_src/dependencies/tutorial011.py!}
+```
+
+////
+
+이 경우, **FastAPI**는 추가 매개변수와 하위 의존성을 확인하기 위해 `__call__`을 사용하게 되며,
+나중에 *경로 연산 함수*에서 매개변수에 값을 전달할 때 이를 호출하게 됩니다.
+
+## 인스턴스 매개변수화하기
+
+이제 `__init__`을 사용하여 의존성을 "매개변수화"할 수 있는 인스턴스의 매개변수를 선언할 수 있습니다:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="9"
+{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="8"
+{!> ../../docs_src/dependencies/tutorial011_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | 참고
+
+가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
+
+///
+
+```Python hl_lines="7"
+{!> ../../docs_src/dependencies/tutorial011.py!}
+```
+
+////
+
+이 경우, **FastAPI**는 `__init__`에 전혀 관여하지 않으며, 우리는 이 메서드를 코드에서 직접 사용하게 됩니다.
+
+## 인스턴스 생성하기
+
+다음과 같이 이 클래스의 인스턴스를 생성할 수 있습니다:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="18"
+{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="17"
+{!> ../../docs_src/dependencies/tutorial011_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | 참고
+
+가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
+
+///
+
+```Python hl_lines="16"
+{!> ../../docs_src/dependencies/tutorial011.py!}
+```
+
+////
+
+이렇게 하면 `checker.fixed_content` 속성에 `"bar"`라는 값을 담아 의존성을 "매개변수화"할 수 있습니다.
+
+## 인스턴스를 의존성으로 사용하기
+
+그런 다음, `Depends(FixedContentQueryChecker)` 대신 `Depends(checker)`에서 이 `checker` 인스턴스를 사용할 수 있으며,
+클래스 자체가 아닌 인스턴스 `checker`가 의존성이 됩니다.
+
+의존성을 해결할 때 **FastAPI**는 이 `checker`를 다음과 같이 호출합니다:
+
+```Python
+checker(q="somequery")
+```
+
+...그리고 이때 반환되는 값을 *경로 연산 함수*의 `fixed_content_included` 매개변수로 전달합니다:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="22"
+{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="21"
+{!> ../../docs_src/dependencies/tutorial011_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | 참고
+
+가능하다면 `Annotated` 버전을 사용하는 것이 좋습니다.
+
+///
+
+```Python hl_lines="20"
+{!> ../../docs_src/dependencies/tutorial011.py!}
+```
+
+////
+
+/// tip | 참고
+
+이 모든 과정이 복잡하게 느껴질 수 있습니다. 그리고 지금은 이 방법이 얼마나 유용한지 명확하지 않을 수도 있습니다.
+
+이 예시는 의도적으로 간단하게 만들었지만, 전체 구조가 어떻게 작동하는지 보여줍니다.
+
+보안 관련 장에서는 이와 같은 방식으로 구현된 편의 함수들이 있습니다.
+
+이 모든 과정을 이해했다면, 이러한 보안 도구들이 내부적으로 어떻게 작동하는지 이미 파악한 것입니다.
+
+///
diff --git a/docs/ko/docs/advanced/events.md b/docs/ko/docs/advanced/events.md
index e155f41f1..273c9a479 100644
--- a/docs/ko/docs/advanced/events.md
+++ b/docs/ko/docs/advanced/events.md
@@ -4,7 +4,7 @@
이 함수들은 `async def` 또는 평범하게 `def`으로 선언할 수 있습니다.
-/// warning | "경고"
+/// warning | 경고
이벤트 핸들러는 주 응용 프로그램에서만 작동합니다. [하위 응용 프로그램 - 마운트](./sub-applications.md){.internal-link target=_blank}에서는 작동하지 않습니다.
@@ -15,7 +15,7 @@
응용 프로그램을 시작하기 전에 실행하려는 함수를 "startup" 이벤트로 선언합니다:
```Python hl_lines="8"
-{!../../../docs_src/events/tutorial001.py!}
+{!../../docs_src/events/tutorial001.py!}
```
이 경우 `startup` 이벤트 핸들러 함수는 단순히 몇 가지 값으로 구성된 `dict` 형식의 "데이터베이스"를 초기화합니다.
@@ -29,18 +29,18 @@
응용 프로그램이 종료될 때 실행하려는 함수를 추가하려면 `"shutdown"` 이벤트로 선언합니다:
```Python hl_lines="6"
-{!../../../docs_src/events/tutorial002.py!}
+{!../../docs_src/events/tutorial002.py!}
```
이 예제에서 `shutdown` 이벤트 핸들러 함수는 `"Application shutdown"`이라는 텍스트가 적힌 `log.txt` 파일을 추가할 것입니다.
-/// info | "정보"
+/// info | 정보
`open()` 함수에서 `mode="a"`는 "추가"를 의미합니다. 따라서 이미 존재하는 파일의 내용을 덮어쓰지 않고 새로운 줄을 추가합니다.
///
-/// tip | "팁"
+/// tip | 팁
이 예제에서는 파일과 상호작용 하기 위해 파이썬 표준 함수인 `open()`을 사용하고 있습니다.
@@ -50,7 +50,7 @@
///
-/// info | "정보"
+/// info | 정보
이벤트 핸들러에 관한 내용은 Starlette 이벤트 문서에서 추가로 확인할 수 있습니다.
diff --git a/docs/ko/docs/advanced/index.md b/docs/ko/docs/advanced/index.md
index cb628fa10..31704727c 100644
--- a/docs/ko/docs/advanced/index.md
+++ b/docs/ko/docs/advanced/index.md
@@ -6,7 +6,7 @@
이어지는 장에서는 여러분이 다른 옵션, 구성 및 추가 기능을 보실 수 있습니다.
-/// tip | "팁"
+/// tip | 팁
다음 장들이 **반드시 "심화"**인 것은 아닙니다.
diff --git a/docs/ko/docs/advanced/response-change-status-code.md b/docs/ko/docs/advanced/response-change-status-code.md
new file mode 100644
index 000000000..f3cdd2ba5
--- /dev/null
+++ b/docs/ko/docs/advanced/response-change-status-code.md
@@ -0,0 +1,33 @@
+# 응답 - 상태 코드 변경
+
+기본 [응답 상태 코드 설정](../tutorial/response-status-code.md){.internal-link target=_blank}이 가능하다는 걸 이미 알고 계실 겁니다.
+
+하지만 경우에 따라 기본 설정과 다른 상태 코드를 반환해야 할 때가 있습니다.
+
+## 사용 예
+
+예를 들어 기본적으로 HTTP 상태 코드 "OK" `200`을 반환하고 싶다고 가정해 봅시다.
+
+하지만 데이터가 존재하지 않으면 이를 새로 생성하고, HTTP 상태 코드 "CREATED" `201`을 반환하고자 할 때가 있을 수 있습니다.
+
+이때도 여전히 `response_model`을 사용하여 반환하는 데이터를 필터링하고 변환하고 싶을 수 있습니다.
+
+이런 경우에는 `Response` 파라미터를 사용할 수 있습니다.
+
+## `Response` 파라미터 사용하기
+
+*경로 작동 함수*에 `Response` 타입의 파라미터를 선언할 수 있습니다. (쿠키와 헤더에 대해 선언하는 것과 유사하게)
+
+그리고 이 *임시* 응답 객체에서 `status_code`를 설정할 수 있습니다.
+
+```Python hl_lines="1 9 12"
+{!../../docs_src/response_change_status_code/tutorial001.py!}
+```
+
+그리고 평소처럼 원하는 객체(`dict`, 데이터베이스 모델 등)를 반환할 수 있습니다.
+
+`response_model`을 선언했다면 반환된 객체는 여전히 필터링되고 변환됩니다.
+
+**FastAPI**는 이 *임시* 응답 객체에서 상태 코드(쿠키와 헤더 포함)를 추출하여, `response_model`로 필터링된 반환 값을 최종 응답에 넣습니다.
+
+또한, 의존성에서도 `Response` 파라미터를 선언하고 그 안에서 상태 코드를 설정할 수 있습니다. 단, 마지막으로 설정된 상태 코드가 우선 적용된다는 점을 유의하세요.
diff --git a/docs/ko/docs/advanced/response-cookies.md b/docs/ko/docs/advanced/response-cookies.md
new file mode 100644
index 000000000..f762e94b5
--- /dev/null
+++ b/docs/ko/docs/advanced/response-cookies.md
@@ -0,0 +1,53 @@
+# 응답 쿠키
+
+## `Response` 매개변수 사용하기
+
+*경로 작동 함수*에서 `Response` 타입의 매개변수를 선언할 수 있습니다.
+
+그런 다음 해당 *임시* 응답 객체에서 쿠키를 설정할 수 있습니다.
+
+```Python hl_lines="1 8-9"
+{!../../docs_src/response_cookies/tutorial002.py!}
+```
+
+그런 다음 필요한 객체(`dict`, 데이터베이스 모델 등)를 반환할 수 있습니다.
+
+그리고 `response_model`을 선언했다면 반환한 객체를 거르고 변환하는 데 여전히 사용됩니다.
+
+**FastAPI**는 그 *임시* 응답에서 쿠키(또한 헤더 및 상태 코드)를 추출하고, 반환된 값이 포함된 최종 응답에 이를 넣습니다. 이 값은 `response_model`로 걸러지게 됩니다.
+
+또한 의존관계에서 `Response` 매개변수를 선언하고, 해당 의존성에서 쿠키(및 헤더)를 설정할 수도 있습니다.
+
+## `Response`를 직접 반환하기
+
+코드에서 `Response`를 직접 반환할 때도 쿠키를 생성할 수 있습니다.
+
+이를 위해 [Response를 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 설명한 대로 응답을 생성할 수 있습니다.
+
+그런 다음 쿠키를 설정하고 반환하면 됩니다:
+```Python hl_lines="1 18"
+{!../../docs_src/response_directly/tutorial002.py!}
+```
+/// tip
+
+`Response` 매개변수를 사용하지 않고 응답을 직접 반환하는 경우, FastAPI는 이를 직접 반환한다는 점에 유의하세요.
+
+따라서 데이터가 올바른 유형인지 확인해야 합니다. 예: `JSONResponse`를 반환하는 경우, JSON과 호환되는지 확인하세요.
+
+또한 `response_model`로 걸러져야 할 데이터가 전달되지 않도록 확인하세요.
+
+///
+
+### 추가 정보
+
+/// note | 기술적 세부사항
+
+`from starlette.responses import Response` 또는 `from starlette.responses import JSONResponse`를 사용할 수도 있습니다.
+
+**FastAPI**는 개발자의 편의를 위해 `fastapi.responses`로 동일한 `starlette.responses`를 제공합니다. 그러나 대부분의 응답은 Starlette에서 직접 제공됩니다.
+
+또한 `Response`는 헤더와 쿠키를 설정하는 데 자주 사용되므로, **FastAPI**는 이를 `fastapi.Response`로도 제공합니다.
+
+///
+
+사용 가능한 모든 매개변수와 옵션은 Starlette 문서에서 확인할 수 있습니다.
diff --git a/docs/ko/docs/advanced/response-directly.md b/docs/ko/docs/advanced/response-directly.md
new file mode 100644
index 000000000..aedebff9d
--- /dev/null
+++ b/docs/ko/docs/advanced/response-directly.md
@@ -0,0 +1,67 @@
+# 응답을 직접 반환하기
+
+**FastAPI**에서 *경로 작업(path operation)*을 생성할 때, 일반적으로 `dict`, `list`, Pydantic 모델, 데이터베이스 모델 등의 데이터를 반환할 수 있습니다.
+
+기본적으로 **FastAPI**는 [JSON 호환 가능 인코더](../tutorial/encoder.md){.internal-link target=_blank}에 설명된 `jsonable_encoder`를 사용해 해당 반환 값을 자동으로 `JSON`으로 변환합니다.
+
+그런 다음, JSON 호환 데이터(예: `dict`)를 `JSONResponse`에 넣어 사용자의 응답을 전송하는 방식으로 처리됩니다.
+
+그러나 *경로 작업*에서 `JSONResponse`를 직접 반환할 수도 있습니다.
+
+예를 들어, 사용자 정의 헤더나 쿠키를 반환해야 하는 경우에 유용할 수 있습니다.
+
+## `Response` 반환하기
+
+사실, `Response` 또는 그 하위 클래스를 반환할 수 있습니다.
+
+/// tip
+
+`JSONResponse` 자체도 `Response`의 하위 클래스입니다.
+
+///
+
+그리고 `Response`를 반환하면 **FastAPI**가 이를 그대로 전달합니다.
+
+Pydantic 모델로 데이터 변환을 수행하지 않으며, 내용을 다른 형식으로 변환하지 않습니다.
+
+이로 인해 많은 유연성을 얻을 수 있습니다. 어떤 데이터 유형이든 반환할 수 있고, 데이터 선언이나 유효성 검사를 재정의할 수 있습니다.
+
+## `Response`에서 `jsonable_encoder` 사용하기
+
+**FastAPI**는 반환하는 `Response`에 아무런 변환을 하지 않으므로, 그 내용이 준비되어 있어야 합니다.
+
+예를 들어, Pydantic 모델을 `dict`로 변환해 `JSONResponse`에 넣지 않으면 JSON 호환 유형으로 변환된 데이터 유형(예: `datetime`, `UUID` 등)이 사용되지 않습니다.
+
+이러한 경우, 데이터를 응답에 전달하기 전에 `jsonable_encoder`를 사용하여 변환할 수 있습니다:
+
+```Python hl_lines="6-7 21-22"
+{!../../docs_src/response_directly/tutorial001.py!}
+```
+
+/// note | 기술적 세부 사항
+
+`from starlette.responses import JSONResponse`를 사용할 수도 있습니다.
+
+**FastAPI**는 개발자의 편의를 위해 `starlette.responses`를 `fastapi.responses`로 제공합니다. 그러나 대부분의 가능한 응답은 Starlette에서 직접 제공합니다.
+
+///
+
+## 사용자 정의 `Response` 반환하기
+위 예제는 필요한 모든 부분을 보여주지만, 아직 유용하지는 않습니다. 사실 데이터를 직접 반환하면 **FastAPI**가 이를 `JSONResponse`에 넣고 `dict`로 변환하는 등 모든 작업을 자동으로 처리합니다.
+
+이제, 사용자 정의 응답을 반환하는 방법을 알아보겠습니다.
+
+예를 들어 XML 응답을 반환하고 싶다고 가정해보겠습니다.
+
+XML 내용을 문자열에 넣고, 이를 `Response`에 넣어 반환할 수 있습니다:
+
+```Python hl_lines="1 18"
+{!../../docs_src/response_directly/tutorial002.py!}
+```
+
+## 참고 사항
+`Response`를 직접 반환할 때, 그 데이터는 자동으로 유효성 검사되거나, 변환(직렬화)되거나, 문서화되지 않습니다.
+
+그러나 [OpenAPI에서 추가 응답](additional-responses.md){.internal-link target=_blank}에서 설명된 대로 문서화할 수 있습니다.
+
+이후 단락에서 자동 데이터 변환, 문서화 등을 사용하면서 사용자 정의 `Response`를 선언하는 방법을 확인할 수 있습니다.
diff --git a/docs/ko/docs/advanced/response-headers.md b/docs/ko/docs/advanced/response-headers.md
new file mode 100644
index 000000000..974a06969
--- /dev/null
+++ b/docs/ko/docs/advanced/response-headers.md
@@ -0,0 +1,45 @@
+# 응답 헤더
+
+## `Response` 매개변수 사용하기
+
+여러분은 *경로 작동 함수*에서 `Response` 타입의 매개변수를 선언할 수 있습니다 (쿠키와 같이 사용할 수 있습니다).
+
+그런 다음, 여러분은 해당 *임시* 응답 객체에서 헤더를 설정할 수 있습니다.
+
+```Python hl_lines="1 7-8"
+{!../../docs_src/response_headers/tutorial002.py!}
+```
+
+그 후, 일반적으로 사용하듯이 필요한 객체(`dict`, 데이터베이스 모델 등)를 반환할 수 있습니다.
+
+`response_model`을 선언한 경우, 반환한 객체를 필터링하고 변환하는 데 여전히 사용됩니다.
+
+**FastAPI**는 해당 *임시* 응답에서 헤더(쿠키와 상태 코드도 포함)를 추출하여, 여러분이 반환한 값을 포함하는 최종 응답에 `response_model`로 필터링된 값을 넣습니다.
+
+또한, 종속성에서 `Response` 매개변수를 선언하고 그 안에서 헤더(및 쿠키)를 설정할 수 있습니다.
+
+## `Response` 직접 반환하기
+
+`Response`를 직접 반환할 때에도 헤더를 추가할 수 있습니다.
+
+[응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 설명한 대로 응답을 생성하고, 헤더를 추가 매개변수로 전달하세요.
+
+```Python hl_lines="10-12"
+{!../../docs_src/response_headers/tutorial001.py!}
+```
+
+/// note | 기술적 세부사항
+
+`from starlette.responses import Response`나 `from starlette.responses import JSONResponse`를 사용할 수도 있습니다.
+
+**FastAPI**는 `starlette.responses`를 `fastapi.responses`로 개발자의 편의를 위해 직접 제공하지만, 대부분의 응답은 Starlette에서 직접 제공됩니다.
+
+그리고 `Response`는 헤더와 쿠키를 설정하는 데 자주 사용될 수 있으므로, **FastAPI**는 `fastapi.Response`로도 이를 제공합니다.
+
+///
+
+## 커스텀 헤더
+
+‘X-’ 접두어를 사용하여 커스텀 사설 헤더를 추가할 수 있습니다.
+
+하지만, 여러분이 브라우저에서 클라이언트가 볼 수 있기를 원하는 커스텀 헤더가 있는 경우, CORS 설정에 이를 추가해야 합니다([CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}에서 자세히 알아보세요). `expose_headers` 매개변수를 사용하여 Starlette의 CORS 설명서에 문서화된 대로 설정할 수 있습니다.
diff --git a/docs/ko/docs/advanced/testing-events.md b/docs/ko/docs/advanced/testing-events.md
new file mode 100644
index 000000000..dc082412a
--- /dev/null
+++ b/docs/ko/docs/advanced/testing-events.md
@@ -0,0 +1,7 @@
+# 이벤트 테스트: 시작 - 종료
+
+테스트에서 이벤트 핸들러(`startup` 및 `shutdown`)를 실행해야 하는 경우, `with` 문과 함께 `TestClient`를 사용할 수 있습니다.
+
+```Python hl_lines="9-12 20-24"
+{!../../docs_src/app_testing/tutorial003.py!}
+```
diff --git a/docs/ko/docs/advanced/testing-websockets.md b/docs/ko/docs/advanced/testing-websockets.md
new file mode 100644
index 000000000..f1580c3c3
--- /dev/null
+++ b/docs/ko/docs/advanced/testing-websockets.md
@@ -0,0 +1,15 @@
+# WebSocket 테스트하기
+
+`TestClient`를 사용하여 WebSocket을 테스트할 수 있습니다.
+
+이를 위해 `with` 문에서 `TestClient`를 사용하여 WebSocket에 연결합니다:
+
+```Python hl_lines="27-31"
+{!../../docs_src/app_testing/tutorial002.py!}
+```
+
+/// note | 참고
+
+자세한 내용은 Starlette의 WebSocket 테스트에 관한 설명서를 참고하시길 바랍니다.
+
+///
diff --git a/docs/ko/docs/advanced/using-request-directly.md b/docs/ko/docs/advanced/using-request-directly.md
new file mode 100644
index 000000000..027ea9fad
--- /dev/null
+++ b/docs/ko/docs/advanced/using-request-directly.md
@@ -0,0 +1,58 @@
+# `Request` 직접 사용하기
+
+지금까지 요청에서 필요한 부분을 각 타입으로 선언하여 사용해 왔습니다.
+
+다음과 같은 곳에서 데이터를 가져왔습니다:
+
+* 경로의 파라미터로부터.
+* 헤더.
+* 쿠키.
+* 기타 등등.
+
+이렇게 함으로써, **FastAPI**는 데이터를 검증하고 변환하며, API에 대한 문서를 자동화로 생성합니다.
+
+하지만 `Request` 객체에 직접 접근해야 하는 상황이 있을 수 있습니다.
+
+## `Request` 객체에 대한 세부 사항
+
+**FastAPI**는 실제로 내부에 **Starlette**을 사용하며, 그 위에 여러 도구를 덧붙인 구조입니다. 따라서 여러분이 필요할 때 Starlette의 `Request` 객체를 직접 사용할 수 있습니다.
+
+`Request` 객체에서 데이터를 직접 가져오는 경우(예: 본문을 읽기)에는 FastAPI가 해당 데이터를 검증하거나 변환하지 않으며, 문서화(OpenAPI를 통한 문서 자동화(로 생성된) API 사용자 인터페이스)도 되지 않습니다.
+
+그러나 다른 매개변수(예: Pydantic 모델을 사용한 본문)는 여전히 검증, 변환, 주석 추가 등이 이루어집니다.
+
+하지만 특정한 경우에는 `Request` 객체에 직접 접근하는 것이 유용할 수 있습니다.
+
+## `Request` 객체를 직접 사용하기
+
+여러분이 클라이언트의 IP 주소/호스트 정보를 *경로 작동 함수* 내부에서 가져와야 한다고 가정해 보겠습니다.
+
+이를 위해서는 요청에 직접 접근해야 합니다.
+
+```Python hl_lines="1 7-8"
+{!../../docs_src/using_request_directly/tutorial001.py!}
+```
+
+*경로 작동 함수* 매개변수를 `Request` 타입으로 선언하면 **FastAPI**가 해당 매개변수에 `Request` 객체를 전달하는 것을 알게 됩니다.
+
+/// tip | 팁
+
+이 경우, 요청 매개변수와 함께 경로 매개변수를 선언한 것을 볼 수 있습니다.
+
+따라서, 경로 매개변수는 추출되고 검증되며 지정된 타입으로 변환되고 OpenAPI로 주석이 추가됩니다.
+
+이와 같은 방식으로, 다른 매개변수들을 평소처럼 선언하면서, 부가적으로 `Request`도 가져올 수 있습니다.
+
+///
+
+## `Request` 설명서
+
+여러분은 `Request` 객체에 대한 더 자세한 내용을 공식 Starlette 설명서 사이트에서 읽어볼 수 있습니다.
+
+/// note | 기술 세부사항
+
+`from starlette.requests import Request`를 사용할 수도 있습니다.
+
+**FastAPI**는 여러분(개발자)를 위한 편의를 위해 이를 직접 제공하지만, 실제로는 Starlette에서 가져온 것입니다.
+
+///
diff --git a/docs/ko/docs/advanced/wsgi.md b/docs/ko/docs/advanced/wsgi.md
new file mode 100644
index 000000000..87aabf203
--- /dev/null
+++ b/docs/ko/docs/advanced/wsgi.md
@@ -0,0 +1,37 @@
+# WSGI 포함하기 - Flask, Django 그 외
+
+[서브 응용 프로그램 - 마운트](sub-applications.md){.internal-link target=_blank}, [프록시 뒤편에서](behind-a-proxy.md){.internal-link target=_blank}에서 보았듯이 WSGI 응용 프로그램들을 다음과 같이 마운트 할 수 있습니다.
+
+`WSGIMiddleware`를 사용하여 WSGI 응용 프로그램(예: Flask, Django 등)을 감쌀 수 있습니다.
+
+## `WSGIMiddleware` 사용하기
+
+`WSGIMiddleware`를 불러와야 합니다.
+
+그런 다음, WSGI(예: Flask) 응용 프로그램을 미들웨어로 포장합니다.
+
+그 후, 해당 경로에 마운트합니다.
+
+```Python hl_lines="2-3 23"
+{!../../docs_src/wsgi/tutorial001.py!}
+```
+
+## 확인하기
+
+이제 `/v1/` 경로에 있는 모든 요청은 Flask 응용 프로그램에서 처리됩니다.
+
+그리고 나머지는 **FastAPI**에 의해 처리됩니다.
+
+실행하면 http://localhost:8000/v1/으로 이동해서 Flask의 응답을 볼 수 있습니다:
+
+```txt
+Hello, World from Flask!
+```
+
+그리고 다음으로 이동하면 http://localhost:8000/v2 Flask의 응답을 볼 수 있습니다:
+
+```JSON
+{
+ "message": "Hello World"
+}
+```
diff --git a/docs/ko/docs/async.md b/docs/ko/docs/async.md
index dfc2caa78..fa0d20488 100644
--- a/docs/ko/docs/async.md
+++ b/docs/ko/docs/async.md
@@ -21,7 +21,7 @@ async def read_results():
return results
```
-/// note | "참고"
+/// note | 참고
`async def`로 생성된 함수 내부에서만 `await`를 사용할 수 있습니다.
@@ -369,7 +369,7 @@ FastAPI를 사용하지 않더라도, 높은 호환성 및 가장 빠른 Python 프레임워크 중 하나로 실행되며, Starlette와 Uvicorn 자체(내부적으로 FastAPI가 사용하는 도구)보다 조금 아래에 위치합니다.
+
+그러나 벤치마크와 비교를 확인할 때 다음 사항을 염두에 두어야 합니다.
+
+## 벤치마크와 속도
+
+벤치마크를 확인할 때, 일반적으로 여러 가지 유형의 도구가 동등한 것으로 비교되는 것을 볼 수 있습니다.
+
+특히, Uvicorn, Starlette, FastAPI가 함께 비교되는 경우가 많습니다(다른 여러 도구와 함께).
+
+도구가 해결하는 문제가 단순할수록 성능이 더 좋아집니다. 그리고 대부분의 벤치마크는 도구가 제공하는 추가 기능을 테스트하지 않습니다.
+
+계층 구조는 다음과 같습니다:
+
+* **Uvicorn**: ASGI 서버
+ * **Starlette**: (Uvicorn 사용) 웹 마이크로 프레임워크
+ * **FastAPI**: (Starlette 사용) API 구축을 위한 데이터 검증 등 여러 추가 기능이 포함된 API 마이크로 프레임워크
+
+* **Uvicorn**:
+ * 서버 자체 외에는 많은 추가 코드가 없기 때문에 최고의 성능을 발휘합니다.
+ * 직접 Uvicorn으로 응용 프로그램을 작성하지는 않을 것입니다. 즉, 사용자의 코드에는 적어도 Starlette(또는 **FastAPI**)에서 제공하는 모든 코드가 포함되어야 합니다. 그렇게 하면 최종 응용 프로그램은 프레임워크를 사용하고 앱 코드와 버그를 최소화하는 것과 동일한 오버헤드를 갖게 됩니다.
+ * Uvicorn을 비교할 때는 Daphne, Hypercorn, uWSGI 등의 응용 프로그램 서버와 비교하세요.
+* **Starlette**:
+ * Uvicorn 다음으로 좋은 성능을 발휘합니다. 사실 Starlette는 Uvicorn을 사용하여 실행됩니다. 따라서 더 많은 코드를 실행해야 하기 때문에 Uvicorn보다 "느려질" 수밖에 없습니다.
+ * 하지만 경로 기반 라우팅 등 간단한 웹 응용 프로그램을 구축할 수 있는 도구를 제공합니다.
+ * Starlette를 비교할 때는 Sanic, Flask, Django 등의 웹 프레임워크(또는 마이크로 프레임워크)와 비교하세요.
+* **FastAPI**:
+ * Starlette가 Uvicorn을 사용하므로 Uvicorn보다 빨라질 수 없는 것과 마찬가지로, **FastAPI**는 Starlette를 사용하므로 더 빠를 수 없습니다.
+ * FastAPI는 Starlette에 추가적으로 더 많은 기능을 제공합니다. API를 구축할 때 거의 항상 필요한 데이터 검증 및 직렬화와 같은 기능들이 포함되어 있습니다. 그리고 이를 사용하면 문서 자동화 기능도 제공됩니다(문서 자동화는 응용 프로그램 실행 시 오버헤드를 추가하지 않고 시작 시 생성됩니다).
+ * FastAPI를 사용하지 않고 직접 Starlette(또는 Sanic, Flask, Responder 등)를 사용했다면 데이터 검증 및 직렬화를 직접 구현해야 합니다. 따라서 최종 응용 프로그램은 FastAPI를 사용한 것과 동일한 오버헤드를 가지게 될 것입니다. 많은 경우 데이터 검증 및 직렬화가 응용 프로그램에서 작성된 코드 중 가장 많은 부분을 차지합니다.
+ * 따라서 FastAPI를 사용함으로써 개발 시간, 버그, 코드 라인을 줄일 수 있으며, FastAPI를 사용하지 않았을 때와 동일하거나 더 나은 성능을 얻을 수 있습니다(코드에서 모두 구현해야 하기 때문에).
+ * FastAPI를 비교할 때는 Flask-apispec, NestJS, Molten 등 데이터 검증, 직렬화 및 문서화가 통합된 자동 데이터 검증, 직렬화 및 문서화를 제공하는 웹 응용 프로그램 프레임워크(또는 도구 집합)와 비교하세요.
diff --git a/docs/ko/docs/deployment/docker.md b/docs/ko/docs/deployment/docker.md
index 502a36fc0..e8b2746c5 100644
--- a/docs/ko/docs/deployment/docker.md
+++ b/docs/ko/docs/deployment/docker.md
@@ -4,7 +4,7 @@ FastAPI 어플리케이션을 배포할 때 일반적인 접근 방법은 **리
리눅스 컨테이너를 사용하는 데에는 **보안**, **반복 가능성**, **단순함** 등의 장점이 있습니다.
-/// tip | "팁"
+/// tip | 팁
시간에 쫓기고 있고 이미 이런것들을 알고 있다면 [`Dockerfile`👇](#build-a-docker-image-for-fastapi)로 점프할 수 있습니다.
@@ -133,7 +133,7 @@ Successfully installed fastapi pydantic uvicorn
-/// info | "정보"
+/// info | 정보
패키지 종속성을 정의하고 설치하기 위한 방법과 도구는 다양합니다.
@@ -231,7 +231,7 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
프로그램이 `/code`에서 시작하고 그 속에 `./app` 디렉터리가 여러분의 코드와 함께 들어있기 때문에, **Uvicorn**은 이를 보고 `app`을 `app.main`으로부터 **불러 올** 것입니다.
-/// tip | "팁"
+/// tip | 팁
각 코드 라인을 코드의 숫자 버블을 클릭하여 리뷰할 수 있습니다. 👆
@@ -305,7 +305,7 @@ $ docker build -t myimage .
-/// tip | "팁"
+/// tip | 팁
맨 끝에 있는 `.` 에 주목합시다. 이는 `./`와 동등하며, 도커에게 컨테이너 이미지를 빌드하기 위한 디렉터리를 알려줍니다.
@@ -409,7 +409,7 @@ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
**HTTPS**와 **인증서**의 **자동** 취득을 다루는 것은 다른 컨테이너가 될 수 있는데, 예를 들어 Traefik을 사용하는 것입니다.
-/// tip | "팁"
+/// tip | 팁
Traefik은 도커, 쿠버네티스, 그리고 다른 도구와 통합되어 있어 여러분의 컨테이너를 포함하는 HTTPS를 셋업하고 설정하는 것이 매우 쉽습니다.
@@ -441,7 +441,7 @@ Traefik은 도커, 쿠버네티스, 그리고 다른 도구와 통합되어 있
이 요소가 요청들의 **로드**를 읽어들이고 각 워커에게 (바라건대) **균형적으로** 분배한다면, 이 요소는 일반적으로 **로드 밸런서**라고 불립니다.
-/// tip | "팁"
+/// tip | 팁
HTTPS를 위해 사용된 **TLS 종료 프록시** 요소 또한 **로드 밸런서**가 될 수 있습니다.
@@ -524,7 +524,7 @@ HTTPS를 위해 사용된 **TLS 종료 프록시** 요소 또한 **로드 밸런
만약 여러분이 **여러개의 컨테이너**를 가지고 있다면, 아마도 각각의 컨테이너는 **하나의 프로세스**를 가지고 있을 것입니다(예를 들어, **쿠버네티스** 클러스터에서). 그러면 여러분은 복제된 워커 컨테이너를 실행하기 **이전에**, 하나의 컨테이너에 있는 **이전의 단계들을** 수행하는 단일 프로세스를 가지는 **별도의 컨테이너들**을 가지고 싶을 것입니다.
-/// info | "정보"
+/// info | 정보
만약 여러분이 쿠버네티스를 사용하고 있다면, 아마도 이는 Init Container일 것입니다.
@@ -544,7 +544,7 @@ HTTPS를 위해 사용된 **TLS 종료 프록시** 요소 또한 **로드 밸런
* tiangolo/uvicorn-gunicorn-fastapi.
-/// warning | "경고"
+/// warning | 경고
여러분이 이 베이스 이미지 또는 다른 유사한 이미지를 필요로 하지 **않을** 높은 가능성이 있으며, [위에서 설명된 것처럼: FastAPI를 위한 도커 이미지 빌드하기](#build-a-docker-image-for-fastapi) 처음부터 이미지를 빌드하는 것이 더 나을 수 있습니다.
@@ -556,7 +556,7 @@ HTTPS를 위해 사용된 **TLS 종료 프록시** 요소 또한 **로드 밸런
또한 스크립트를 통해 **시작하기 전 사전 단계**를 실행하는 것을 지원합니다.
-/// tip | "팁"
+/// tip | 팁
모든 설정과 옵션을 보려면, 도커 이미지 페이지로 이동합니다: tiangolo/uvicorn-gunicorn-fastapi.
@@ -687,7 +687,7 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
11. `uvicorn` 커맨드를 실행하여, `app.main`에서 불러온 `app` 객체를 사용하도록 합니다.
-/// tip | "팁"
+/// tip | 팁
버블 숫자를 클릭해 각 줄이 하는 일을 알아볼 수 있습니다.
diff --git a/docs/ko/docs/deployment/server-workers.md b/docs/ko/docs/deployment/server-workers.md
index 39976faf5..b40b25cd8 100644
--- a/docs/ko/docs/deployment/server-workers.md
+++ b/docs/ko/docs/deployment/server-workers.md
@@ -17,7 +17,7 @@
지금부터 **구니콘**을 **유비콘 워커 프로세스**와 함께 사용하는 방법을 알려드리겠습니다.
-/// info | "정보"
+/// info | 정보
만약 도커와 쿠버네티스 같은 컨테이너를 사용하고 있다면 다음 챕터 [FastAPI와 컨테이너 - 도커](docker.md){.internal-link target=_blank}에서 더 많은 정보를 얻을 수 있습니다.
diff --git a/docs/ko/docs/deployment/versions.md b/docs/ko/docs/deployment/versions.md
index f3b3c2d7b..559a892ab 100644
--- a/docs/ko/docs/deployment/versions.md
+++ b/docs/ko/docs/deployment/versions.md
@@ -43,7 +43,7 @@ fastapi>=0.45.0,<0.46.0
FastAPI는 오류를 수정하고, 일반적인 변경사항을 위해 "패치"버전의 관습을 따릅니다.
-/// tip | "팁"
+/// tip | 팁
여기서 말하는 "패치"란 버전의 마지막 숫자로, 예를 들어 `0.2.3` 버전에서 "패치"는 `3`을 의미합니다.
@@ -57,7 +57,7 @@ fastapi>=0.45.0,<0.46.0
수정된 사항과 새로운 요소들이 "마이너" 버전에 추가되었습니다.
-/// tip | "팁"
+/// tip | 팁
"마이너"란 버전 넘버의 가운데 숫자로, 예를 들어서 `0.2.3`의 "마이너" 버전은 `2`입니다.
diff --git a/docs/ko/docs/environment-variables.md b/docs/ko/docs/environment-variables.md
new file mode 100644
index 000000000..1e6af3ceb
--- /dev/null
+++ b/docs/ko/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# 환경 변수
+
+/// tip | 팁
+
+만약 "환경 변수"가 무엇이고, 어떻게 사용하는지 알고 계시다면, 이 챕터를 스킵하셔도 좋습니다.
+
+///
+
+환경 변수는 파이썬 코드의 **바깥**인, **운영 체제**에 존재하는 변수입니다. 파이썬 코드나 다른 프로그램에서 읽을 수 있습니다.
+
+환경 변수는 애플리케이션 **설정**을 처리하거나, 파이썬의 **설치** 과정의 일부로 유용합니다.
+
+## 환경 변수를 만들고 사용하기
+
+파이썬 없이도, **셸 (터미널)** 에서 환경 변수를 **생성** 하고 사용할 수 있습니다.
+
+//// tab | Linux, macOS, Windows Bash
+
+
-/// tip | "팁"
+/// tip | 팁
만약 PyCharm를 편집기로 사용한다면, Pydantic PyCharm Plugin을 사용할 수 있습니다.
@@ -170,7 +170,7 @@
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/body/tutorial002_py310.py!}
+{!> ../../docs_src/body/tutorial002_py310.py!}
```
////
@@ -178,7 +178,7 @@
//// tab | Python 3.8+
```Python hl_lines="21"
-{!> ../../../docs_src/body/tutorial002.py!}
+{!> ../../docs_src/body/tutorial002.py!}
```
////
@@ -192,7 +192,7 @@
//// tab | Python 3.10+
```Python hl_lines="15-16"
-{!> ../../../docs_src/body/tutorial003_py310.py!}
+{!> ../../docs_src/body/tutorial003_py310.py!}
```
////
@@ -200,7 +200,7 @@
//// tab | Python 3.8+
```Python hl_lines="17-18"
-{!> ../../../docs_src/body/tutorial003.py!}
+{!> ../../docs_src/body/tutorial003.py!}
```
////
@@ -214,7 +214,7 @@
//// tab | Python 3.10+
```Python hl_lines="16"
-{!> ../../../docs_src/body/tutorial004_py310.py!}
+{!> ../../docs_src/body/tutorial004_py310.py!}
```
////
@@ -222,7 +222,7 @@
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/body/tutorial004.py!}
+{!> ../../docs_src/body/tutorial004.py!}
```
////
@@ -233,7 +233,7 @@
* 만약 매개변수가 (`int`, `float`, `str`, `bool` 등과 같은) **유일한 타입**으로 되어있으면, **쿼리** 매개변수로 해석될 것입니다.
* 만약 매개변수가 **Pydantic 모델** 타입으로 선언되어 있으면, 요청 **본문**으로 해석될 것입니다.
-/// note | "참고"
+/// note | 참고
FastAPI는 `q`의 값이 필요없음을 알게 될 것입니다. 기본 값이 `= None`이기 때문입니다.
diff --git a/docs/ko/docs/tutorial/cookie-params.md b/docs/ko/docs/tutorial/cookie-params.md
index 5f129b63f..427539210 100644
--- a/docs/ko/docs/tutorial/cookie-params.md
+++ b/docs/ko/docs/tutorial/cookie-params.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="1"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
@@ -67,7 +67,7 @@
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -75,7 +75,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -83,40 +83,40 @@
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="7"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
-/// note | "기술 세부사항"
+/// note | 기술 세부사항
`Cookie`는 `Path` 및 `Query`의 "자매"클래스입니다. 이 역시 동일한 공통 `Param` 클래스를 상속합니다.
@@ -124,7 +124,7 @@
///
-/// info | "정보"
+/// info | 정보
쿠키를 선언하기 위해서는 `Cookie`를 사용해야 합니다. 그렇지 않으면 해당 매개변수를 쿼리 매개변수로 해석하기 때문입니다.
diff --git a/docs/ko/docs/tutorial/cors.md b/docs/ko/docs/tutorial/cors.md
index 312fdee1b..0222e6258 100644
--- a/docs/ko/docs/tutorial/cors.md
+++ b/docs/ko/docs/tutorial/cors.md
@@ -47,7 +47,7 @@
* 특정한 HTTP 헤더 또는 와일드카드 `"*"` 를 사용한 모든 HTTP 헤더.
```Python hl_lines="2 6-11 13-19"
-{!../../../docs_src/cors/tutorial001.py!}
+{!../../docs_src/cors/tutorial001.py!}
```
`CORSMiddleware` 에서 사용하는 기본 매개변수는 제한적이므로, 브라우저가 교차-도메인 상황에서 특정한 출처, 메소드, 헤더 등을 사용할 수 있도록 하려면 이들을 명시적으로 허용해야 합니다.
@@ -78,7 +78,7 @@
CORS에 대한 더 많은 정보를 알고싶다면, Mozilla CORS 문서를 참고하기 바랍니다.
-/// note | "기술적 세부 사항"
+/// note | 기술적 세부 사항
`from starlette.middleware.cors import CORSMiddleware` 역시 사용할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/debugging.md b/docs/ko/docs/tutorial/debugging.md
index cb45e5169..fcb68b565 100644
--- a/docs/ko/docs/tutorial/debugging.md
+++ b/docs/ko/docs/tutorial/debugging.md
@@ -7,7 +7,7 @@
FastAPI 애플리케이션에서 `uvicorn`을 직접 임포트하여 실행합니다
```Python hl_lines="1 15"
-{!../../../docs_src/debugging/tutorial001.py!}
+{!../../docs_src/debugging/tutorial001.py!}
```
### `__name__ == "__main__"` 에 대하여
@@ -74,7 +74,7 @@ from myapp import app
은 실행되지 않습니다.
-/// info | "정보"
+/// info | 정보
자세한 내용은 공식 Python 문서를 확인하세요
diff --git a/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md
index 259fe4b6d..41e48aefc 100644
--- a/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/ko/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -9,7 +9,7 @@
//// tab | 파이썬 3.6 이상
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | 파이썬 3.10 이상
```Python hl_lines="7"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
@@ -84,7 +84,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.6 이상
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -92,7 +92,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.10 이상
```Python hl_lines="9-13"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
@@ -102,7 +102,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.6 이상
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -110,7 +110,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.10 이상
```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
@@ -120,7 +120,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.6 이상
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -128,7 +128,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.10 이상
```Python hl_lines="6"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
@@ -150,7 +150,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.6 이상
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -158,7 +158,7 @@ FastAPI가 실질적으로 확인하는 것은 "호출 가능성"(함수, 클래
//// tab | 파이썬 3.10 이상
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
@@ -203,7 +203,7 @@ commons = Depends(CommonQueryParams)
//// tab | 파이썬 3.6 이상
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003.py!}
+{!> ../../docs_src/dependencies/tutorial003.py!}
```
////
@@ -211,7 +211,7 @@ commons = Depends(CommonQueryParams)
//// tab | 파이썬 3.10 이상
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
+{!> ../../docs_src/dependencies/tutorial003_py310.py!}
```
////
@@ -251,7 +251,7 @@ commons: CommonQueryParams = Depends()
//// tab | 파이썬 3.6 이상
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004.py!}
+{!> ../../docs_src/dependencies/tutorial004.py!}
```
////
@@ -259,14 +259,14 @@ commons: CommonQueryParams = Depends()
//// tab | 파이썬 3.10 이상
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
+{!> ../../docs_src/dependencies/tutorial004_py310.py!}
```
////
...이렇게 코드를 단축하여도 **FastAPI**는 무엇을 해야하는지 알고 있습니다.
-/// tip | "팁"
+/// tip | 팁
만약 이것이 도움이 되기보다 더 헷갈리게 만든다면, 잊어버리십시오. 이것이 반드시 필요한 것은 아닙니다.
diff --git a/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
index bc8af488d..fab636b7f 100644
--- a/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
+++ b/docs/ko/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -25,28 +25,28 @@
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
이러한 의존성들은 기존 의존성들과 같은 방식으로 실행/해결됩니다. 그러나 값은 (무엇이든 반환한다면) *경로 작동 함수*에 제공되지 않습니다.
-/// tip | "팁"
+/// tip | 팁
일부 편집기에서는 사용되지 않는 함수 매개변수를 검사하고 오류로 표시합니다.
@@ -56,7 +56,7 @@
///
-/// info | "정보"
+/// info | 정보
이 예시에서 `X-Key`와 `X-Token`이라는 커스텀 헤더를 만들어 사용했습니다.
@@ -75,7 +75,7 @@
//// tab | Python 3.9+
```Python hl_lines="8 13"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -83,21 +83,21 @@
//// tab | Python 3.8+
```Python hl_lines="7 12"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="6 11"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -109,7 +109,7 @@
//// tab | Python 3.9+
```Python hl_lines="10 15"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -117,21 +117,21 @@
//// tab | Python 3.8+
```Python hl_lines="9 14"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="8 13"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -145,7 +145,7 @@
//// tab | Python 3.9+
```Python hl_lines="11 16"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -153,21 +153,21 @@
//// tab | Python 3.8+
```Python hl_lines="10 15"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="9 14"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
diff --git a/docs/ko/docs/tutorial/dependencies/global-dependencies.md b/docs/ko/docs/tutorial/dependencies/global-dependencies.md
index 2ce2cf4f2..0ad8b55fd 100644
--- a/docs/ko/docs/tutorial/dependencies/global-dependencies.md
+++ b/docs/ko/docs/tutorial/dependencies/global-dependencies.md
@@ -9,7 +9,7 @@
//// tab | Python 3.9+
```Python hl_lines="16"
-{!> ../../../docs_src/dependencies/tutorial012_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial012_an_py39.py!}
```
////
@@ -17,21 +17,21 @@
//// tab | Python 3.8+
```Python hl_lines="16"
-{!> ../../../docs_src/dependencies/tutorial012_an.py!}
+{!> ../../docs_src/dependencies/tutorial012_an.py!}
```
////
//// tab | Python 3.8 Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="15"
-{!> ../../../docs_src/dependencies/tutorial012.py!}
+{!> ../../docs_src/dependencies/tutorial012.py!}
```
////
diff --git a/docs/ko/docs/tutorial/dependencies/index.md b/docs/ko/docs/tutorial/dependencies/index.md
index 361989e2b..1aba6e787 100644
--- a/docs/ko/docs/tutorial/dependencies/index.md
+++ b/docs/ko/docs/tutorial/dependencies/index.md
@@ -34,7 +34,7 @@
//// tab | Python 3.10+
```Python hl_lines="8-9"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -42,7 +42,7 @@
//// tab | Python 3.9+
```Python hl_lines="8-11"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -50,35 +50,35 @@
//// tab | Python 3.8+
```Python hl_lines="9-12"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="6-7"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="8-11"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -101,7 +101,7 @@
그 후 위의 값을 포함한 `dict` 자료형으로 반환할 뿐입니다.
-/// info | "정보"
+/// info | 정보
FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를 사용하기 권장합니다) 추가했습니다.
@@ -116,7 +116,7 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -124,7 +124,7 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -132,35 +132,35 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="1"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -172,7 +172,7 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
//// tab | Python 3.10+
```Python hl_lines="13 18"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -180,7 +180,7 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
//// tab | Python 3.9+
```Python hl_lines="15 20"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -188,35 +188,35 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
//// tab | Python 3.8+
```Python hl_lines="16 21"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="11 16"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ Annotated가 없는 경우
-/// tip | "팁"
+/// tip | 팁
가능하다면 `Annotated`가 달린 버전을 권장합니다.
///
```Python hl_lines="15 20"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -231,7 +231,7 @@ FastAPI는 0.95.0 버전부터 `Annotated`에 대한 지원을 (그리고 이를
그리고 그 함수는 *경로 작동 함수*가 작동하는 것과 같은 방식으로 매개변수를 받습니다.
-/// tip | "팁"
+/// tip | 팁
여러분은 다음 장에서 함수를 제외하고서, "다른 것들"이 어떻게 의존성으로 사용되는지 알게 될 것입니다.
@@ -256,7 +256,7 @@ common_parameters --> read_users
이렇게 하면 공용 코드를 한번만 적어도 되며, **FastAPI**는 *경로 작동*을 위해 이에 대한 호출을 처리합니다.
-/// check | "확인"
+/// check | 확인
특별한 클래스를 만들지 않아도 되며, 이러한 것 혹은 비슷한 종류를 **FastAPI**에 "등록"하기 위해 어떤 곳에 넘겨주지 않아도 됩니다.
@@ -279,7 +279,7 @@ commons: Annotated[dict, Depends(common_parameters)]
//// tab | Python 3.10+
```Python hl_lines="12 16 21"
-{!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_02_an_py310.py!}
```
////
@@ -287,7 +287,7 @@ commons: Annotated[dict, Depends(common_parameters)]
//// tab | Python 3.9+
```Python hl_lines="14 18 23"
-{!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_02_an_py39.py!}
```
////
@@ -295,12 +295,12 @@ commons: Annotated[dict, Depends(common_parameters)]
//// tab | Python 3.8+
```Python hl_lines="15 19 24"
-{!> ../../../docs_src/dependencies/tutorial001_02_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_02_an.py!}
```
////
-/// tip | "팁"
+/// tip | 팁
이는 그저 표준 파이썬이고 "type alias"라고 부르며 사실 **FastAPI**에 국한되는 것은 아닙니다.
@@ -322,7 +322,7 @@ commons: Annotated[dict, Depends(common_parameters)]
아무 문제 없습니다. **FastAPI**는 무엇을 할지 알고 있습니다.
-/// note | "참고"
+/// note | 참고
잘 모르시겠다면, [Async: *"In a hurry?"*](../../async.md){.internal-link target=_blank} 문서에서 `async`와 `await`에 대해 확인할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/encoder.md b/docs/ko/docs/tutorial/encoder.md
index b8e87449c..52277f258 100644
--- a/docs/ko/docs/tutorial/encoder.md
+++ b/docs/ko/docs/tutorial/encoder.md
@@ -21,7 +21,7 @@ JSON 호환 가능 데이터만 수신하는 `fake_db` 데이터베이스가 존
Pydantic 모델과 같은 객체를 받고 JSON 호환 가능한 버전으로 반환합니다:
```Python hl_lines="5 22"
-{!../../../docs_src/encoder/tutorial001.py!}
+{!../../docs_src/encoder/tutorial001.py!}
```
이 예시는 Pydantic 모델을 `dict`로, `datetime` 형식을 `str`로 변환합니다.
@@ -30,7 +30,7 @@ Pydantic 모델과 같은 객체를 받고 JSON 호환 가능한 버전으로
길이가 긴 문자열 형태의 JSON 형식(문자열)의 데이터가 들어있는 상황에서는 `str`로 반환하지 않습니다. JSON과 모두 호환되는 값과 하위 값이 있는 Python 표준 데이터 구조 (예: `dict`)를 반환합니다.
-/// note | "참고"
+/// note | 참고
실제로 `jsonable_encoder`는 **FastAPI** 에서 내부적으로 데이터를 변환하는 데 사용하지만, 다른 많은 곳에서도 이는 유용합니다.
diff --git a/docs/ko/docs/tutorial/extra-data-types.md b/docs/ko/docs/tutorial/extra-data-types.md
index df3c7a06e..8baaa64fc 100644
--- a/docs/ko/docs/tutorial/extra-data-types.md
+++ b/docs/ko/docs/tutorial/extra-data-types.md
@@ -58,7 +58,7 @@
//// tab | Python 3.10+
```Python hl_lines="1 3 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py310.py!}
```
////
@@ -66,7 +66,7 @@
//// tab | Python 3.9+
```Python hl_lines="1 3 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py39.py!}
```
////
@@ -74,7 +74,7 @@
//// tab | Python 3.8+
```Python hl_lines="1 3 13-17"
-{!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an.py!}
```
////
@@ -88,7 +88,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="1 2 11-15"
-{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
```
////
@@ -102,7 +102,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="1 2 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001.py!}
+{!> ../../docs_src/extra_data_types/tutorial001.py!}
```
////
@@ -112,7 +112,7 @@ Prefer to use the `Annotated` version if possible.
//// tab | Python 3.10+
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py310.py!}
```
////
@@ -120,7 +120,7 @@ Prefer to use the `Annotated` version if possible.
//// tab | Python 3.9+
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py39.py!}
```
////
@@ -128,7 +128,7 @@ Prefer to use the `Annotated` version if possible.
//// tab | Python 3.8+
```Python hl_lines="19-20"
-{!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an.py!}
```
////
@@ -142,7 +142,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="17-18"
-{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
```
////
@@ -156,7 +156,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001.py!}
+{!> ../../docs_src/extra_data_types/tutorial001.py!}
```
////
diff --git a/docs/ko/docs/tutorial/first-steps.md b/docs/ko/docs/tutorial/first-steps.md
index 52e53fd89..4a689b74a 100644
--- a/docs/ko/docs/tutorial/first-steps.md
+++ b/docs/ko/docs/tutorial/first-steps.md
@@ -3,7 +3,7 @@
가장 단순한 FastAPI 파일은 다음과 같이 보일 것입니다:
```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
위 코드를 `main.py`에 복사합니다.
@@ -24,7 +24,7 @@ $ uvicorn main:app --reload
-/// note | "참고"
+/// note | 참고
`uvicorn main:app` 명령은 다음을 의미합니다:
@@ -134,12 +134,12 @@ API와 통신하는 클라이언트(프론트엔드, 모바일, IoT 애플리케
### 1 단계: `FastAPI` 임포트
```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI`는 당신의 API를 위한 모든 기능을 제공하는 파이썬 클래스입니다.
-/// note | "기술 세부사항"
+/// note | 기술 세부사항
`FastAPI`는 `Starlette`를 직접 상속하는 클래스입니다.
@@ -150,7 +150,7 @@ API와 통신하는 클라이언트(프론트엔드, 모바일, IoT 애플리케
### 2 단계: `FastAPI` "인스턴스" 생성
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
여기에서 `app` 변수는 `FastAPI` 클래스의 "인스턴스"가 됩니다.
@@ -172,7 +172,7 @@ $ uvicorn main:app --reload
아래처럼 앱을 만든다면:
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial002.py!}
+{!../../docs_src/first_steps/tutorial002.py!}
```
이를 `main.py` 파일에 넣고, `uvicorn`을 아래처럼 호출해야 합니다:
@@ -205,7 +205,7 @@ https://example.com/items/foo
/items/foo
```
-/// info | "정보"
+/// info | 정보
"경로"는 일반적으로 "엔드포인트" 또는 "라우트"라고도 불립니다.
@@ -251,7 +251,7 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
#### *경로 작동 데코레이터* 정의
```Python hl_lines="6"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`@app.get("/")`은 **FastAPI**에게 바로 아래에 있는 함수가 다음으로 이동하는 요청을 처리한다는 것을 알려줍니다.
@@ -259,7 +259,7 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
* 경로 `/`
* get 작동 사용
-/// info | "`@decorator` 정보"
+/// info | `@decorator` 정보
이 `@something` 문법은 파이썬에서 "데코레이터"라 부릅니다.
@@ -286,7 +286,7 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
* `@app.patch()`
* `@app.trace()`
-/// tip | "팁"
+/// tip | 팁
각 작동(HTTP 메소드)을 원하는 대로 사용해도 됩니다.
@@ -307,7 +307,7 @@ API를 설계할 때 일반적으로 특정 행동을 수행하기 위해 특정
* **함수**: 는 "데코레이터" 아래에 있는 함수입니다 (`@app.get("/")` 아래).
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
이것은 파이썬 함수입니다.
@@ -321,10 +321,10 @@ URL "`/`"에 대한 `GET` 작동을 사용하는 요청을 받을 때마다 **Fa
`async def`을 이용하는 대신 일반 함수로 정의할 수 있습니다:
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
+{!../../docs_src/first_steps/tutorial003.py!}
```
-/// note | "참고"
+/// note | 참고
차이점을 모르겠다면 [Async: *"바쁘신 경우"*](../async.md#_1){.internal-link target=_blank}을 확인하세요.
@@ -333,7 +333,7 @@ URL "`/`"에 대한 `GET` 작동을 사용하는 요청을 받을 때마다 **Fa
### 5 단계: 콘텐츠 반환
```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`dict`, `list`, 단일값을 가진 `str`, `int` 등을 반환할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/header-params.md b/docs/ko/docs/tutorial/header-params.md
index d403b9175..972f52a33 100644
--- a/docs/ko/docs/tutorial/header-params.md
+++ b/docs/ko/docs/tutorial/header-params.md
@@ -7,7 +7,7 @@
먼저 `Header`를 임포트합니다:
```Python hl_lines="3"
-{!../../../docs_src/header_params/tutorial001.py!}
+{!../../docs_src/header_params/tutorial001.py!}
```
## `Header` 매개변수 선언
@@ -17,10 +17,10 @@
첫 번째 값은 기본값이며, 추가 검증이나 어노테이션 매개변수 모두 전달할 수 있습니다:
```Python hl_lines="9"
-{!../../../docs_src/header_params/tutorial001.py!}
+{!../../docs_src/header_params/tutorial001.py!}
```
-/// note | "기술 세부사항"
+/// note | 기술 세부사항
`Header`는 `Path`, `Query` 및 `Cookie`의 "자매"클래스입니다. 이 역시 동일한 공통 `Param` 클래스를 상속합니다.
@@ -28,7 +28,7 @@
///
-/// info | "정보"
+/// info | 정보
헤더를 선언하기 위해서 `Header`를 사용해야 합니다. 그렇지 않으면 해당 매개변수를 쿼리 매개변수로 해석하기 때문입니다.
@@ -51,10 +51,10 @@
만약 언더스코어를 하이픈으로 자동 변환을 비활성화해야 할 어떤 이유가 있다면, `Header`의 `convert_underscores` 매개변수를 `False`로 설정하십시오:
```Python hl_lines="10"
-{!../../../docs_src/header_params/tutorial002.py!}
+{!../../docs_src/header_params/tutorial002.py!}
```
-/// warning | "경고"
+/// warning | 경고
`convert_underscore`를 `False`로 설정하기 전에, 어떤 HTTP 프록시들과 서버들은 언더스코어가 포함된 헤더 사용을 허락하지 않는다는 것을 명심하십시오.
@@ -71,7 +71,7 @@
예를 들어, 두 번 이상 나타날 수 있는 `X-Token`헤더를 선언하려면, 다음과 같이 작성합니다:
```Python hl_lines="9"
-{!../../../docs_src/header_params/tutorial003.py!}
+{!../../docs_src/header_params/tutorial003.py!}
```
다음과 같은 두 개의 HTTP 헤더를 전송하여 해당 *경로* 와 통신할 경우:
diff --git a/docs/ko/docs/tutorial/index.md b/docs/ko/docs/tutorial/index.md
index d00a942f0..9f5328992 100644
--- a/docs/ko/docs/tutorial/index.md
+++ b/docs/ko/docs/tutorial/index.md
@@ -30,7 +30,7 @@ $ uvicorn main:app --reload
코드를 작성하거나 복사, 편집할 때, 로컬 환경에서 실행하는 것을 **강력히 권장**합니다.
-로컬 편집기에서 사용한다면, 모든 타입 검사와 자동완성 등 작성해야 하는 코드가 얼마나 적은지 보면서 FastAPI의 비로소 경험할 수 있습니다.
+로컬 편집기에서 사용한다면, 모든 타입 검사와 자동완성 등 작성해야 하는 코드가 얼마나 적은지 보면서 FastAPI의 이점을 비로소 경험할 수 있습니다.
---
@@ -53,7 +53,7 @@ $ pip install "fastapi[all]"
...이는 코드를 실행하는 서버로 사용할 수 있는 `uvicorn` 또한 포함하고 있습니다.
-/// note | "참고"
+/// note | 참고
부분적으로 설치할 수도 있습니다.
diff --git a/docs/ko/docs/tutorial/metadata.md b/docs/ko/docs/tutorial/metadata.md
new file mode 100644
index 000000000..87531152c
--- /dev/null
+++ b/docs/ko/docs/tutorial/metadata.md
@@ -0,0 +1,131 @@
+
+# 메타데이터 및 문서화 URL
+
+**FastAPI** 응용 프로그램에서 다양한 메타데이터 구성을 사용자 맞춤 설정할 수 있습니다.
+
+## API에 대한 메타데이터
+
+OpenAPI 명세 및 자동화된 API 문서 UI에 사용되는 다음 필드를 설정할 수 있습니다:
+
+| 매개변수 | 타입 | 설명 |
+|----------|------|-------|
+| `title` | `str` | API의 제목입니다. |
+| `summary` | `str` | API에 대한 짧은 요약입니다. OpenAPI 3.1.0, FastAPI 0.99.0부터 사용 가능 |
+| `description` | `str` | API에 대한 짧은 설명입니다. 마크다운을 사용할 수 있습니다. |
+| `version` | `string` | API의 버전입니다. OpenAPI의 버전이 아닌, 여러분의 애플리케이션의 버전을 나타냅니다. 예: `2.5.0` |
+| `terms_of_service` | `str` | API 이용 약관의 URL입니다. 제공하는 경우 URL 형식이어야 합니다. |
+| `contact` | `dict` | 노출된 API에 대한 연락처 정보입니다. 여러 필드를 포함할 수 있습니다. contact 필드| 매개변수 | 타입 | 설명 |
|---|---|---|
name | str | 연락처 인물/조직의 식별명입니다. |
url | str | 연락처 정보가 담긴 URL입니다. URL 형식이어야 합니다. |
email | str | 연락처 인물/조직의 이메일 주소입니다. 이메일 주소 형식이어야 합니다. |
license_info 필드| 매개변수 | 타입 | 설명 |
|---|---|---|
name | str | 필수 (license_info가 설정된 경우). API에 사용된 라이선스 이름입니다. |
identifier | str | API에 대한 SPDX 라이선스 표현입니다. identifier 필드는 url 필드와 상호 배타적입니다. OpenAPI 3.1.0, FastAPI 0.99.0부터 사용 가능 |
url | str | API에 사용된 라이선스의 URL입니다. URL 형식이어야 합니다. |
+
+## 라이선스 식별자
+
+OpenAPI 3.1.0 및 FastAPI 0.99.0부터 `license_info`에 `identifier`를 URL 대신 설정할 수 있습니다.
+
+예:
+
+```Python hl_lines="31"
+{!../../docs_src/metadata/tutorial001_1.py!}
+```
+
+## 태그에 대한 메타데이터
+
+`openapi_tags` 매개변수를 사용하여 경로 작동을 그룹화하는 데 사용되는 태그에 추가 메타데이터를 추가할 수 있습니다.
+
+리스트는 각 태그에 대해 하나의 딕셔너리를 포함해야 합니다.
+
+각 딕셔너리에는 다음이 포함될 수 있습니다:
+
+* `name` (**필수**): `tags` 매개변수에서 *경로 작동*과 `APIRouter`에 사용된 태그 이름과 동일한 `str`입니다.
+* `description`: 태그에 대한 간단한 설명을 담은 `str`입니다. 마크다운을 사용할 수 있으며 문서 UI에 표시됩니다.
+* `externalDocs`: 외부 문서를 설명하는 `dict`이며:
+ * `description`: 외부 문서에 대한 간단한 설명을 담은 `str`입니다.
+ * `url` (**필수**): 외부 문서의 URL을 담은 `str`입니다.
+
+### 태그에 대한 메타데이터 생성
+
+`users` 및 `items`에 대한 태그 예시와 함께 메타데이터를 생성하고 이를 `openapi_tags` 매개변수로 전달해 보겠습니다:
+
+```Python hl_lines="3-16 18"
+{!../../docs_src/metadata/tutorial004.py!}
+```
+
+설명 안에 마크다운을 사용할 수 있습니다. 예를 들어 "login"은 굵게(**login**) 표시되고, "fancy"는 기울임꼴(_fancy_)로 표시됩니다.
+
+/// tip
+
+사용 중인 모든 태그에 메타데이터를 추가할 필요는 없습니다.
+
+///
+
+### 태그 사용
+
+`tags` 매개변수를 *경로 작동* 및 `APIRouter`와 함께 사용하여 태그에 할당할 수 있습니다:
+
+```Python hl_lines="21 26"
+{!../../docs_src/metadata/tutorial004.py!}
+```
+
+/// info
+
+태그에 대한 자세한 내용은 [경로 작동 구성](path-operation-configuration.md#tags){.internal-link target=_blank}에서 읽어보세요.
+
+///
+
+### 문서 확인
+
+이제 문서를 확인하면 모든 추가 메타데이터가 표시됩니다:
+
+
+
+### 태그 순서
+
+각 태그 메타데이터 딕셔너리의 순서는 문서 UI에 표시되는 순서를 정의합니다.
+
+예를 들어, 알파벳 순서상 `users`는 `items` 뒤에 오지만, 우리는 `users` 메타데이터를 리스트의 첫 번째 딕셔너리로 추가했기 때문에 먼저 표시됩니다.
+
+## OpenAPI URL
+
+OpenAPI 구조는 기본적으로 `/openapi.json`에서 제공됩니다.
+
+`openapi_url` 매개변수를 통해 이를 설정할 수 있습니다.
+
+예를 들어, 이를 `/api/v1/openapi.json`에 제공하도록 설정하려면:
+
+```Python hl_lines="3"
+{!../../docs_src/metadata/tutorial002.py!}
+```
+
+OpenAPI 구조를 완전히 비활성화하려면 `openapi_url=None`으로 설정할 수 있으며, 이를 사용하여 문서화 사용자 인터페이스도 비활성화됩니다.
+
+## 문서화 URL
+
+포함된 두 가지 문서화 사용자 인터페이스를 설정할 수 있습니다:
+
+* **Swagger UI**: `/docs`에서 제공됩니다.
+ * `docs_url` 매개변수로 URL을 설정할 수 있습니다.
+ * `docs_url=None`으로 설정하여 비활성화할 수 있습니다.
+* **ReDoc**: `/redoc`에서 제공됩니다.
+ * `redoc_url` 매개변수로 URL을 설정할 수 있습니다.
+ * `redoc_url=None`으로 설정하여 비활성화할 수 있습니다.
+
+예를 들어, Swagger UI를 `/documentation`에서 제공하고 ReDoc을 비활성화하려면:
+
+```Python hl_lines="3"
+{!../../docs_src/metadata/tutorial003.py!}
+```
diff --git a/docs/ko/docs/tutorial/middleware.md b/docs/ko/docs/tutorial/middleware.md
index 84f67bd26..0547066f1 100644
--- a/docs/ko/docs/tutorial/middleware.md
+++ b/docs/ko/docs/tutorial/middleware.md
@@ -11,7 +11,7 @@
* **응답** 또는 다른 필요한 코드를 실행시키는 동작을 할 수 있습니다.
* **응답**를 반환합니다.
-/// note | "기술 세부사항"
+/// note | 기술 세부사항
만약 `yield`를 사용한 의존성을 가지고 있다면, 미들웨어가 실행되고 난 후에 exit이 실행됩니다.
@@ -32,10 +32,10 @@
* `response`를 반환하기 전에 추가로 `response`를 수정할 수 있습니다.
```Python hl_lines="8-9 11 14"
-{!../../../docs_src/middleware/tutorial001.py!}
+{!../../docs_src/middleware/tutorial001.py!}
```
-/// tip | "팁"
+/// tip | 팁
사용자 정의 헤더는 'X-' 접두사를 사용하여 추가할 수 있습니다.
@@ -43,7 +43,7 @@
///
-/// note | "기술적 세부사항"
+/// note | 기술적 세부사항
`from starlette.requests import request`를 사용할 수도 있습니다.
@@ -60,7 +60,7 @@
예를 들어, 요청을 수행하고 응답을 생성하는데 까지 걸린 시간 값을 가지고 있는 `X-Process-Time` 같은 사용자 정의 헤더를 추가할 수 있습니다.
```Python hl_lines="10 12-13"
-{!../../../docs_src/middleware/tutorial001.py!}
+{!../../docs_src/middleware/tutorial001.py!}
```
## 다른 미들웨어
diff --git a/docs/ko/docs/tutorial/path-operation-configuration.md b/docs/ko/docs/tutorial/path-operation-configuration.md
index b6608a14d..75a9c71ce 100644
--- a/docs/ko/docs/tutorial/path-operation-configuration.md
+++ b/docs/ko/docs/tutorial/path-operation-configuration.md
@@ -2,7 +2,7 @@
*경로 작동 데코레이터*를 설정하기 위해서 전달할수 있는 몇 가지 매개변수가 있습니다.
-/// warning | "경고"
+/// warning | 경고
아래 매개변수들은 *경로 작동 함수*가 아닌 *경로 작동 데코레이터*에 직접 전달된다는 사실을 기억하십시오.
@@ -17,12 +17,12 @@
하지만 각 코드의 의미를 모른다면, `status`에 있는 단축 상수들을 사용할수 있습니다:
```Python hl_lines="3 17"
-{!../../../docs_src/path_operation_configuration/tutorial001.py!}
+{!../../docs_src/path_operation_configuration/tutorial001.py!}
```
각 상태 코드들은 응답에 사용되며, OpenAPI 스키마에 추가됩니다.
-/// note | "기술적 세부사항"
+/// note | 기술적 세부사항
다음과 같이 임포트하셔도 좋습니다. `from starlette import status`.
@@ -35,7 +35,7 @@
(보통 단일 `str`인) `str`로 구성된 `list`와 함께 매개변수 `tags`를 전달하여, `경로 작동`에 태그를 추가할 수 있습니다:
```Python hl_lines="17 22 27"
-{!../../../docs_src/path_operation_configuration/tutorial002.py!}
+{!../../docs_src/path_operation_configuration/tutorial002.py!}
```
전달된 태그들은 OpenAPI의 스키마에 추가되며, 자동 문서 인터페이스에서 사용됩니다:
@@ -47,7 +47,7 @@
`summary`와 `description`을 추가할 수 있습니다:
```Python hl_lines="20-21"
-{!../../../docs_src/path_operation_configuration/tutorial003.py!}
+{!../../docs_src/path_operation_configuration/tutorial003.py!}
```
## 독스트링으로 만든 기술
@@ -57,7 +57,7 @@
마크다운 문법으로 독스트링을 작성할 수 있습니다, 작성된 마크다운 형식의 독스트링은 (마크다운의 들여쓰기를 고려하여) 올바르게 화면에 출력됩니다.
```Python hl_lines="19-27"
-{!../../../docs_src/path_operation_configuration/tutorial004.py!}
+{!../../docs_src/path_operation_configuration/tutorial004.py!}
```
이는 대화형 문서에서 사용됩니다:
@@ -69,16 +69,16 @@
`response_description` 매개변수로 응답에 관한 설명을 명시할 수 있습니다:
```Python hl_lines="21"
-{!../../../docs_src/path_operation_configuration/tutorial005.py!}
+{!../../docs_src/path_operation_configuration/tutorial005.py!}
```
-/// info | "정보"
+/// info | 정보
`response_description`은 구체적으로 응답을 지칭하며, `description`은 일반적인 *경로 작동*을 지칭합니다.
///
-/// check | "확인"
+/// check | 확인
OpenAPI는 각 *경로 작동*이 응답에 관한 설명을 요구할 것을 명시합니다.
@@ -93,7 +93,7 @@ OpenAPI는 각 *경로 작동*이 응답에 관한 설명을 요구할 것을
단일 *경로 작동*을 없애지 않고 지원중단을 해야한다면, `deprecated` 매개변수를 전달하면 됩니다.
```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_configuration/tutorial006.py!}
```
대화형 문서에 지원중단이라고 표시됩니다.
diff --git a/docs/ko/docs/tutorial/path-params-numeric-validations.md b/docs/ko/docs/tutorial/path-params-numeric-validations.md
index 6d3215c24..736f2dc1d 100644
--- a/docs/ko/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/ko/docs/tutorial/path-params-numeric-validations.md
@@ -7,7 +7,7 @@
먼저 `fastapi`에서 `Path`를 임포트합니다:
```Python hl_lines="3"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
## 메타데이터 선언
@@ -17,10 +17,10 @@
예를 들어, `title` 메타데이터 값을 경로 매개변수 `item_id`에 선언하려면 다음과 같이 입력할 수 있습니다:
```Python hl_lines="10"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
-/// note | "참고"
+/// note | 참고
경로 매개변수는 경로의 일부여야 하므로 언제나 필수적입니다.
@@ -47,7 +47,7 @@
따라서 함수를 다음과 같이 선언 할 수 있습니다:
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
## 필요한 경우 매개변수 정렬하기, 트릭
@@ -59,7 +59,7 @@
파이썬은 `*`으로 아무런 행동도 하지 않지만, 따르는 매개변수들은 kwargs로도 알려진 키워드 인자(키-값 쌍)여야 함을 인지합니다. 기본값을 가지고 있지 않더라도 그렇습니다.
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
## 숫자 검증: 크거나 같음
@@ -69,7 +69,7 @@
여기서 `ge=1`인 경우, `item_id`는 `1`보다 "크거나(`g`reater) 같은(`e`qual)" 정수형 숫자여야 합니다.
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
## 숫자 검증: 크거나 같음 및 작거나 같음
@@ -80,7 +80,7 @@
* `le`: 작거나 같은(`l`ess than or `e`qual)
```Python hl_lines="9"
-{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
## 숫자 검증: 부동소수, 크거나 및 작거나
@@ -94,7 +94,7 @@
lt 역시 마찬가지입니다.
```Python hl_lines="11"
-{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
## 요약
@@ -108,7 +108,7 @@
* `lt`: 작거나(`l`ess `t`han)
* `le`: 작거나 같은(`l`ess than or `e`qual)
-/// info | "정보"
+/// info | 정보
`Query`, `Path`, 그리고 나중에게 보게될 것들은 (여러분이 사용할 필요가 없는) 공통 `Param` 클래스의 서브 클래스입니다.
@@ -116,7 +116,7 @@
///
-/// note | "기술 세부사항"
+/// note | 기술 세부사항
`fastapi`에서 `Query`, `Path` 등을 임포트 할 때, 이것들은 실제로 함수입니다.
diff --git a/docs/ko/docs/tutorial/path-params.md b/docs/ko/docs/tutorial/path-params.md
index 67a2d899d..21808e2ca 100644
--- a/docs/ko/docs/tutorial/path-params.md
+++ b/docs/ko/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
파이썬의 포맷 문자열 리터럴에서 사용되는 문법을 이용하여 경로 "매개변수" 또는 "변수"를 선언할 수 있습니다:
```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
경로 매개변수 `item_id`의 값은 함수의 `item_id` 인자로 전달됩니다.
@@ -19,12 +19,12 @@
파이썬 표준 타입 어노테이션을 사용하여 함수에 있는 경로 매개변수의 타입을 선언할 수 있습니다:
```Python hl_lines="7"
-{!../../../docs_src/path_params/tutorial002.py!}
+{!../../docs_src/path_params/tutorial002.py!}
```
위의 예시에서, `item_id`는 `int`로 선언되었습니다.
-/// check | "확인"
+/// check | 확인
이 기능은 함수 내에서 오류 검사, 자동완성 등의 편집기 기능을 활용할 수 있게 해줍니다.
@@ -38,7 +38,7 @@
{"item_id":3}
```
-/// check | "확인"
+/// check | 확인
함수가 받은(반환도 하는) 값은 문자열 `"3"`이 아니라 파이썬 `int` 형인 `3`입니다.
@@ -69,7 +69,7 @@
`int`가 아닌 `float`을 전달하는 경우에도 동일한 오류가 나타납니다: http://127.0.0.1:8000/items/4.2
-/// check | "확인"
+/// check | 확인
즉, 파이썬 타입 선언을 하면 **FastAPI**는 데이터 검증을 합니다.
@@ -85,7 +85,7 @@
-/// check | "확인"
+/// check | 확인
그저 파이썬 타입 선언을 하기만 하면 **FastAPI**는 자동 대화형 API 문서(Swagger UI)를 제공합니다.
@@ -122,7 +122,7 @@
*경로 작동*은 순차적으로 실행되기 때문에 `/users/{user_id}` 이전에 `/users/me`를 먼저 선언해야 합니다:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
+{!../../docs_src/path_params/tutorial003.py!}
```
그렇지 않으면 `/users/{user_id}`는 `/users/me` 요청 또한 매개변수 `user_id`의 값이 `"me"`인 것으로 "생각하게" 됩니다.
@@ -140,16 +140,16 @@
가능한 값들에 해당하는 고정된 값의 클래스 어트리뷰트들을 만듭니다:
```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// info | "정보"
+/// info | 정보
열거형(또는 enums)은 파이썬 버전 3.4 이후로 사용 가능합니다.
///
-/// tip | "팁"
+/// tip | 팁
혹시 궁금하다면, "AlexNet", "ResNet", 그리고 "LeNet"은 그저 기계 학습 모델들의 이름입니다.
@@ -160,7 +160,7 @@
생성한 열거형 클래스(`ModelName`)를 사용하는 타입 어노테이션으로 *경로 매개변수*를 만듭니다:
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### 문서 확인
@@ -178,7 +178,7 @@
열거형 `ModelName`의 *열거형 멤버*를 비교할 수 있습니다:
```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
#### *열거형 값* 가져오기
@@ -186,10 +186,10 @@
`model_name.value` 또는 일반적으로 `your_enum_member.value`를 이용하여 실제 값(위 예시의 경우 `str`)을 가져올 수 있습니다:
```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// tip | "팁"
+/// tip | 팁
`ModelName.lenet.value`로도 값 `"lenet"`에 접근할 수 있습니다.
@@ -202,7 +202,7 @@
클라이언트에 반환하기 전에 해당 값(이 경우 문자열)으로 변환됩니다:
```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
클라이언트는 아래의 JSON 응답을 얻습니다:
@@ -243,10 +243,10 @@ Starlette의 옵션을 직접 이용하여 다음과 같은 URL을 사용함으
따라서 다음과 같이 사용할 수 있습니다:
```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
+{!../../docs_src/path_params/tutorial004.py!}
```
-/// tip | "팁"
+/// tip | 팁
매개변수가 가져야 하는 값이 `/home/johndoe/myfile.txt`와 같이 슬래시로 시작(`/`)해야 할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/query-params-str-validations.md b/docs/ko/docs/tutorial/query-params-str-validations.md
index 11193950b..71f884e83 100644
--- a/docs/ko/docs/tutorial/query-params-str-validations.md
+++ b/docs/ko/docs/tutorial/query-params-str-validations.md
@@ -5,12 +5,12 @@
이 응용 프로그램을 예로 들어보겠습니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial001.py!}
+{!../../docs_src/query_params_str_validations/tutorial001.py!}
```
쿼리 매개변수 `q`는 `Optional[str]` 자료형입니다. 즉, `str` 자료형이지만 `None` 역시 될 수 있음을 뜻하고, 실제로 기본값은 `None`이기 때문에 FastAPI는 이 매개변수가 필수가 아니라는 것을 압니다.
-/// note | "참고"
+/// note | 참고
FastAPI는 `q`의 기본값이 `= None`이기 때문에 필수가 아님을 압니다.
@@ -27,7 +27,7 @@ FastAPI는 `q`의 기본값이 `= None`이기 때문에 필수가 아님을 압
이를 위해 먼저 `fastapi`에서 `Query`를 임포트합니다:
```Python hl_lines="3"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!../../docs_src/query_params_str_validations/tutorial002.py!}
```
## 기본값으로 `Query` 사용
@@ -35,7 +35,7 @@ FastAPI는 `q`의 기본값이 `= None`이기 때문에 필수가 아님을 압
이제 `Query`를 매개변수의 기본값으로 사용하여 `max_length` 매개변수를 50으로 설정합니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!../../docs_src/query_params_str_validations/tutorial002.py!}
```
기본값 `None`을 `Query(None)`으로 바꿔야 하므로, `Query`의 첫 번째 매개변수는 기본값을 정의하는 것과 같은 목적으로 사용됩니다.
@@ -54,7 +54,7 @@ q: Optional[str] = None
하지만 명시적으로 쿼리 매개변수를 선언합니다.
-/// info | "정보"
+/// info | 정보
FastAPI는 다음 부분에 관심이 있습니다:
@@ -87,7 +87,7 @@ q: str = Query(None, max_length=50)
매개변수 `min_length` 또한 추가할 수 있습니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial003.py!}
+{!../../docs_src/query_params_str_validations/tutorial003.py!}
```
## 정규식 추가
@@ -95,7 +95,7 @@ q: str = Query(None, max_length=50)
매개변수와 일치해야 하는 정규표현식을 정의할 수 있습니다:
```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial004.py!}
+{!../../docs_src/query_params_str_validations/tutorial004.py!}
```
이 특정 정규표현식은 전달 받은 매개변수 값을 검사합니다:
@@ -115,10 +115,10 @@ q: str = Query(None, max_length=50)
`min_length`가 `3`이고, 기본값이 `"fixedquery"`인 쿼리 매개변수 `q`를 선언해봅시다:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial005.py!}
+{!../../docs_src/query_params_str_validations/tutorial005.py!}
```
-/// note | "참고"
+/// note | 참고
기본값을 갖는 것만으로 매개변수는 선택적이 됩니다.
@@ -147,10 +147,10 @@ q: Optional[str] = Query(None, min_length=3)
그래서 `Query`를 필수값으로 만들어야 할 때면, 첫 번째 인자로 `...`를 사용할 수 있습니다:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial006.py!}
+{!../../docs_src/query_params_str_validations/tutorial006.py!}
```
-/// info | "정보"
+/// info | 정보
이전에 `...`를 본적이 없다면: 특별한 단일값으로, 파이썬의 일부이며 "Ellipsis"라 부릅니다.
@@ -165,7 +165,7 @@ q: Optional[str] = Query(None, min_length=3)
예를 들어, URL에서 여러번 나오는 `q` 쿼리 매개변수를 선언하려면 다음과 같이 작성할 수 있습니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial011.py!}
+{!../../docs_src/query_params_str_validations/tutorial011.py!}
```
아래와 같은 URL을 사용합니다:
@@ -187,7 +187,7 @@ http://localhost:8000/items/?q=foo&q=bar
}
```
-/// tip | "팁"
+/// tip | 팁
위의 예와 같이 `list` 자료형으로 쿼리 매개변수를 선언하려면 `Query`를 명시적으로 사용해야 합니다. 그렇지 않으면 요청 본문으로 해석됩니다.
@@ -202,7 +202,7 @@ http://localhost:8000/items/?q=foo&q=bar
그리고 제공된 값이 없으면 기본 `list` 값을 정의할 수도 있습니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial012.py!}
+{!../../docs_src/query_params_str_validations/tutorial012.py!}
```
아래로 이동한다면:
@@ -227,10 +227,10 @@ http://localhost:8000/items/
`List[str]` 대신 `list`를 직접 사용할 수도 있습니다:
```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial013.py!}
+{!../../docs_src/query_params_str_validations/tutorial013.py!}
```
-/// note | "참고"
+/// note | 참고
이 경우 FastAPI는 리스트의 내용을 검사하지 않음을 명심하기 바랍니다.
@@ -244,7 +244,7 @@ http://localhost:8000/items/
해당 정보는 생성된 OpenAPI에 포함되고 문서 사용자 인터페이스 및 외부 도구에서 사용됩니다.
-/// note | "참고"
+/// note | 참고
도구에 따라 OpenAPI 지원 수준이 다를 수 있음을 명심하기 바랍니다.
@@ -255,13 +255,13 @@ http://localhost:8000/items/
`title`을 추가할 수 있습니다:
```Python hl_lines="10"
-{!../../../docs_src/query_params_str_validations/tutorial007.py!}
+{!../../docs_src/query_params_str_validations/tutorial007.py!}
```
그리고 `description`도 추가할 수 있습니다:
```Python hl_lines="13"
-{!../../../docs_src/query_params_str_validations/tutorial008.py!}
+{!../../docs_src/query_params_str_validations/tutorial008.py!}
```
## 별칭 매개변수
@@ -283,7 +283,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
이럴 경우 `alias`를 선언할 수 있으며, 해당 별칭은 매개변수 값을 찾는 데 사용됩니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params_str_validations/tutorial009.py!}
+{!../../docs_src/query_params_str_validations/tutorial009.py!}
```
## 매개변수 사용하지 않게 하기
@@ -295,7 +295,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
그렇다면 `deprecated=True` 매개변수를 `Query`로 전달합니다:
```Python hl_lines="18"
-{!../../../docs_src/query_params_str_validations/tutorial010.py!}
+{!../../docs_src/query_params_str_validations/tutorial010.py!}
```
문서가 아래와 같이 보일겁니다:
diff --git a/docs/ko/docs/tutorial/query-params.md b/docs/ko/docs/tutorial/query-params.md
index e71444c18..7fa3e8c53 100644
--- a/docs/ko/docs/tutorial/query-params.md
+++ b/docs/ko/docs/tutorial/query-params.md
@@ -3,7 +3,7 @@
경로 매개변수의 일부가 아닌 다른 함수 매개변수를 선언하면 "쿼리" 매개변수로 자동 해석합니다.
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
+{!../../docs_src/query_params/tutorial001.py!}
```
쿼리는 URL에서 `?` 후에 나오고 `&`으로 구분되는 키-값 쌍의 집합입니다.
@@ -64,18 +64,18 @@ http://127.0.0.1:8000/items/?skip=20
같은 방법으로 기본값을 `None`으로 설정하여 선택적 매개변수를 선언할 수 있습니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial002.py!}
+{!../../docs_src/query_params/tutorial002.py!}
```
이 경우 함수 매개변수 `q`는 선택적이며 기본값으로 `None` 값이 됩니다.
-/// check | "확인"
+/// check | 확인
**FastAPI**는 `item_id`가 경로 매개변수이고 `q`는 경로 매개변수가 아닌 쿼리 매개변수라는 것을 알 정도로 충분히 똑똑합니다.
///
-/// note | "참고"
+/// note | 참고
FastAPI는 `q`가 `= None`이므로 선택적이라는 것을 인지합니다.
@@ -88,7 +88,7 @@ FastAPI는 `q`가 `= None`이므로 선택적이라는 것을 인지합니다.
`bool` 형으로 선언할 수도 있고, 아래처럼 변환됩니다:
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial003.py!}
+{!../../docs_src/query_params/tutorial003.py!}
```
이 경우, 아래로 이동하면:
@@ -133,7 +133,7 @@ http://127.0.0.1:8000/items/foo?short=yes
매개변수들은 이름으로 감지됩니다:
```Python hl_lines="8 10"
-{!../../../docs_src/query_params/tutorial004.py!}
+{!../../docs_src/query_params/tutorial004.py!}
```
## 필수 쿼리 매개변수
@@ -145,7 +145,7 @@ http://127.0.0.1:8000/items/foo?short=yes
그러나 쿼리 매개변수를 필수로 만들려면 단순히 기본값을 선언하지 않으면 됩니다:
```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
+{!../../docs_src/query_params/tutorial005.py!}
```
여기 쿼리 매개변수 `needy`는 `str`형인 필수 쿼리 매개변수입니다.
@@ -191,7 +191,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
그리고 물론, 일부 매개변수는 필수로, 다른 일부는 기본값을, 또 다른 일부는 선택적으로 선언할 수 있습니다:
```Python hl_lines="10"
-{!../../../docs_src/query_params/tutorial006.py!}
+{!../../docs_src/query_params/tutorial006.py!}
```
위 예시에서는 3가지 쿼리 매개변수가 있습니다:
@@ -200,7 +200,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
* `skip`, 기본값이 `0`인 `int`.
* `limit`, 선택적인 `int`.
-/// tip | "팁"
+/// tip | 팁
[경로 매개변수](path-params.md#_8){.internal-link target=_blank}와 마찬가지로 `Enum`을 사용할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/request-files.md b/docs/ko/docs/tutorial/request-files.md
index b7781ef5e..ca0f43978 100644
--- a/docs/ko/docs/tutorial/request-files.md
+++ b/docs/ko/docs/tutorial/request-files.md
@@ -2,7 +2,7 @@
`File`을 사용하여 클라이언트가 업로드할 파일들을 정의할 수 있습니다.
-/// info | "정보"
+/// info | 정보
업로드된 파일을 전달받기 위해 먼저 `python-multipart`를 설치해야합니다.
@@ -17,7 +17,7 @@
`fastapi` 에서 `File` 과 `UploadFile` 을 임포트 합니다:
```Python hl_lines="1"
-{!../../../docs_src/request_files/tutorial001.py!}
+{!../../docs_src/request_files/tutorial001.py!}
```
## `File` 매개변수 정의
@@ -25,10 +25,10 @@
`Body` 및 `Form` 과 동일한 방식으로 파일의 매개변수를 생성합니다:
```Python hl_lines="7"
-{!../../../docs_src/request_files/tutorial001.py!}
+{!../../docs_src/request_files/tutorial001.py!}
```
-/// info | "정보"
+/// info | 정보
`File` 은 `Form` 으로부터 직접 상속된 클래스입니다.
@@ -36,7 +36,7 @@
///
-/// tip | "팁"
+/// tip | 팁
File의 본문을 선언할 때, 매개변수가 쿼리 매개변수 또는 본문(JSON) 매개변수로 해석되는 것을 방지하기 위해 `File` 을 사용해야합니다.
@@ -55,7 +55,7 @@ File의 본문을 선언할 때, 매개변수가 쿼리 매개변수 또는 본
`File` 매개변수를 `UploadFile` 타입으로 정의합니다:
```Python hl_lines="12"
-{!../../../docs_src/request_files/tutorial001.py!}
+{!../../docs_src/request_files/tutorial001.py!}
```
`UploadFile` 을 사용하는 것은 `bytes` 과 비교해 다음과 같은 장점이 있습니다:
@@ -104,7 +104,7 @@ contents = myfile.file.read()
///
-/// note | "Starlette 기술적 세부사항"
+/// note | Starlette 기술적 세부사항
**FastAPI**의 `UploadFile` 은 **Starlette**의 `UploadFile` 을 직접적으로 상속받지만, **Pydantic** 및 FastAPI의 다른 부분들과의 호환성을 위해 필요한 부분들이 추가되었습니다.
@@ -116,7 +116,7 @@ HTML의 폼들(``)이 서버에 데이터를 전송하는 방식은
**FastAPI**는 JSON 대신 올바른 위치에서 데이터를 읽을 수 있도록 합니다.
-/// note | "기술적 세부사항"
+/// note | 기술적 세부사항
폼의 데이터는 파일이 포함되지 않은 경우 일반적으로 "미디어 유형" `application/x-www-form-urlencoded` 을 사용해 인코딩 됩니다.
@@ -126,7 +126,7 @@ HTML의 폼들(``)이 서버에 데이터를 전송하는 방식은
///
-/// warning | "경고"
+/// warning | 경고
다수의 `File` 과 `Form` 매개변수를 한 *경로 작동*에 선언하는 것이 가능하지만, 요청의 본문이 `application/json` 가 아닌 `multipart/form-data` 로 인코딩 되기 때문에 JSON으로 받아야하는 `Body` 필드를 함께 선언할 수는 없습니다.
@@ -143,12 +143,12 @@ HTML의 폼들(``)이 서버에 데이터를 전송하는 방식은
이 기능을 사용하기 위해 , `bytes` 의 `List` 또는 `UploadFile` 를 선언하기 바랍니다:
```Python hl_lines="10 15"
-{!../../../docs_src/request_files/tutorial002.py!}
+{!../../docs_src/request_files/tutorial002.py!}
```
선언한대로, `bytes` 의 `list` 또는 `UploadFile` 들을 전송받을 것입니다.
-/// note | "참고"
+/// note | 참고
2019년 4월 14일부터 Swagger UI가 하나의 폼 필드로 다수의 파일을 업로드하는 것을 지원하지 않습니다. 더 많은 정보를 원하면, #4276과 #3641을 참고하세요.
@@ -158,7 +158,7 @@ HTML의 폼들(``)이 서버에 데이터를 전송하는 방식은
///
-/// note | "기술적 세부사항"
+/// note | 기술적 세부사항
`from starlette.responses import HTMLResponse` 역시 사용할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/request-forms-and-files.md b/docs/ko/docs/tutorial/request-forms-and-files.md
index 0867414ea..75bca9f15 100644
--- a/docs/ko/docs/tutorial/request-forms-and-files.md
+++ b/docs/ko/docs/tutorial/request-forms-and-files.md
@@ -2,7 +2,7 @@
`File` 과 `Form` 을 사용하여 파일과 폼을 함께 정의할 수 있습니다.
-/// info | "정보"
+/// info | 정보
파일과 폼 데이터를 함께, 또는 각각 업로드하기 위해 먼저 `python-multipart`를 설치해야합니다.
@@ -13,7 +13,7 @@
## `File` 및 `Form` 업로드
```Python hl_lines="1"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!../../docs_src/request_forms_and_files/tutorial001.py!}
```
## `File` 및 `Form` 매개변수 정의
@@ -21,14 +21,14 @@
`Body` 및 `Query`와 동일한 방식으로 파일과 폼의 매개변수를 생성합니다:
```Python hl_lines="8"
-{!../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!../../docs_src/request_forms_and_files/tutorial001.py!}
```
파일과 폼 필드는 폼 데이터 형식으로 업로드되어 파일과 폼 필드로 전달됩니다.
어떤 파일들은 `bytes`로, 또 어떤 파일들은 `UploadFile`로 선언할 수 있습니다.
-/// warning | "경고"
+/// warning | 경고
다수의 `File`과 `Form` 매개변수를 한 *경로 작동*에 선언하는 것이 가능하지만, 요청의 본문이 `application/json`가 아닌 `multipart/form-data`로 인코딩 되기 때문에 JSON으로 받아야하는 `Body` 필드를 함께 선언할 수는 없습니다.
diff --git a/docs/ko/docs/tutorial/response-model.md b/docs/ko/docs/tutorial/response-model.md
index fc74a60b3..6ba9654d6 100644
--- a/docs/ko/docs/tutorial/response-model.md
+++ b/docs/ko/docs/tutorial/response-model.md
@@ -9,10 +9,10 @@
* 기타.
```Python hl_lines="17"
-{!../../../docs_src/response_model/tutorial001.py!}
+{!../../docs_src/response_model/tutorial001.py!}
```
-/// note | "참고"
+/// note | 참고
`response_model`은 "데코레이터" 메소드(`get`, `post`, 등)의 매개변수입니다. 모든 매개변수들과 본문(body)처럼 *경로 작동 함수*가 아닙니다.
@@ -31,7 +31,7 @@ FastAPI는 이 `response_model`를 사용하여:
* 해당 모델의 출력 데이터 제한. 이것이 얼마나 중요한지 아래에서 볼 것입니다.
-/// note | "기술 세부사항"
+/// note | 기술 세부사항
응답 모델은 함수의 타입 어노테이션 대신 이 매개변수로 선언하는데, 경로 함수가 실제 응답 모델을 반환하지 않고 `dict`, 데이터베이스 객체나 기타 다른 모델을 `response_model`을 사용하여 필드 제한과 직렬화를 수행하고 반환할 수 있기 때문입니다
@@ -42,13 +42,13 @@ FastAPI는 이 `response_model`를 사용하여:
여기서 우리는 평문 비밀번호를 포함하는 `UserIn` 모델을 선언합니다:
```Python hl_lines="9 11"
-{!../../../docs_src/response_model/tutorial002.py!}
+{!../../docs_src/response_model/tutorial002.py!}
```
그리고 이 모델을 사용하여 입력을 선언하고 같은 모델로 출력을 선언합니다:
```Python hl_lines="17-18"
-{!../../../docs_src/response_model/tutorial002.py!}
+{!../../docs_src/response_model/tutorial002.py!}
```
이제 브라우저가 비밀번호로 사용자를 만들 때마다 API는 응답으로 동일한 비밀번호를 반환합니다.
@@ -57,7 +57,7 @@ FastAPI는 이 `response_model`를 사용하여:
그러나 동일한 모델을 다른 *경로 작동*에서 사용할 경우, 모든 클라이언트에게 사용자의 비밀번호를 발신할 수 있습니다.
-/// danger | "위험"
+/// danger | 위험
절대로 사용자의 평문 비밀번호를 저장하거나 응답으로 발신하지 마십시오.
@@ -68,19 +68,19 @@ FastAPI는 이 `response_model`를 사용하여:
대신 평문 비밀번호로 입력 모델을 만들고 해당 비밀번호 없이 출력 모델을 만들 수 있습니다:
```Python hl_lines="9 11 16"
-{!../../../docs_src/response_model/tutorial003.py!}
+{!../../docs_src/response_model/tutorial003.py!}
```
여기서 *경로 작동 함수*가 비밀번호를 포함하는 동일한 입력 사용자를 반환할지라도:
```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial003.py!}
+{!../../docs_src/response_model/tutorial003.py!}
```
...`response_model`을 `UserOut` 모델로 선언했기 때문에 비밀번호를 포함하지 않습니다:
```Python hl_lines="22"
-{!../../../docs_src/response_model/tutorial003.py!}
+{!../../docs_src/response_model/tutorial003.py!}
```
따라서 **FastAPI**는 출력 모델에서 선언하지 않은 모든 데이터를 (Pydantic을 사용하여) 필터링합니다.
@@ -100,7 +100,7 @@ FastAPI는 이 `response_model`를 사용하여:
응답 모델은 아래와 같이 기본값을 가질 수 있습니다:
```Python hl_lines="11 13-14"
-{!../../../docs_src/response_model/tutorial004.py!}
+{!../../docs_src/response_model/tutorial004.py!}
```
* `description: Optional[str] = None`은 기본값으로 `None`을 갖습니다.
@@ -116,7 +116,7 @@ FastAPI는 이 `response_model`를 사용하여:
*경로 작동 데코레이터* 매개변수를 `response_model_exclude_unset=True`로 설정 할 수 있습니다:
```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial004.py!}
+{!../../docs_src/response_model/tutorial004.py!}
```
이러한 기본값은 응답에 포함되지 않고 실제로 설정된 값만 포함됩니다.
@@ -130,13 +130,13 @@ FastAPI는 이 `response_model`를 사용하여:
}
```
-/// info | "정보"
+/// info | 정보
FastAPI는 이를 위해 Pydantic 모델의 `.dict()`의 `exclude_unset` 매개변수를 사용합니다.
///
-/// info | "정보"
+/// info | 정보
아래 또한 사용할 수 있습니다:
@@ -181,7 +181,7 @@ ID가 `baz`인 항목(items)처럼 기본값과 동일한 값을 갖는다면:
따라서 JSON 스키마에 포함됩니다.
-/// tip | "팁"
+/// tip | 팁
`None` 뿐만 아니라 다른 어떤 것도 기본값이 될 수 있습니다.
@@ -197,7 +197,7 @@ ID가 `baz`인 항목(items)처럼 기본값과 동일한 값을 갖는다면:
Pydantic 모델이 하나만 있고 출력에서 일부 데이터를 제거하려는 경우 빠른 지름길로 사용할 수 있습니다.
-/// tip | "팁"
+/// tip | 팁
하지만 이러한 매개변수 대신 여러 클래스를 사용하여 위 아이디어를 사용하는 것을 추천합니다.
@@ -208,10 +208,10 @@ Pydantic 모델이 하나만 있고 출력에서 일부 데이터를 제
///
```Python hl_lines="31 37"
-{!../../../docs_src/response_model/tutorial005.py!}
+{!../../docs_src/response_model/tutorial005.py!}
```
-/// tip | "팁"
+/// tip | 팁
문법 `{"name", "description"}`은 두 값을 갖는 `set`을 만듭니다.
@@ -224,7 +224,7 @@ Pydantic 모델이 하나만 있고 출력에서 일부 데이터를 제
`list` 또는 `tuple` 대신 `set`을 사용하는 법을 잊었더라도, FastAPI는 `set`으로 변환하고 정상적으로 작동합니다:
```Python hl_lines="31 37"
-{!../../../docs_src/response_model/tutorial006.py!}
+{!../../docs_src/response_model/tutorial006.py!}
```
## 요약
diff --git a/docs/ko/docs/tutorial/response-status-code.md b/docs/ko/docs/tutorial/response-status-code.md
index 48cb49cbf..8e3a16645 100644
--- a/docs/ko/docs/tutorial/response-status-code.md
+++ b/docs/ko/docs/tutorial/response-status-code.md
@@ -9,10 +9,10 @@
* 기타
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
-/// note | "참고"
+/// note | 참고
`status_code` 는 "데코레이터" 메소드(`get`, `post` 등)의 매개변수입니다. 모든 매개변수들과 본문처럼 *경로 작동 함수*가 아닙니다.
@@ -20,7 +20,7 @@
`status_code` 매개변수는 HTTP 상태 코드를 숫자로 입력받습니다.
-/// info | "정보"
+/// info | 정보
`status_code` 는 파이썬의 `http.HTTPStatus` 와 같은 `IntEnum` 을 입력받을 수도 있습니다.
@@ -33,7 +33,7 @@
-/// note | "참고"
+/// note | 참고
어떤 응답 코드들은 해당 응답에 본문이 없다는 것을 의미하기도 합니다 (다음 항목 참고).
@@ -43,7 +43,7 @@
## HTTP 상태 코드에 대하여
-/// note | "참고"
+/// note | 참고
만약 HTTP 상태 코드에 대하여 이미 알고있다면, 다음 항목으로 넘어가십시오.
@@ -66,7 +66,7 @@ HTTP는 세자리의 숫자 상태 코드를 응답의 일부로 전송합니다
* 일반적인 클라이언트 오류의 경우 `400` 을 사용할 수 있습니다.
* `5xx` 상태 코드는 서버 오류에 사용됩니다. 이것들을 직접 사용할 일은 거의 없습니다. 응용 프로그램 코드나 서버의 일부에서 문제가 발생하면 자동으로 이들 상태 코드 중 하나를 반환합니다.
-/// tip | "팁"
+/// tip | 팁
각각의 상태 코드와 이들이 의미하는 내용에 대해 더 알고싶다면 MDN HTTP 상태 코드에 관한 문서 를 확인하십시오.
@@ -77,7 +77,7 @@ HTTP는 세자리의 숫자 상태 코드를 응답의 일부로 전송합니다
상기 예시 참고:
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
`201` 은 "생성됨"를 의미하는 상태 코드입니다.
@@ -87,14 +87,14 @@ HTTP는 세자리의 숫자 상태 코드를 응답의 일부로 전송합니다
`fastapi.status` 의 편의 변수를 사용할 수 있습니다.
```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
+{!../../docs_src/response_status_code/tutorial002.py!}
```
이것은 단순히 작업을 편리하게 하기 위한 것으로, HTTP 상태 코드와 동일한 번호를 갖고있지만, 이를 사용하면 편집기의 자동완성 기능을 사용할 수 있습니다:
-/// note | "기술적 세부사항"
+/// note | 기술적 세부사항
`from starlette import status` 역시 사용할 수 있습니다.
diff --git a/docs/ko/docs/tutorial/schema-extra-example.md b/docs/ko/docs/tutorial/schema-extra-example.md
index 7b5ccdd32..77e94db72 100644
--- a/docs/ko/docs/tutorial/schema-extra-example.md
+++ b/docs/ko/docs/tutorial/schema-extra-example.md
@@ -8,35 +8,15 @@
생성된 JSON 스키마에 추가될 Pydantic 모델을 위한 `examples`을 선언할 수 있습니다.
-//// tab | Python 3.10+ Pydantic v2
+//// tab | Pydantic v2
-```Python hl_lines="13-24"
-{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
////
-//// tab | Python 3.10+ Pydantic v1
+//// tab | Pydantic v1
-```Python hl_lines="13-23"
-{!> ../../../docs_src/schema_extra_example/tutorial001_py310_pv1.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Pydantic v2
-
-```Python hl_lines="15-26"
-{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Pydantic v1
-
-```Python hl_lines="15-25"
-{!> ../../../docs_src/schema_extra_example/tutorial001_pv1.py!}
-```
+{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
////
@@ -58,7 +38,7 @@ Pydantic v1에서 ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="4 10-13"
-{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
## JSON Schema에서의 `examples` - OpenAPI
@@ -114,57 +80,7 @@ Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를
여기, `Body()`에 예상되는 예제 데이터 하나를 포함한 `examples`를 넘겼습니다:
-//// tab | Python 3.10+
-
-```Python hl_lines="22-29"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="22-29"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="23-30"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ Annotated가 없는 경우
-
-/// tip | "팁"
-
-가능하다면 `Annotated`가 달린 버전을 권장합니다.
-
-///
-
-```Python hl_lines="18-25"
-{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Annotated가 없는 경우
-
-/// tip | "팁"
-
-가능하다면 `Annotated`가 달린 버전을 권장합니다.
-
-///
-
-```Python hl_lines="20-27"
-{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *}
### 문서 UI 예시
@@ -176,57 +92,7 @@ Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를
물론 여러 `examples`를 넘길 수 있습니다:
-//// tab | Python 3.10+
-
-```Python hl_lines="23-38"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="23-38"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="24-39"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ Annotated가 없는 경우
-
-/// tip | "팁"
-
-가능하다면 `Annotated`가 달린 버전을 권장합니다.
-
-///
-
-```Python hl_lines="19-34"
-{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Annotated가 없는 경우
-
-/// tip | "팁"
-
-가능하다면 `Annotated`가 달린 버전을 권장합니다.
-
-///
-
-```Python hl_lines="21-36"
-{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}
이와 같이 하면 이 예제는 그 본문 데이터를 위한 내부 **JSON 스키마**의 일부가 될 것입니다.
@@ -267,57 +133,7 @@ Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를
이를 다음과 같이 사용할 수 있습니다:
-//// tab | Python 3.10+
-
-```Python hl_lines="23-49"
-{!> ../../../docs_src/schema_extra_example/tutorial005_an_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="23-49"
-{!> ../../../docs_src/schema_extra_example/tutorial005_an_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="24-50"
-{!> ../../../docs_src/schema_extra_example/tutorial005_an.py!}
-```
-
-////
-
-//// tab | Python 3.10+ Annotated가 없는 경우
-
-/// tip | "팁"
-
-가능하다면 `Annotated`가 달린 버전을 권장합니다.
-
-///
-
-```Python hl_lines="19-45"
-{!> ../../../docs_src/schema_extra_example/tutorial005_py310.py!}
-```
-
-////
-
-//// tab | Python 3.8+ Annotated가 없는 경우
-
-/// tip | "팁"
-
-가능하다면 `Annotated`가 달린 버전을 권장합니다.
-
-///
-
-```Python hl_lines="21-47"
-{!> ../../../docs_src/schema_extra_example/tutorial005.py!}
-```
-
-////
+{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
### 문서 UI에서의 OpenAPI 예시
@@ -327,7 +143,7 @@ Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를
## 기술적 세부 사항
-/// tip | "팁"
+/// tip | 팁
이미 **FastAPI**의 **0.99.0 혹은 그 이상** 버전을 사용하고 있다면, 이 세부 사항을 **스킵**해도 상관 없을 것입니다.
@@ -337,7 +153,7 @@ Pydantic 모델과 같이 `Field()`를 사용할 때 추가적인 `examples`를
///
-/// warning | "경고"
+/// warning | 경고
표준 **JSON 스키마**와 **OpenAPI**에 대한 아주 기술적인 세부사항입니다.
@@ -361,7 +177,7 @@ OpenAPI는 또한 `example`과 `examples` 필드를 명세서의 다른 부분
* `File()`
* `Form()`
-/// info | "정보"
+/// info | 정보
이 예전 OpenAPI-특화 `examples` 매개변수는 이제 FastAPI `0.103.0`부터 `openapi_examples`입니다.
@@ -377,7 +193,7 @@ OpenAPI는 또한 `example`과 `examples` 필드를 명세서의 다른 부분
JSON 스키마의 새로운 `examples` 필드는 예제 속 **단순한 `list`**이며, (위에서 상술한 것처럼) OpenAPI의 다른 곳에 존재하는 dict으로 된 추가적인 메타데이터가 아닙니다.
-/// info | "정보"
+/// info | 정보
더 쉽고 새로운 JSON 스키마와의 통합과 함께 OpenAPI 3.1.0가 배포되었지만, 잠시동안 자동 문서 생성을 제공하는 도구인 Swagger UI는 OpenAPI 3.1.0을 지원하지 않았습니다 (5.0.0 버전부터 지원합니다 🎉).
diff --git a/docs/ko/docs/tutorial/security/get-current-user.md b/docs/ko/docs/tutorial/security/get-current-user.md
index 9bf3d4ee1..cf550735a 100644
--- a/docs/ko/docs/tutorial/security/get-current-user.md
+++ b/docs/ko/docs/tutorial/security/get-current-user.md
@@ -3,7 +3,7 @@
이전 장에서 (의존성 주입 시스템을 기반으로 한)보안 시스템은 *경로 작동 함수*에서 `str`로 `token`을 제공했습니다:
```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
그러나 아직도 유용하지 않습니다.
@@ -19,7 +19,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.7 이상
```Python hl_lines="5 12-16"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -27,7 +27,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.10 이상
```Python hl_lines="3 10-14"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -45,7 +45,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.7 이상
```Python hl_lines="25"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -53,7 +53,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.10 이상
```Python hl_lines="23"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -65,7 +65,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.7 이상
```Python hl_lines="19-22 26-27"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -73,7 +73,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.10 이상
```Python hl_lines="17-20 24-25"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -85,7 +85,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.7 이상
```Python hl_lines="31"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -93,7 +93,7 @@ Pydantic을 사용하여 본문을 선언하는 것과 같은 방식으로 다
//// tab | 파이썬 3.10 이상
```Python hl_lines="29"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
@@ -102,7 +102,7 @@ Pydantic 모델인 `User`로 `current_user`의 타입을 선언하는 것을 알
이것은 모든 완료 및 타입 검사를 통해 함수 내부에서 우리를 도울 것입니다.
-/// tip | "팁"
+/// tip | 팁
요청 본문도 Pydantic 모델로 선언된다는 것을 기억할 것입니다.
@@ -110,7 +110,7 @@ Pydantic 모델인 `User`로 `current_user`의 타입을 선언하는 것을 알
///
-/// check | "확인"
+/// check | 확인
이 의존성 시스템이 설계된 방식은 모두 `User` 모델을 반환하는 다양한 의존성(다른 "의존적인")을 가질 수 있도록 합니다.
@@ -153,7 +153,7 @@ Pydantic 모델인 `User`로 `current_user`의 타입을 선언하는 것을 알
//// tab | 파이썬 3.7 이상
```Python hl_lines="30-32"
-{!> ../../../docs_src/security/tutorial002.py!}
+{!> ../../docs_src/security/tutorial002.py!}
```
////
@@ -161,7 +161,7 @@ Pydantic 모델인 `User`로 `current_user`의 타입을 선언하는 것을 알
//// tab | 파이썬 3.10 이상
```Python hl_lines="28-30"
-{!> ../../../docs_src/security/tutorial002_py310.py!}
+{!> ../../docs_src/security/tutorial002_py310.py!}
```
////
diff --git a/docs/ko/docs/tutorial/security/simple-oauth2.md b/docs/ko/docs/tutorial/security/simple-oauth2.md
index 9593f96f5..fd18c1d47 100644
--- a/docs/ko/docs/tutorial/security/simple-oauth2.md
+++ b/docs/ko/docs/tutorial/security/simple-oauth2.md
@@ -55,7 +55,7 @@ OAuth2의 경우 문자열일 뿐입니다.
//// tab | 파이썬 3.7 이상
```Python hl_lines="4 76"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -63,7 +63,7 @@ OAuth2의 경우 문자열일 뿐입니다.
//// tab | 파이썬 3.10 이상
```Python hl_lines="2 74"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -117,7 +117,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
//// tab | 파이썬 3.7 이상
```Python hl_lines="3 77-79"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -125,7 +125,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
//// tab | 파이썬 3.10 이상
```Python hl_lines="1 75-77"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -157,7 +157,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
//// tab | P파이썬 3.7 이상
```Python hl_lines="80-83"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -165,7 +165,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
//// tab | 파이썬 3.10 이상
```Python hl_lines="78-81"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -213,7 +213,7 @@ UserInDB(
//// tab | 파이썬 3.7 이상
```Python hl_lines="85"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -221,7 +221,7 @@ UserInDB(
//// tab | 파이썬 3.10 이상
```Python hl_lines="83"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
@@ -253,7 +253,7 @@ UserInDB(
//// tab | 파이썬 3.7 이상
```Python hl_lines="58-66 69-72 90"
-{!> ../../../docs_src/security/tutorial003.py!}
+{!> ../../docs_src/security/tutorial003.py!}
```
////
@@ -261,7 +261,7 @@ UserInDB(
//// tab | 파이썬 3.10 이상
```Python hl_lines="55-64 67-70 88"
-{!> ../../../docs_src/security/tutorial003_py310.py!}
+{!> ../../docs_src/security/tutorial003_py310.py!}
```
////
diff --git a/docs/ko/docs/tutorial/static-files.md b/docs/ko/docs/tutorial/static-files.md
index 360aaaa6b..af785f206 100644
--- a/docs/ko/docs/tutorial/static-files.md
+++ b/docs/ko/docs/tutorial/static-files.md
@@ -8,10 +8,10 @@
* 특정 경로에 `StaticFiles()` 인스턴스를 "마운트" 합니다.
```Python hl_lines="2 6"
-{!../../../docs_src/static_files/tutorial001.py!}
+{!../../docs_src/static_files/tutorial001.py!}
```
-/// note | "기술적 세부사항"
+/// note | 기술적 세부사항
`from starlette.staticfiles import StaticFiles` 를 사용할 수도 있습니다.
diff --git a/docs/nl/docs/environment-variables.md b/docs/nl/docs/environment-variables.md
new file mode 100644
index 000000000..f6b3d285b
--- /dev/null
+++ b/docs/nl/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# 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
+
+
+
+### 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":
+
+```Python hl_lines="1"
+{!../../docs_src/python_types/tutorial002.py!}
+```
+
+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:
+
+```Python hl_lines="1"
+{!../../docs_src/python_types/tutorial003.py!}
+```
+
+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)`:
+
+```Python hl_lines="2"
+{!../../docs_src/python_types/tutorial004.py!}
+```
+
+## 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`
+
+```Python hl_lines="1"
+{!../../docs_src/python_types/tutorial005.py!}
+```
+
+### 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:
+
+```Python hl_lines="1 4"
+{!../../docs_src/python_types/tutorial009c.py!}
+```
+
+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:
+
+```Python hl_lines="1 4"
+{!../../docs_src/python_types/tutorial009c_py310.py!}
+```
+
+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:
+
+```Python hl_lines="1-3"
+{!../../docs_src/python_types/tutorial010.py!}
+```
+
+Vervolgens kun je een variabele van het type `Persoon` declareren:
+
+```Python hl_lines="6"
+{!../../docs_src/python_types/tutorial010.py!}
+```
+
+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/pl/docs/help-fastapi.md b/docs/pl/docs/help-fastapi.md
index 4daad5e90..3ea328dc2 100644
--- a/docs/pl/docs/help-fastapi.md
+++ b/docs/pl/docs/help-fastapi.md
@@ -229,7 +229,7 @@ Jeśli możesz mi w tym pomóc, **pomożesz mi utrzymać FastAPI** i zapewnisz
Dołącz do 👥 serwera czatu na Discordzie 👥 i spędzaj czas z innymi w społeczności FastAPI.
-/// tip | "Wskazówka"
+/// 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}.
diff --git a/docs/pl/docs/index.md b/docs/pl/docs/index.md
index e591e1c9d..9a96c6553 100644
--- a/docs/pl/docs/index.md
+++ b/docs/pl/docs/index.md
@@ -90,7 +90,7 @@ Kluczowe cechy:
"_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._"
-
+
---
diff --git a/docs/pl/docs/tutorial/first-steps.md b/docs/pl/docs/tutorial/first-steps.md
index 8f1b9b922..8fa4c75ad 100644
--- a/docs/pl/docs/tutorial/first-steps.md
+++ b/docs/pl/docs/tutorial/first-steps.md
@@ -2,9 +2,7 @@
Najprostszy plik FastAPI może wyglądać tak:
-```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py *}
Skopiuj to do pliku `main.py`.
@@ -133,13 +131,11 @@ Możesz go również użyć do automatycznego generowania kodu dla klientów, kt
### Krok 1: zaimportuj `FastAPI`
-```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
-```
+{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
`FastAPI` jest klasą, która zapewnia wszystkie funkcjonalności Twojego API.
-/// note | "Szczegóły techniczne"
+/// note | Szczegóły techniczne
`FastAPI` jest klasą, która dziedziczy bezpośrednio z `Starlette`.
@@ -149,9 +145,7 @@ Oznacza to, że możesz korzystać ze wszystkich funkcjonalności operacji get
+
+## Respostas disponíveis
+
+Aqui estão algumas dos tipos de resposta disponíveis.
+
+Lembre-se que você pode utilizar `Response` para retornar qualquer outra coisa, ou até mesmo criar uma subclasse personalizada.
+
+/// note | Detalhes Técnicos
+
+Você também pode utilizar `from starlette.responses import HTMLResponse`.
+
+O **FastAPI** provê a mesma `starlette.responses` como `fastapi.responses` apenas como uma facilidade para você, desenvolvedor. Mas a maioria das respostas disponíveis vêm diretamente do Starlette.
+
+///
+
+### `Response`
+
+A classe principal de respostas, todas as outras respostas herdam dela.
+
+Você pode retorná-la diretamente.
+
+Ela aceita os seguintes parâmetros:
+
+* `content` - Uma sequência de caracteres (`str`) ou `bytes`.
+* `status_code` - Um código de status HTTP do tipo `int`.
+* `headers` - Um dicionário `dict` de strings.
+* `media_type` - Uma `str` informando o media type. E.g. `"text/html"`.
+
+O FastAPI (Starlette, na verdade) irá incluir o cabeçalho Content-Length automaticamente. Ele também irá incluir o cabeçalho Content-Type, baseado no `media_type` e acrescentando uma codificação para tipos textuais.
+
+```Python hl_lines="1 18"
+{!../../docs_src/response_directly/tutorial002.py!}
+```
+
+### `HTMLResponse`
+
+Usa algum texto ou sequência de bytes e retorna uma resposta HTML. Como você leu acima.
+
+### `PlainTextResponse`
+
+Usa algum texto ou sequência de bytes para retornar uma resposta de texto não formatado.
+
+```Python hl_lines="2 7 9"
+{!../../docs_src/custom_response/tutorial005.py!}
+```
+
+### `JSONResponse`
+
+Pega alguns dados e retorna uma resposta com codificação `application/json`.
+
+É a resposta padrão utilizada no **FastAPI**, como você leu acima.
+
+### `ORJSONResponse`
+
+Uma alternativa mais rápida de resposta JSON utilizando o `orjson`, como você leu acima.
+
+/// info | Informação
+
+Essa resposta requer a instalação do pacote `orjson`, com o comando `pip install orjson`, por exemplo.
+
+///
+
+### `UJSONResponse`
+
+Uma alternativa de resposta JSON utilizando a biblioteca `ujson`.
+
+/// info | Informação
+
+Essa resposta requer a instalação do pacote `ujson`, com o comando `pip install ujson`, por exemplo.
+
+///
+
+/// warning | Aviso
+
+`ujson` é menos cauteloso que a implementação nativa do Python na forma que os casos especiais são tratados
+
+///
+
+```Python hl_lines="2 7"
+{!../../docs_src/custom_response/tutorial001.py!}
+```
+
+/// tip | Dica
+
+É possível que `ORJSONResponse` seja uma alternativa mais rápida.
+
+///
+
+### `RedirectResponse`
+
+Retorna um redirecionamento HTTP. Utiliza o código de status 307 (Redirecionamento Temporário) por padrão.
+
+Você pode retornar uma `RedirectResponse` diretamente:
+
+```Python hl_lines="2 9"
+{!../../docs_src/custom_response/tutorial006.py!}
+```
+
+---
+
+Ou você pode utilizá-la no parâmetro `response_class`:
+
+```Python hl_lines="2 7 9"
+{!../../docs_src/custom_response/tutorial006b.py!}
+```
+
+Se você fizer isso, então você pode retornar a URL diretamente da sua *função de operação de rota*
+
+Neste caso, o `status_code` utilizada será o padrão de `RedirectResponse`, que é `307`.
+
+---
+
+Você também pode utilizar o parâmetro `status_code` combinado com o parâmetro `response_class`:
+
+```Python hl_lines="2 7 9"
+{!../../docs_src/custom_response/tutorial006c.py!}
+```
+
+### `StreamingResponse`
+
+Recebe uma gerador assíncrono ou um gerador/iterador comum e retorna o corpo da requisição continuamente (stream).
+
+```Python hl_lines="2 14"
+{!../../docs_src/custom_response/tutorial007.py!}
+```
+
+#### Utilizando `StreamingResponse` com objetos semelhantes a arquivos
+
+Se você tiver um objeto semelhante a um arquivo (e.g. o objeto retornado por `open()`), você pode criar uma função geradora para iterar sobre esse objeto.
+
+Dessa forma, você não precisa ler todo o arquivo na memória primeiro, e você pode passar essa função geradora para `StreamingResponse` e retorná-la.
+
+Isso inclui muitas bibliotecas que interagem com armazenamento em nuvem, processamento de vídeos, entre outras.
+
+```{ .python .annotate hl_lines="2 10-12 14" }
+{!../../docs_src/custom_response/tutorial008.py!}
+```
+
+1. Essa é a função geradora. É definida como "função geradora" porque contém declarações `yield` nela.
+2. Ao utilizar o bloco `with`, nós garantimos que o objeto semelhante a um arquivo é fechado após a função geradora ser finalizada. Isto é, após a resposta terminar de ser enivada.
+3. Essa declaração `yield from` informa a função para iterar sobre essa coisa nomeada de `file_like`. E então, para cada parte iterada, fornece essa parte como se viesse dessa função geradora (`iterfile`).
+
+ Então, é uma função geradora que transfere o trabalho de "geração" para alguma outra coisa interna.
+
+ Fazendo dessa forma, podemos colocá-la em um bloco `with`, e assim garantir que o objeto semelhante a um arquivo é fechado quando a função termina.
+
+/// tip | Dica
+
+Perceba que aqui estamos utilizando o `open()` da biblioteca padrão que não suporta `async` e `await`, e declaramos a operação de rota com o `def` básico.
+
+///
+
+### `FileResponse`
+
+Envia um arquivo de forma assíncrona e contínua (stream).
+*
+Recebe um conjunto de argumentos do construtor diferente dos outros tipos de resposta:
+
+* `path` - O caminho do arquivo que será transmitido
+* `headers` - quaisquer cabeçalhos que serão incluídos, como um dicionário.
+* `media_type` - Uma string com o media type. Se não for definida, o media type é inferido a partir do nome ou caminho do arquivo.
+* `filename` - Se for definido, é incluído no cabeçalho `Content-Disposition`.
+
+Respostas de Arquivos incluem o tamanho do arquivo, data da última modificação e ETags apropriados, nos cabeçalhos `Content-Length`, `Last-Modified` e `ETag`, respectivamente.
+
+```Python hl_lines="2 10"
+{!../../docs_src/custom_response/tutorial009.py!}
+```
+
+Você também pode usar o parâmetro `response_class`:
+
+```Python hl_lines="2 8 10"
+{!../../docs_src/custom_response/tutorial009b.py!}
+```
+
+Nesse caso, você pode retornar o caminho do arquivo diretamente da sua *função de operação de rota*.
+
+## Classe de resposta personalizada
+
+Você pode criar sua própria classe de resposta, herdando de `Response` e usando essa nova classe.
+
+Por exemplo, vamos supor que você queira utilizar o `orjson`, mas com algumas configurações personalizadas que não estão incluídas na classe `ORJSONResponse`.
+
+Vamos supor também que você queira retornar um JSON indentado e formatado, então você quer utilizar a opção `orjson.OPT_INDENT_2` do orjson.
+
+Você poderia criar uma classe `CustomORJSONResponse`. A principal coisa a ser feita é sobrecarregar o método render da classe Response, `Response.render(content)`, que retorna o conteúdo em bytes, para retornar o conteúdo que você deseja:
+
+```Python hl_lines="9-14 17"
+{!../../docs_src/custom_response/tutorial009c.py!}
+```
+
+Agora em vez de retornar:
+
+```json
+{"message": "Hello World"}
+```
+
+...essa resposta retornará:
+
+```json
+{
+ "message": "Hello World"
+}
+```
+
+Obviamente, você provavelmente vai encontrar maneiras muito melhores de se aproveitar disso do que a formatação de JSON. 😉
+
+## Classe de resposta padrão
+
+Quando você criar uma instância da classe **FastAPI** ou um `APIRouter` você pode especificar qual classe de resposta utilizar por padrão.
+
+O padrão que define isso é o `default_response_class`.
+
+No exemplo abaixo, o **FastAPI** irá utilizar `ORJSONResponse` por padrão, em todas as *operações de rota*, em vez de `JSONResponse`.
+
+```Python hl_lines="2 4"
+{!../../docs_src/custom_response/tutorial010.py!}
+```
+
+/// tip | Dica
+
+Você ainda pode substituir `response_class` em *operações de rota* como antes.
+
+///
+
+## Documentação adicional
+
+Você também pode declarar o media type e muitos outros detalhes no OpenAPI utilizando `responses`: [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/pt/docs/advanced/dataclasses.md b/docs/pt/docs/advanced/dataclasses.md
new file mode 100644
index 000000000..af603ada7
--- /dev/null
+++ b/docs/pt/docs/advanced/dataclasses.md
@@ -0,0 +1,101 @@
+# Usando Dataclasses
+
+FastAPI é construído em cima do **Pydantic**, e eu tenho mostrado como usar modelos Pydantic para declarar requisições e respostas.
+
+Mas o FastAPI também suporta o uso de `dataclasses` da mesma forma:
+
+```Python hl_lines="1 7-12 19-20"
+{!../../docs_src/dataclasses/tutorial001.py!}
+```
+
+Isso ainda é suportado graças ao **Pydantic**, pois ele tem suporte interno para `dataclasses`.
+
+Então, mesmo com o código acima que não usa Pydantic explicitamente, o FastAPI está usando Pydantic para converter essas dataclasses padrão para a versão do Pydantic.
+
+E claro, ele suporta o mesmo:
+
+* validação de dados
+* serialização de dados
+* documentação de dados, etc.
+
+Isso funciona da mesma forma que com os modelos Pydantic. E na verdade é alcançado da mesma maneira por baixo dos panos, usando Pydantic.
+
+/// info | Informação
+
+Lembre-se de que dataclasses não podem fazer tudo o que os modelos Pydantic podem fazer.
+
+Então, você ainda pode precisar usar modelos Pydantic.
+
+Mas se você tem um monte de dataclasses por aí, este é um truque legal para usá-las para alimentar uma API web usando FastAPI. 🤓
+
+///
+
+## Dataclasses em `response_model`
+
+Você também pode usar `dataclasses` no parâmetro `response_model`:
+
+```Python hl_lines="1 7-13 19"
+{!../../docs_src/dataclasses/tutorial002.py!}
+```
+
+A dataclass será automaticamente convertida para uma dataclass Pydantic.
+
+Dessa forma, seu esquema aparecerá na interface de documentação da API:
+
+
+
+## Dataclasses em Estruturas de Dados Aninhadas
+
+Você também pode combinar `dataclasses` com outras anotações de tipo para criar estruturas de dados aninhadas.
+
+Em alguns casos, você ainda pode ter que usar a versão do Pydantic das `dataclasses`. Por exemplo, se você tiver erros com a documentação da API gerada automaticamente.
+
+Nesse caso, você pode simplesmente trocar as `dataclasses` padrão por `pydantic.dataclasses`, que é um substituto direto:
+
+```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
+{!../../docs_src/dataclasses/tutorial003.py!}
+```
+
+1. Ainda importamos `field` das `dataclasses` padrão.
+
+2. `pydantic.dataclasses` é um substituto direto para `dataclasses`.
+
+3. A dataclass `Author` inclui uma lista de dataclasses `Item`.
+
+4. A dataclass `Author` é usada como o parâmetro `response_model`.
+
+5. Você pode usar outras anotações de tipo padrão com dataclasses como o corpo da requisição.
+
+ Neste caso, é uma lista de dataclasses `Item`.
+
+6. Aqui estamos retornando um dicionário que contém `items`, que é uma lista de dataclasses.
+
+ O FastAPI ainda é capaz de serializar os dados para JSON.
+
+7. Aqui o `response_model` está usando uma anotação de tipo de uma lista de dataclasses `Author`.
+
+ Novamente, você pode combinar `dataclasses` com anotações de tipo padrão.
+
+8. Note que esta *função de operação de rota* usa `def` regular em vez de `async def`.
+
+ Como sempre, no FastAPI você pode combinar `def` e `async def` conforme necessário.
+
+ Se você precisar de uma atualização sobre quando usar qual, confira a seção _"Com pressa?"_ na documentação sobre [`async` e `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+9. Esta *função de operação de rota* não está retornando dataclasses (embora pudesse), mas uma lista de dicionários com dados internos.
+
+ O FastAPI usará o parâmetro `response_model` (que inclui dataclasses) para converter a resposta.
+
+Você pode combinar `dataclasses` com outras anotações de tipo em muitas combinações diferentes para formar estruturas de dados complexas.
+
+Confira as dicas de anotação no código acima para ver mais detalhes específicos.
+
+## Saiba Mais
+
+Você também pode combinar `dataclasses` com outros modelos Pydantic, herdar deles, incluí-los em seus próprios modelos, etc.
+
+Para saber mais, confira a documentação do Pydantic sobre dataclasses.
+
+## Versão
+
+Isso está disponível desde a versão `0.67.0` do FastAPI. 🔖
diff --git a/docs/pt/docs/advanced/events.md b/docs/pt/docs/advanced/events.md
index 5f722763e..783dbfc83 100644
--- a/docs/pt/docs/advanced/events.md
+++ b/docs/pt/docs/advanced/events.md
@@ -32,14 +32,14 @@ Vamos iniciar com um exemplo e ver isso detalhadamente.
Nós criamos uma função assíncrona chamada `lifespan()` com `yield` como este:
```Python hl_lines="16 19"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
Aqui nós estamos simulando a *inicialização* custosa do carregamento do modelo colocando a (falsa) função de modelo no dicionário com modelos de _machine learning_ antes do `yield`. Este código será executado **antes** da aplicação **começar a receber requisições**, durante a *inicialização*.
E então, logo após o `yield`, descarregaremos o modelo. Esse código será executado **após** a aplicação **terminar de lidar com as requisições**, pouco antes do *encerramento*. Isso poderia, por exemplo, liberar recursos como memória ou GPU.
-/// tip | "Dica"
+/// tip | Dica
O `shutdown` aconteceria quando você estivesse **encerrando** a aplicação.
@@ -52,7 +52,7 @@ Talvez você precise inicializar uma nova versão, ou apenas cansou de executá-
A primeira coisa a notar, é que estamos definindo uma função assíncrona com `yield`. Isso é muito semelhante à Dependências com `yield`.
```Python hl_lines="14-19"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
A primeira parte da função, antes do `yield`, será executada **antes** da aplicação inicializar.
@@ -66,7 +66,7 @@ Se você verificar, a função está decorada com um `@asynccontextmanager`.
Que converte a função em algo chamado de "**Gerenciador de Contexto Assíncrono**".
```Python hl_lines="1 13"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
Um **gerenciador de contexto** em Python é algo que você pode usar em uma declaração `with`, por exemplo, `open()` pode ser usado como um gerenciador de contexto:
@@ -90,12 +90,12 @@ No nosso exemplo de código acima, nós não usamos ele diretamente, mas nós pa
O parâmetro `lifespan` da aplicação `FastAPI` usa um **Gerenciador de Contexto Assíncrono**, então nós podemos passar nosso novo gerenciador de contexto assíncrono do `lifespan` para ele.
```Python hl_lines="22"
-{!../../../docs_src/events/tutorial003.py!}
+{!../../docs_src/events/tutorial003.py!}
```
## Eventos alternativos (deprecados)
-/// warning | "Aviso"
+/// warning | Aviso
A maneira recomendada para lidar com a *inicialização* e o *encerramento* é usando o parâmetro `lifespan` da aplicação `FastAPI` como descrito acima.
@@ -114,7 +114,7 @@ Essas funções podem ser declaradas com `async def` ou `def` normal.
Para adicionar uma função que deve rodar antes da aplicação iniciar, declare-a com o evento `"startup"`:
```Python hl_lines="8"
-{!../../../docs_src/events/tutorial001.py!}
+{!../../docs_src/events/tutorial001.py!}
```
Nesse caso, a função de manipulação de evento `startup` irá inicializar os itens do "banco de dados" (só um `dict`) com alguns valores.
@@ -128,18 +128,18 @@ E sua aplicação não irá começar a receber requisições até que todos os m
Para adicionar uma função que deve ser executada quando a aplicação estiver encerrando, declare ela com o evento `"shutdown"`:
```Python hl_lines="6"
-{!../../../docs_src/events/tutorial002.py!}
+{!../../docs_src/events/tutorial002.py!}
```
Aqui, a função de manipulação de evento `shutdown` irá escrever uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
-/// info | "Informação"
+/// info | Informação
Na função `open()`, o `mode="a"` significa "acrescentar", então, a linha irá ser adicionada depois de qualquer coisa que esteja naquele arquivo, sem sobrescrever o conteúdo anterior.
///
-/// tip | "Dica"
+/// tip | Dica
Perceba que nesse caso nós estamos usando a função padrão do Python `open()` que interage com um arquivo.
@@ -165,7 +165,7 @@ Só um detalhe técnico para nerds curiosos. 🤓
Por baixo, na especificação técnica ASGI, essa é a parte do Protocolo Lifespan, e define eventos chamados `startup` e `shutdown`.
-/// info | "Informação"
+/// info | Informação
Você pode ler mais sobre o manipulador `lifespan` do Starlette na Documentação do Lifespan Starlette.
diff --git a/docs/pt/docs/advanced/index.md b/docs/pt/docs/advanced/index.md
index 2569fc914..22ba2bf4a 100644
--- a/docs/pt/docs/advanced/index.md
+++ b/docs/pt/docs/advanced/index.md
@@ -6,7 +6,7 @@ O [Tutorial - Guia de Usuário](../tutorial/index.md){.internal-link target=_bla
Na próxima seção você verá outras opções, configurações, e recursos adicionais.
-/// tip | "Dica"
+/// tip | Dica
As próximas seções **não são necessáriamente "avançadas"**
diff --git a/docs/pt/docs/advanced/middleware.md b/docs/pt/docs/advanced/middleware.md
new file mode 100644
index 000000000..8167f7d27
--- /dev/null
+++ b/docs/pt/docs/advanced/middleware.md
@@ -0,0 +1,96 @@
+# Middleware Avançado
+
+No tutorial principal você leu como adicionar [Middleware Personalizado](../tutorial/middleware.md){.internal-link target=_blank} à sua aplicação.
+
+E então você também leu como lidar com [CORS com o `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
+
+Nesta seção, veremos como usar outros middlewares.
+
+## Adicionando middlewares ASGI
+
+Como o **FastAPI** é baseado no Starlette e implementa a especificação ASGI, você pode usar qualquer middleware ASGI.
+
+O middleware não precisa ser feito para o FastAPI ou Starlette para funcionar, desde que siga a especificação ASGI.
+
+No geral, os middlewares ASGI são classes que esperam receber um aplicativo ASGI como o primeiro argumento.
+
+Então, na documentação de middlewares ASGI de terceiros, eles provavelmente dirão para você fazer algo como:
+
+```Python
+from unicorn import UnicornMiddleware
+
+app = SomeASGIApp()
+
+new_app = UnicornMiddleware(app, some_config="rainbow")
+```
+
+Mas, o FastAPI (na verdade, o Starlette) fornece uma maneira mais simples de fazer isso que garante que os middlewares internos lidem com erros do servidor e que os manipuladores de exceções personalizados funcionem corretamente.
+
+Para isso, você usa `app.add_middleware()` (como no exemplo para CORS).
+
+```Python
+from fastapi import FastAPI
+from unicorn import UnicornMiddleware
+
+app = FastAPI()
+
+app.add_middleware(UnicornMiddleware, some_config="rainbow")
+```
+
+`app.add_middleware()` recebe uma classe de middleware como o primeiro argumento e quaisquer argumentos adicionais a serem passados para o middleware.
+
+## Middlewares Integrados
+
+**FastAPI** inclui vários middlewares para casos de uso comuns, veremos a seguir como usá-los.
+
+/// note | Detalhes Técnicos
+
+Para o próximo exemplo, você também poderia usar `from starlette.middleware.something import SomethingMiddleware`.
+
+**FastAPI** fornece vários middlewares em `fastapi.middleware` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria dos middlewares disponíveis vem diretamente do Starlette.
+
+///
+
+## `HTTPSRedirectMiddleware`
+
+Garante que todas as requisições devem ser `https` ou `wss`.
+
+Qualquer requisição para `http` ou `ws` será redirecionada para o esquema seguro.
+
+{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
+
+## `TrustedHostMiddleware`
+
+Garante que todas as requisições recebidas tenham um cabeçalho `Host` corretamente configurado, a fim de proteger contra ataques de cabeçalho de host HTTP.
+
+{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
+
+Os seguintes argumentos são suportados:
+
+* `allowed_hosts` - Uma lista de nomes de domínio que são permitidos como nomes de host. Domínios com coringa, como `*.example.com`, são suportados para corresponder a subdomínios. Para permitir qualquer nome de host, use `allowed_hosts=["*"]` ou omita o middleware.
+
+Se uma requisição recebida não for validada corretamente, uma resposta `400` será enviada.
+
+## `GZipMiddleware`
+
+Gerencia respostas GZip para qualquer requisição que inclua `"gzip"` no cabeçalho `Accept-Encoding`.
+
+O middleware lidará com respostas padrão e de streaming.
+
+{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
+
+Os seguintes argumentos são suportados:
+
+* `minimum_size` - Não comprima respostas menores que este tamanho mínimo em bytes. O padrão é `500`.
+* `compresslevel` - Usado durante a compressão GZip. É um inteiro variando de 1 a 9. O padrão é `9`. Um valor menor resulta em uma compressão mais rápida, mas em arquivos maiores, enquanto um valor maior resulta em uma compressão mais lenta, mas em arquivos menores.
+
+## Outros middlewares
+
+Há muitos outros middlewares ASGI.
+
+Por exemplo:
+
+* Uvicorn's `ProxyHeadersMiddleware`
+* MessagePack
+
+Para checar outros middlewares disponíveis, confira Documentação de Middlewares do Starlette e a Lista Incrível do ASGI.
diff --git a/docs/pt/docs/advanced/openapi-callbacks.md b/docs/pt/docs/advanced/openapi-callbacks.md
new file mode 100644
index 000000000..c66ababa0
--- /dev/null
+++ b/docs/pt/docs/advanced/openapi-callbacks.md
@@ -0,0 +1,194 @@
+# Callbacks na OpenAPI
+
+Você poderia criar uma API com uma *operação de rota* que poderia acionar uma solicitação a uma *API externa* criada por outra pessoa (provavelmente o mesmo desenvolvedor que estaria *usando* sua API).
+
+O processo que acontece quando seu aplicativo de API chama a *API externa* é chamado de "callback". Porque o software que o desenvolvedor externo escreveu envia uma solicitação para sua API e então sua API *chama de volta*, enviando uma solicitação para uma *API externa* (que provavelmente foi criada pelo mesmo desenvolvedor).
+
+Nesse caso, você poderia querer documentar como essa API externa *deveria* ser. Que *operação de rota* ela deveria ter, que corpo ela deveria esperar, que resposta ela deveria retornar, etc.
+
+## Um aplicativo com callbacks
+
+Vamos ver tudo isso com um exemplo.
+
+Imagine que você tem um aplicativo que permite criar faturas.
+
+Essas faturas terão um `id`, `title` (opcional), `customer` e `total`.
+
+O usuário da sua API (um desenvolvedor externo) criará uma fatura em sua API com uma solicitação POST.
+
+Então sua API irá (vamos imaginar):
+
+* Enviar uma solicitação de pagamento para o desenvolvedor externo.
+* Coletar o dinheiro.
+* Enviar a notificação de volta para o usuário da API (o desenvolvedor externo).
+* Isso será feito enviando uma solicitação POST (de *sua API*) para alguma *API externa* fornecida por esse desenvolvedor externo (este é o "callback").
+
+## O aplicativo **FastAPI** normal
+
+Vamos primeiro ver como o aplicativo da API normal se pareceria antes de adicionar o callback.
+
+Ele terá uma *operação de rota* que receberá um corpo `Invoice`, e um parâmetro de consulta `callback_url` que conterá a URL para o callback.
+
+Essa parte é bastante normal, a maior parte do código provavelmente já é familiar para você:
+
+```Python hl_lines="9-13 36-53"
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
+```
+
+/// tip | Dica
+
+O parâmetro de consulta `callback_url` usa um tipo Pydantic Url.
+
+///
+
+A única coisa nova é o argumento `callbacks=invoices_callback_router.routes` no decorador da *operação de rota*. Veremos o que é isso a seguir.
+
+## Documentando o callback
+
+O código real do callback dependerá muito do seu próprio aplicativo de API.
+
+E provavelmente variará muito de um aplicativo para o outro.
+
+Poderia ser apenas uma ou duas linhas de código, como:
+
+```Python
+callback_url = "https://example.com/api/v1/invoices/events/"
+httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
+```
+
+Mas possivelmente a parte mais importante do callback é garantir que o usuário da sua API (o desenvolvedor externo) implemente a *API externa* corretamente, de acordo com os dados que *sua API* vai enviar no corpo da solicitação do callback, etc.
+
+Então, o que faremos a seguir é adicionar o código para documentar como essa *API externa* deve ser para receber o callback de *sua API*.
+
+A documentação aparecerá na interface do Swagger em `/docs` em sua API, e permitirá que os desenvolvedores externos saibam como construir a *API externa*.
+
+Esse exemplo não implementa o callback em si (que poderia ser apenas uma linha de código), apenas a parte da documentação.
+
+/// tip | Dica
+
+O callback real é apenas uma solicitação HTTP.
+
+Quando implementando o callback por você mesmo, você pode usar algo como HTTPX ou Requisições.
+
+///
+
+## Escrevendo o código de documentação do callback
+
+Esse código não será executado em seu aplicativo, nós só precisamos dele para *documentar* como essa *API externa* deveria ser.
+
+Mas, você já sabe como criar facilmente documentação automática para uma API com o **FastAPI**.
+
+Então vamos usar esse mesmo conhecimento para documentar como a *API externa* deveria ser... criando as *operações de rota* que a *API externa* deveria implementar (as que sua API irá chamar).
+
+/// tip | Dica
+
+Quando escrever o código para documentar um callback, pode ser útil imaginar que você é aquele *desenvolvedor externo*. E que você está atualmente implementando a *API externa*, não *sua API*.
+
+Adotar temporariamente esse ponto de vista (do *desenvolvedor externo*) pode ajudar a sentir que é mais óbvio onde colocar os parâmetros, o modelo Pydantic para o corpo, para a resposta, etc. para essa *API externa*.
+
+///
+
+### Criar um `APIRouter` para o callback
+
+Primeiramente crie um novo `APIRouter` que conterá um ou mais callbacks.
+
+```Python hl_lines="3 25"
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
+```
+
+### Crie a *operação de rota* do callback
+
+Para criar a *operação de rota* do callback, use o mesmo `APIRouter` que você criou acima.
+
+Ele deve parecer exatamente como uma *operação de rota* normal do FastAPI:
+
+* Ele provavelmente deveria ter uma declaração do corpo que deveria receber, por exemplo. `body: InvoiceEvent`.
+* E também deveria ter uma declaração de um código de status de resposta, por exemplo. `response_model=InvoiceEventReceived`.
+
+```Python hl_lines="16-18 21-22 28-32"
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
+```
+
+Há 2 diferenças principais de uma *operação de rota* normal:
+
+* Ela não necessita ter nenhum código real, porque seu aplicativo nunca chamará esse código. Ele é usado apenas para documentar a *API externa*. Então, a função poderia ter apenas `pass`.
+* A *rota* pode conter uma expressão OpenAPI 3 (veja mais abaixo) onde pode usar variáveis com parâmetros e partes da solicitação original enviada para *sua API*.
+
+### A expressão do caminho do callback
+
+A *rota* do callback pode ter uma expressão OpenAPI 3 que pode conter partes da solicitação original enviada para *sua API*.
+
+Nesse caso, é a `str`:
+
+```Python
+"{$callback_url}/invoices/{$request.body.id}"
+```
+
+Então, se o usuário da sua API (o desenvolvedor externo) enviar uma solicitação para *sua API* para:
+
+```
+https://yourapi.com/invoices/?callback_url=https://www.external.org/events
+```
+
+com um corpo JSON de:
+
+```JSON
+{
+ "id": "2expen51ve",
+ "customer": "Mr. Richie Rich",
+ "total": "9999"
+}
+```
+
+então *sua API* processará a fatura e, em algum momento posterior, enviará uma solicitação de callback para o `callback_url` (a *API externa*):
+
+```
+https://www.external.org/events/invoices/2expen51ve
+```
+
+com um corpo JSON contendo algo como:
+
+```JSON
+{
+ "description": "Payment celebration",
+ "paid": true
+}
+```
+
+e esperaria uma resposta daquela *API externa* com um corpo JSON como:
+
+```JSON
+{
+ "ok": true
+}
+```
+
+/// tip | Dica
+
+Perceba como a URL de callback usada contém a URL recebida como um parâmetro de consulta em `callback_url` (`https://www.external.org/events`) e também o `id` da fatura de dentro do corpo JSON (`2expen51ve`).
+
+///
+
+### Adicionar o roteador de callback
+
+Nesse ponto você tem a(s) *operação de rota de callback* necessária(s) (a(s) que o *desenvolvedor externo* deveria implementar na *API externa*) no roteador de callback que você criou acima.
+
+Agora use o parâmetro `callbacks` no decorador da *operação de rota de sua API* para passar o atributo `.routes` (que é na verdade apenas uma `list` de rotas/*operações de rota*) do roteador de callback que você criou acima:
+
+```Python hl_lines="35"
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
+```
+
+/// tip | Dica
+
+Perceba que você não está passando o roteador em si (`invoices_callback_router`) para `callback=`, mas o atributo `.routes`, como em `invoices_callback_router.routes`.
+
+///
+
+### Verifique a documentação
+
+Agora você pode iniciar seu aplicativo e ir para http://127.0.0.1:8000/docs.
+
+Você verá sua documentação incluindo uma seção "Callbacks" para sua *operação de rota* que mostra como a *API externa* deveria ser:
+
+
diff --git a/docs/pt/docs/advanced/openapi-webhooks.md b/docs/pt/docs/advanced/openapi-webhooks.md
index 2ccd0e819..344fe6371 100644
--- a/docs/pt/docs/advanced/openapi-webhooks.md
+++ b/docs/pt/docs/advanced/openapi-webhooks.md
@@ -22,7 +22,7 @@ Com o **FastAPI**, utilizando o OpenAPI, você pode definir os nomes destes webh
Isto pode facilitar bastante para os seus usuários **implementarem as APIs deles** para receber as requisições dos seus **webhooks**, eles podem inclusive ser capazes de gerar parte do código da API deles.
-/// info | "Informação"
+/// info | Informação
Webhooks estão disponíveis a partir do OpenAPI 3.1.0, e possui suporte do FastAPI a partir da versão `0.99.0`.
@@ -33,12 +33,12 @@ Webhooks estão disponíveis a partir do OpenAPI 3.1.0, e possui suporte do Fast
Quando você cria uma aplicação com o **FastAPI**, existe um atributo chamado `webhooks`, que você utilizar para defini-los da mesma maneira que você definiria as suas **operações de rotas**, utilizando por exemplo `@app.webhooks.post()`.
```Python hl_lines="9-13 36-53"
-{!../../../docs_src/openapi_webhooks/tutorial001.py!}
+{!../../docs_src/openapi_webhooks/tutorial001.py!}
```
Os webhooks que você define aparecerão no esquema do **OpenAPI** e na **página de documentação** gerada automaticamente.
-/// info | "Informação"
+/// info | Informação
O objeto `app.webhooks` é na verdade apenas um `APIRouter`, o mesmo tipo que você utilizaria ao estruturar a sua aplicação com diversos arquivos.
diff --git a/docs/pt/docs/advanced/path-operation-advanced-configuration.md b/docs/pt/docs/advanced/path-operation-advanced-configuration.md
new file mode 100644
index 000000000..04f5cc9a3
--- /dev/null
+++ b/docs/pt/docs/advanced/path-operation-advanced-configuration.md
@@ -0,0 +1,212 @@
+# Configuração Avançada da Operação de Rota
+
+## operationId do OpenAPI
+
+/// warning | Aviso
+
+Se você não é um "especialista" no OpenAPI, você provavelmente não precisa disso.
+
+///
+
+Você pode definir o `operationId` do OpenAPI que será utilizado na sua *operação de rota* com o parâmetro `operation_id`.
+
+Você precisa ter certeza que ele é único para cada operação.
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+
+### Utilizando o nome da *função de operação de rota* como o operationId
+
+Se você quiser utilizar o nome das funções da sua API como `operationId`s, você pode iterar sobre todos esses nomes e sobrescrever o `operationId` em cada *operação de rota* utilizando o `APIRoute.name` dela.
+
+Você deve fazer isso depois de adicionar todas as suas *operações de rota*.
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *}
+
+/// tip | Dica
+
+Se você chamar `app.openapi()` manualmente, os `operationId`s devem ser atualizados antes dessa chamada.
+
+///
+
+/// warning | Aviso
+
+Se você fizer isso, você tem que ter certeza de que cada uma das suas *funções de operação de rota* tem um nome único.
+
+Mesmo que elas estejam em módulos (arquivos Python) diferentes.
+
+///
+
+## Excluir do OpenAPI
+
+Para excluir uma *operação de rota* do esquema OpenAPI gerado (e por consequência, dos sistemas de documentação automáticos), utilize o parâmetro `include_in_schema` e defina ele como `False`:
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+
+## Descrição avançada a partir de docstring
+
+Você pode limitar as linhas utilizadas a partir de uma docstring de uma *função de operação de rota* para o OpenAPI.
+
+Adicionar um `\f` (um caractere de escape para alimentação de formulário) faz com que o **FastAPI** restrinja a saída utilizada pelo OpenAPI até esse ponto.
+
+Ele não será mostrado na documentação, mas outras ferramentas (como o Sphinx) serão capazes de utilizar o resto do texto.
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
+
+## Respostas Adicionais
+
+Você provavelmente já viu como declarar o `response_model` e `status_code` para uma *operação de rota*.
+
+Isso define os metadados sobre a resposta principal da *operação de rota*.
+
+Você também pode declarar respostas adicionais, com seus modelos, códigos de status, etc.
+
+Existe um capítulo inteiro da nossa documentação sobre isso, você pode ler em [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
+
+## Extras do OpenAPI
+
+Quando você declara uma *operação de rota* na sua aplicação, o **FastAPI** irá gerar os metadados relevantes da *operação de rota* automaticamente para serem incluídos no esquema do OpenAPI.
+
+/// note | Nota
+
+Na especificação do OpenAPI, isso é chamado de um Objeto de Operação.
+
+///
+
+Ele possui toda a informação sobre a *operação de rota* e é usado para gerar a documentação automaticamente.
+
+Ele inclui os atributos `tags`, `parameters`, `requestBody`, `responses`, etc.
+
+Esse esquema específico para uma *operação de rota* normalmente é gerado automaticamente pelo **FastAPI**, mas você também pode estender ele.
+
+/// tip | Dica
+
+Esse é um ponto de extensão de baixo nível.
+
+Caso você só precise declarar respostas adicionais, uma forma conveniente de fazer isso é com [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
+
+///
+
+Você pode estender o esquema do OpenAPI para uma *operação de rota* utilizando o parâmetro `openapi_extra`.
+
+### Extensões do OpenAPI
+
+Esse parâmetro `openapi_extra` pode ser útil, por exemplo, para declarar [Extensões do 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] *}
+
+Se você abrir os documentos criados automaticamente para a API, sua extensão aparecerá no final da *operação de rota* específica.
+
+
+
+E se você olhar o esquema OpenAPI resultante (na rota `/openapi.json` da sua API), você verá que a sua extensão também faz parte da *operação de rota* específica:
+
+```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"
+ }
+ }
+ }
+}
+```
+
+### Esquema de *operação de rota* do OpenAPI personalizado
+
+O dicionário em `openapi_extra` vai ter todos os seus níveis mesclados dentro do esquema OpenAPI gerado automaticamente para a *operação de rota*.
+
+Então, você pode adicionar dados extras para o esquema gerado automaticamente.
+
+Por exemplo, você poderia optar por ler e validar a requisição com seu próprio código, sem utilizar funcionalidades automatizadas do FastAPI com o Pydantic, mas você ainda pode quere definir a requisição no esquema OpenAPI.
+
+Você pode fazer isso com `openapi_extra`:
+
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36,39:40] *}
+
+Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo analisado como JSON, ele é lido diretamente como `bytes` e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma.
+
+De toda forma, nós podemos declarar o esquema esperado para o corpo da requisição.
+
+### Tipo de conteúdo do OpenAPI personalizado
+
+Utilizando esse mesmo truque, você pode utilizar um modelo Pydantic para definir o esquema JSON que é então incluído na seção do esquema personalizado do OpenAPI na *operação de rota*.
+
+E você pode fazer isso até mesmo quando os dados da requisição não seguem o formato JSON.
+
+Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao FastAPI de extrair o esquema JSON dos modelos Pydantic nem a validação automática do JSON. Na verdade, estamos declarando o tipo do conteúdo da requisição como YAML, em vez de JSON:
+
+//// tab | Pydantic v2
+
+```Python hl_lines="17-22 24"
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
+```
+
+////
+
+//// tab | Pydantic v1
+
+```Python hl_lines="17-22 24"
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
+```
+
+////
+
+/// info | Informação
+
+Na versão 1 do Pydantic, o método para obter o esquema JSON de um modelo é `Item.schema()`, na versão 2 do Pydantic, o método é `Item.model_json_schema()`
+
+///
+
+Entretanto, mesmo que não utilizemos a funcionalidade integrada por padrão, ainda estamos usando um modelo Pydantic para gerar um esquema JSON manualmente para os dados que queremos receber no formato YAML.
+
+Então utilizamos a requisição diretamente, e extraímos o corpo como `bytes`. Isso significa que o FastAPI não vai sequer tentar analisar o corpo da requisição como JSON.
+
+E então no nosso código, nós analisamos o conteúdo YAML diretamente, e estamos utilizando o mesmo modelo Pydantic para validar o conteúdo YAML:
+
+//// tab | Pydantic v2
+
+```Python hl_lines="26-33"
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
+```
+
+////
+
+//// tab | Pydantic v1
+
+```Python hl_lines="26-33"
+{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
+```
+
+////
+
+/// info | Informação
+
+Na versão 1 do Pydantic, o método para analisar e validar um objeto era `Item.parse_obj()`, na versão 2 do Pydantic, o método é chamado de `Item.model_validate()`.
+
+///
+
+///tip | Dica
+
+Aqui reutilizamos o mesmo modelo do Pydantic.
+
+Mas da mesma forma, nós poderíamos ter validado de alguma outra forma.
+
+///
diff --git a/docs/pt/docs/advanced/response-change-status-code.md b/docs/pt/docs/advanced/response-change-status-code.md
index 99695c831..2ac5eca18 100644
--- a/docs/pt/docs/advanced/response-change-status-code.md
+++ b/docs/pt/docs/advanced/response-change-status-code.md
@@ -21,7 +21,7 @@ Você pode declarar um parâmetro do tipo `Response` em sua *função de operaç
E então você pode definir o `status_code` neste objeto de retorno temporal.
```Python hl_lines="1 9 12"
-{!../../../docs_src/response_change_status_code/tutorial001.py!}
+{!../../docs_src/response_change_status_code/tutorial001.py!}
```
E então você pode retornar qualquer objeto que você precise, como você faria normalmente (um `dict`, um modelo de banco de dados, etc.).
diff --git a/docs/pt/docs/advanced/response-cookies.md b/docs/pt/docs/advanced/response-cookies.md
new file mode 100644
index 000000000..cd8f39db3
--- /dev/null
+++ b/docs/pt/docs/advanced/response-cookies.md
@@ -0,0 +1,55 @@
+# Cookies de Resposta
+
+## Usando um parâmetro `Response`
+
+Você pode declarar um parâmetro do tipo `Response` na sua *função de operação de rota*.
+
+E então você pode definir cookies nesse objeto de resposta *temporário*.
+
+```Python hl_lines="1 8-9"
+{!../../docs_src/response_cookies/tutorial002.py!}
+```
+
+Em seguida, você pode retornar qualquer objeto que precise, como normalmente faria (um `dict`, um modelo de banco de dados, etc).
+
+E se você declarou um `response_model`, ele ainda será usado para filtrar e converter o objeto que você retornou.
+
+**FastAPI** usará essa resposta *temporária* para extrair os cookies (também os cabeçalhos e código de status) e os colocará na resposta final que contém o valor que você retornou, filtrado por qualquer `response_model`.
+
+Você também pode declarar o parâmetro `Response` em dependências e definir cookies (e cabeçalhos) nelas.
+
+## Retornando uma `Response` diretamente
+
+Você também pode criar cookies ao retornar uma `Response` diretamente no seu código.
+
+Para fazer isso, você pode criar uma resposta como descrito em [Retornando uma Resposta Diretamente](response-directly.md){.internal-link target=_blank}.
+
+Então, defina os cookies nela e a retorne:
+
+```Python hl_lines="10-12"
+{!../../docs_src/response_cookies/tutorial001.py!}
+```
+
+/// tip | Dica
+
+Lembre-se de que se você retornar uma resposta diretamente em vez de usar o parâmetro `Response`, FastAPI a retornará diretamente.
+
+Portanto, você terá que garantir que seus dados sejam do tipo correto. E.g. será compatível com JSON se você estiver retornando um `JSONResponse`.
+
+E também que você não esteja enviando nenhum dado que deveria ter sido filtrado por um `response_model`.
+
+///
+
+### Mais informações
+
+/// note | Detalhes Técnicos
+
+Você também poderia usar `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`.
+
+**FastAPI** fornece as mesmas `starlette.responses` em `fastapi.responses` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
+
+E como o `Response` pode ser usado frequentemente para definir cabeçalhos e cookies, o **FastAPI** também o fornece em `fastapi.Response`.
+
+///
+
+Para ver todos os parâmetros e opções disponíveis, verifique a documentação no Starlette.
diff --git a/docs/pt/docs/advanced/response-directly.md b/docs/pt/docs/advanced/response-directly.md
new file mode 100644
index 000000000..fd2a0eef1
--- /dev/null
+++ b/docs/pt/docs/advanced/response-directly.md
@@ -0,0 +1,70 @@
+# Retornando uma Resposta Diretamente
+
+Quando você cria uma *operação de rota* no **FastAPI** você pode retornar qualquer dado nela: um dicionário (`dict`), uma lista (`list`), um modelo do Pydantic ou do seu banco de dados, etc.
+
+Por padrão, o **FastAPI** irá converter automaticamente o valor do retorno para JSON utilizando o `jsonable_encoder` explicado em [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+
+Então, por baixo dos panos, ele incluiria esses dados compatíveis com JSON (e.g. um `dict`) dentro de uma `JSONResponse` que é utilizada para enviar uma resposta para o cliente.
+
+Mas você pode retornar a `JSONResponse` diretamente nas suas *operações de rota*.
+
+Pode ser útil para retornar cabeçalhos e cookies personalizados, por exemplo.
+
+## Retornando uma `Response`
+
+Na verdade, você pode retornar qualquer `Response` ou subclasse dela.
+
+/// tip | Dica
+
+A própria `JSONResponse` é uma subclasse de `Response`.
+
+///
+
+E quando você retorna uma `Response`, o **FastAPI** vai repassá-la diretamente.
+
+Ele não vai fazer conversões de dados com modelos do Pydantic, não irá converter a tipagem de nenhum conteúdo, etc.
+
+Isso te dá bastante flexibilidade. Você pode retornar qualquer tipo de dado, sobrescrever qualquer declaração e validação nos dados, etc.
+
+## Utilizando o `jsonable_encoder` em uma `Response`
+
+Como o **FastAPI** não realiza nenhuma mudança na `Response` que você retorna, você precisa garantir que o conteúdo dela está pronto para uso.
+
+Por exemplo, você não pode colocar um modelo do Pydantic em uma `JSONResponse` sem antes convertê-lo em um `dict` com todos os tipos de dados (como `datetime`, `UUID`, etc) convertidos para tipos compatíveis com JSON.
+
+Para esses casos, você pode usar o `jsonable_encoder` para converter seus dados antes de repassá-los para a resposta:
+
+```Python hl_lines="6-7 21-22"
+{!../../docs_src/response_directly/tutorial001.py!}
+```
+
+/// note | Detalhes Técnicos
+
+Você também pode utilizar `from starlette.responses import JSONResponse`.
+
+**FastAPI** utiliza a mesma `starlette.responses` como `fastapi.responses` apenas como uma conveniência para você, desenvolvedor. Mas maior parte das respostas disponíveis vem diretamente do Starlette.
+
+///
+
+## Retornando uma `Response`
+
+O exemplo acima mostra todas as partes que você precisa, mas ainda não é muito útil, já que você poderia ter retornado o `item` diretamente, e o **FastAPI** colocaria em uma `JSONResponse` para você, convertendo em um `dict`, etc. Tudo isso por padrão.
+
+Agora, vamos ver como você pode usar isso para retornar uma resposta personalizada.
+
+Vamos dizer quer retornar uma resposta XML.
+
+Você pode colocar o seu conteúdo XML em uma string, colocar em uma `Response`, e retorná-lo:
+
+```Python hl_lines="1 18"
+{!../../docs_src/response_directly/tutorial002.py!}
+```
+
+## Notas
+
+Quando você retorna uma `Response` diretamente os dados não são validados, convertidos (serializados) ou documentados automaticamente.
+
+Mas você ainda pode documentar como descrito em [Retornos Adicionais no OpenAPI
+](additional-responses.md){.internal-link target=_blank}.
+
+Você pode ver nas próximas seções como usar/declarar essas `Responses` customizadas enquanto mantém a conversão e documentação automática dos dados.
diff --git a/docs/pt/docs/advanced/response-headers.md b/docs/pt/docs/advanced/response-headers.md
new file mode 100644
index 000000000..98a7e0b6d
--- /dev/null
+++ b/docs/pt/docs/advanced/response-headers.md
@@ -0,0 +1,45 @@
+# Cabeçalhos de resposta
+
+## Usando um parâmetro `Response`
+
+Você pode declarar um parâmetro do tipo `Response` na sua *função de operação de rota* (assim como você pode fazer para cookies).
+
+Então você pode definir os cabeçalhos nesse objeto de resposta *temporário*.
+
+```Python hl_lines="1 7-8"
+{!../../docs_src/response_headers/tutorial002.py!}
+```
+
+Em seguida você pode retornar qualquer objeto que precisar, da maneira que faria normalmente (um `dict`, um modelo de banco de dados, etc.).
+
+Se você declarou um `response_model`, ele ainda será utilizado para filtrar e converter o objeto que você retornou.
+
+**FastAPI** usará essa resposta *temporária* para extrair os cabeçalhos (cookies e código de status também) e os colocará na resposta final que contém o valor que você retornou, filtrado por qualquer `response_model`.
+
+Você também pode declarar o parâmetro `Response` em dependências e definir cabeçalhos (e cookies) nelas.
+
+## Retornar uma `Response` diretamente
+
+Você também pode adicionar cabeçalhos quando retornar uma `Response` diretamente.
+
+Crie uma resposta conforme descrito em [Retornar uma resposta diretamente](response-directly.md){.internal-link target=_blank} e passe os cabeçalhos como um parâmetro adicional:
+
+```Python hl_lines="10-12"
+{!../../docs_src/response_headers/tutorial001.py!}
+```
+
+/// note | Detalhes técnicos
+
+Você também pode usar `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`.
+
+**FastAPI** fornece as mesmas `starlette.responses` como `fastapi.responses` apenas como uma conveniência para você, desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
+
+E como a `Response` pode ser usada frequentemente para definir cabeçalhos e cookies, **FastAPI** também a fornece em `fastapi.Response`.
+
+///
+
+## Cabeçalhos personalizados
+
+Tenha em mente que cabeçalhos personalizados proprietários podem ser adicionados usando o prefixo 'X-'.
+
+Porém, se voce tiver cabeçalhos personalizados que deseja que um cliente no navegador possa ver, você precisa adicioná-los às suas configurações de CORS (saiba mais em [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando o parâmetro `expose_headers` descrito na documentação de CORS do Starlette.
diff --git a/docs/pt/docs/advanced/security/http-basic-auth.md b/docs/pt/docs/advanced/security/http-basic-auth.md
new file mode 100644
index 000000000..28c718f64
--- /dev/null
+++ b/docs/pt/docs/advanced/security/http-basic-auth.md
@@ -0,0 +1,192 @@
+# HTTP Basic Auth
+
+Para os casos mais simples, você pode utilizar o HTTP Basic Auth.
+
+No HTTP Basic Auth, a aplicação espera um cabeçalho que contém um usuário e uma senha.
+
+Caso ela não receba, ela retorna um erro HTTP 401 "Unauthorized" (*Não Autorizado*).
+
+E retorna um cabeçalho `WWW-Authenticate` com o valor `Basic`, e um parâmetro opcional `realm`.
+
+Isso sinaliza ao navegador para mostrar o prompt integrado para um usuário e senha.
+
+Então, quando você digitar o usuário e senha, o navegador os envia automaticamente no cabeçalho.
+
+## HTTP Basic Auth Simples
+
+* Importe `HTTPBasic` e `HTTPBasicCredentials`.
+* Crie um "esquema `security`" utilizando `HTTPBasic`.
+* Utilize o `security` com uma dependência em sua *operação de rota*.
+* Isso retorna um objeto do tipo `HTTPBasicCredentials`:
+ * Isto contém o `username` e o `password` enviado.
+
+//// tab | Python 3.9+
+
+```Python hl_lines="4 8 12"
+{!> ../../docs_src/security/tutorial006_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="2 7 11"
+{!> ../../docs_src/security/tutorial006_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="2 6 10"
+{!> ../../docs_src/security/tutorial006.py!}
+```
+
+////
+
+Quando você tentar abrir a URL pela primeira vez (ou clicar no botão "Executar" nos documentos) o navegador vai pedir pelo seu usuário e senha:
+
+
+
+## Verifique o usuário
+
+Aqui está um exemplo mais completo.
+
+Utilize uma dependência para verificar se o usuário e a senha estão corretos.
+
+Para isso, utilize o módulo padrão do Python `secrets` para verificar o usuário e senha.
+
+O `secrets.compare_digest()` necessita receber `bytes` ou `str` que possuem apenas caracteres ASCII (os em inglês). Isso significa que não funcionaria com caracteres como o `á`, como em `Sebastián`.
+
+Para lidar com isso, primeiramente nós convertemos o `username` e o `password` para `bytes`, codificando-os com UTF-8.
+
+Então nós podemos utilizar o `secrets.compare_digest()` para garantir que o `credentials.username` é `"stanleyjobson"`, e que o `credentials.password` é `"swordfish"`.
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1 12-24"
+{!> ../../docs_src/security/tutorial007_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 12-24"
+{!> ../../docs_src/security/tutorial007_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="1 11-21"
+{!> ../../docs_src/security/tutorial007.py!}
+```
+
+////
+
+Isso seria parecido com:
+
+```Python
+if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
+ # Return some error
+ ...
+```
+
+Porém, ao utilizar o `secrets.compare_digest()`, isso estará seguro contra um tipo de ataque chamado "timing attacks" (ataques de temporização).
+
+### Ataques de Temporização
+
+Mas o que é um "timing attack" (ataque de temporização)?
+
+Vamos imaginar que alguns invasores estão tentando adivinhar o usuário e a senha.
+
+E eles enviam uma requisição com um usuário `johndoe` e uma senha `love123`.
+
+Então o código Python em sua aplicação seria equivalente a algo como:
+
+```Python
+if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+Mas no exato momento que o Python compara o primeiro `j` em `johndoe` contra o primeiro `s` em `stanleyjobson`, ele retornará `False`, porque ele já sabe que aquelas duas strings não são a mesma, pensando que "não existe a necessidade de desperdiçar mais poder computacional comparando o resto das letras". E a sua aplicação dirá "Usuário ou senha incorretos".
+
+Então os invasores vão tentar com o usuário `stanleyjobsox` e a senha `love123`.
+
+E a sua aplicação faz algo como:
+
+```Python
+if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+O Python terá que comparar todo o `stanleyjobso` tanto em `stanleyjobsox` como em `stanleyjobson` antes de perceber que as strings não são a mesma. Então isso levará alguns microssegundos a mais para retornar "Usuário ou senha incorretos".
+
+#### O tempo para responder ajuda os invasores
+
+Neste ponto, ao perceber que o servidor demorou alguns microssegundos a mais para enviar o retorno "Usuário ou senha incorretos", os invasores irão saber que eles acertaram _alguma coisa_, algumas das letras iniciais estavam certas.
+
+E eles podem tentar de novo sabendo que provavelmente é algo mais parecido com `stanleyjobsox` do que com `johndoe`.
+
+#### Um ataque "profissional"
+
+Claro, os invasores não tentariam tudo isso de forma manual, eles escreveriam um programa para fazer isso, possivelmente com milhares ou milhões de testes por segundo. E obteriam apenas uma letra a mais por vez.
+
+Mas fazendo isso, em alguns minutos ou horas os invasores teriam adivinhado o usuário e senha corretos, com a "ajuda" da nossa aplicação, apenas usando o tempo levado para responder.
+
+#### Corrija com o `secrets.compare_digest()`
+
+Mas em nosso código já estamos utilizando o `secrets.compare_digest()`.
+
+Resumindo, levará o mesmo tempo para comparar `stanleyjobsox` com `stanleyjobson` do que comparar `johndoe` com `stanleyjobson`. E o mesmo para a senha.
+
+Deste modo, ao utilizar `secrets.compare_digest()` no código de sua aplicação, ela estará a salvo contra toda essa gama de ataques de segurança.
+
+
+### Retorne o erro
+
+Após detectar que as credenciais estão incorretas, retorne um `HTTPException` com o status 401 (o mesmo retornado quando nenhuma credencial foi informada) e adicione o cabeçalho `WWW-Authenticate` para fazer com que o navegador mostre o prompt de login novamente:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="26-30"
+{!> ../../docs_src/security/tutorial007_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="26-30"
+{!> ../../docs_src/security/tutorial007_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="23-27"
+{!> ../../docs_src/security/tutorial007.py!}
+```
+
+////
diff --git a/docs/pt/docs/advanced/security/index.md b/docs/pt/docs/advanced/security/index.md
index ae63f1c96..6c7becb67 100644
--- a/docs/pt/docs/advanced/security/index.md
+++ b/docs/pt/docs/advanced/security/index.md
@@ -4,7 +4,7 @@
Existem algumas funcionalidades adicionais para lidar com segurança além das cobertas em [Tutorial - Guia de Usuário: Segurança](../../tutorial/security/index.md){.internal-link target=_blank}.
-/// tip | "Dica"
+/// tip | Dica
As próximas seções **não são necessariamente "avançadas"**.
diff --git a/docs/pt/docs/advanced/security/oauth2-scopes.md b/docs/pt/docs/advanced/security/oauth2-scopes.md
new file mode 100644
index 000000000..49fb75944
--- /dev/null
+++ b/docs/pt/docs/advanced/security/oauth2-scopes.md
@@ -0,0 +1,786 @@
+# Escopos OAuth2
+
+Você pode utilizar escopos do OAuth2 diretamente com o **FastAPI**, eles são integrados para funcionar perfeitamente.
+
+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.
+
+Toda vez que você "se autentica com" Facebook, Google, GitHub, Microsoft, 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**.
+
+/// warning | Aviso
+
+Isso é uma seção mais ou menos avançada. Se você está apenas começando, você pode pular.
+
+Você não necessariamente precisa de escopos do OAuth2, e você pode lidar com autenticação e autorização da maneira que você achar melhor.
+
+Mas o OAuth2 com escopos pode ser integrado de maneira fácil em sua API (com OpenAPI) e a sua documentação de API.
+
+No entando, você ainda aplica estes escopos, ou qualquer outro requisito de segurança/autorização, conforme necessário, em seu código.
+
+Em muitos casos, OAuth2 com escopos pode ser um exagero.
+
+Mas se você sabe que precisa, ou está curioso, continue lendo.
+
+///
+
+## Escopos OAuth2 e OpenAPI
+
+A especificação OAuth2 define "escopos" como uma lista de strings separadas por espaços.
+
+O conteúdo de cada uma dessas strings pode ter qualquer formato, mas não devem possuir espaços.
+
+Estes escopos representam "permissões".
+
+No OpenAPI (e.g. os documentos da API), você pode definir "esquemas de segurança".
+
+Quando um desses esquemas de segurança utiliza OAuth2, você pode também declarar e utilizar escopos.
+
+Cada "escopo" é apenas uma string (sem espaços).
+
+Eles são normalmente utilizados para declarar permissões de segurança específicas, como por exemplo:
+
+* `users:read` or `users:write` são exemplos comuns.
+* `instagram_basic` é utilizado pelo Facebook / Instagram.
+* `https://www.googleapis.com/auth/drive` é utilizado pelo Google.
+
+/// info | Informação
+
+No OAuth2, um "escopo" é apenas uma string que declara uma permissão específica necessária.
+
+Não importa se ela contém outros caracteres como `:` ou se ela é uma URL.
+
+Estes detalhes são específicos da implementação.
+
+Para o OAuth2, eles são apenas strings.
+
+///
+
+## Visão global
+
+Primeiro, vamos olhar rapidamente as partes que mudam dos exemplos do **Tutorial - Guia de Usuário** para [OAuth2 com Senha (e hash), Bearer com tokens JWT](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Agora utilizando escopos OAuth2:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="5 9 13 47 65 106 108-116 122-125 129-135 140 156"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="2 5 9 13 48 66 107 109-117 123-126 130-136 141 157"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="4 8 12 46 64 105 107-115 121-124 128-134 139 155"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+Agora vamos revisar essas mudanças passo a passo.
+
+## Esquema de segurança OAuth2
+
+A primeira mudança é que agora nós estamos declarando o esquema de segurança OAuth2 com dois escopos disponíveis, `me` e `items`.
+
+O parâmetro `scopes` recebe um `dict` contendo cada escopo como chave e a descrição como valor:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="63-66"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="63-66"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="64-67"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="62-65"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="63-66"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="63-66"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+Pelo motivo de estarmos declarando estes escopos, eles aparecerão nos documentos da API quando você se autenticar/autorizar.
+
+E você poderá selecionar quais escopos você deseja dar acesso: `me` e `items`.
+
+Este é o mesmo mecanismo utilizado quando você adiciona permissões enquanto se autentica com o Facebook, Google, GitHub, etc:
+
+
+
+## Token JWT com escopos
+
+Agora, modifique o *caminho de rota* para retornar os escopos solicitados.
+
+Nós ainda estamos utilizando o mesmo `OAuth2PasswordRequestForm`. Ele inclui a propriedade `scopes` com uma `list` de `str`, com cada escopo que ele recebeu na requisição.
+
+E nós retornamos os escopos como parte do token JWT.
+
+/// danger | Cuidado
+
+Para manter as coisas simples, aqui nós estamos apenas adicionando os escopos recebidos diretamente ao token.
+
+Porém em sua aplicação, por segurança, você deve garantir que você apenas adiciona os escopos que o usuário possui permissão de fato, ou aqueles que você predefiniu.
+
+///
+
+//// tab | Python 3.10+
+
+```Python hl_lines="156"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="156"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="157"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="155"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="156"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="156"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+## Declare escopos em *operações de rota* e dependências
+
+Agora nós declaramos que a *operação de rota* para `/users/me/items/` exige o escopo `items`.
+
+Para isso, nós importamos e utilizamos `Security` de `fastapi`.
+
+Você pode utilizar `Security` para declarar dependências (assim como `Depends`), porém o `Security` também recebe o parâmetros `scopes` com uma lista de escopos (strings).
+
+Neste caso, nós passamos a função `get_current_active_user` como dependência para `Security` (da mesma forma que nós faríamos com `Depends`).
+
+Mas nós também passamos uma `list` de escopos, neste caso com apenas um escopo: `items` (poderia ter mais).
+
+E a função de dependência `get_current_active_user` também pode declarar subdependências, não apenas com `Depends`, mas também com `Security`. Ao declarar sua própria função de subdependência (`get_current_user`), e mais requisitos de escopo.
+
+Neste caso, ele requer o escopo `me` (poderia requerer mais de um escopo).
+
+/// note | Nota
+
+Você não necessariamente precisa adicionar diferentes escopos em diferentes lugares.
+
+Nós estamos fazendo isso aqui para demonstrar como o **FastAPI** lida com escopos declarados em diferentes níveis.
+
+///
+
+//// tab | Python 3.10+
+
+```Python hl_lines="5 140 171"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="5 140 171"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="5 141 172"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="4 139 168"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="5 140 169"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="5 140 169"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+/// info | Informações Técnicas
+
+`Security` é na verdade uma subclasse de `Depends`, e ele possui apenas um parâmetro extra que veremos depois.
+
+Porém ao utilizar `Security` no lugar de `Depends`, o **FastAPI** saberá que ele pode declarar escopos de segurança, utilizá-los internamente, e documentar a API com o OpenAPI.
+
+Mas quando você importa `Query`, `Path`, `Depends`, `Security` entre outros de `fastapi`, eles são na verdade funções que retornam classes especiais.
+
+///
+
+## Utilize `SecurityScopes`
+
+Agora atualize a dependência `get_current_user`.
+
+Este é o usado pelas dependências acima.
+
+Aqui é onde estamos utilizando o mesmo esquema OAuth2 que nós declaramos antes, declarando-o como uma dependência: `oauth2_scheme`.
+
+Porque esta função de dependência não possui nenhum requerimento de escopo, nós podemos utilizar `Depends` com o `oauth2_scheme`. Nós não precisamos utilizar `Security` quando nós não precisamos especificar escopos de segurança.
+
+Nós também declaramos um parâmetro especial do tipo `SecurityScopes`, importado de `fastapi.security`.
+
+A classe `SecurityScopes` é semelhante à classe `Request` (`Request` foi utilizada para obter o objeto da requisição diretamente).
+
+//// tab | Python 3.10+
+
+```Python hl_lines="9 106"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="9 106"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="9 107"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="8 105"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="9 106"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="9 106"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+## Utilize os `scopes`
+
+O parâmetro `security_scopes` será do tipo `SecurityScopes`.
+
+Ele terá a propriedade `scopes` com uma lista contendo todos os escopos requeridos por ele e todas as dependências que utilizam ele como uma subdependência. Isso significa, todos os "dependentes"... pode soar meio confuso, e isso será explicado novamente mais adiante.
+
+O objeto `security_scopes` (da classe `SecurityScopes`) também oferece um atributo `scope_str` com uma única string, contendo os escopos separados por espaços (nós vamos utilizar isso).
+
+Nós criamos uma `HTTPException` que nós podemos reutilizar (`raise`) mais tarde em diversos lugares.
+
+Nesta exceção, nós incluímos os escopos necessários (se houver algum) como uma string separada por espaços (utilizando `scope_str`). Nós colocamos esta string contendo os escopos no cabeçalho `WWW-Authenticate` (isso é parte da especificação).
+
+//// tab | Python 3.10+
+
+```Python hl_lines="106 108-116"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="106 108-116"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="107 109-117"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="105 107-115"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="106 108-116"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="106 108-116"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+## Verifique o `username` e o formato dos dados
+
+Nós verificamos que nós obtemos um `username`, e extraímos os escopos.
+
+E depois nós validamos esse dado com o modelo Pydantic (capturando a exceção `ValidationError`), e se nós obtemos um erro ao ler o token JWT ou validando os dados com o Pydantic, nós levantamos a exceção `HTTPException` que criamos anteriormente.
+
+Para isso, nós atualizamos o modelo Pydantic `TokenData` com a nova propriedade `scopes`.
+
+Ao validar os dados com o Pydantic nós podemos garantir que temos, por exemplo, exatamente uma `list` de `str` com os escopos e uma `str` com o `username`.
+
+No lugar de, por exemplo, um `dict`, ou alguma outra coisa, que poderia quebrar a aplicação em algum lugar mais tarde, tornando isso um risco de segurança.
+
+Nós também verificamos que nós temos um usuário com o "*username*", e caso contrário, nós levantamos a mesma exceção que criamos anteriormente.
+
+//// tab | Python 3.10+
+
+```Python hl_lines="47 117-128"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="47 117-128"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="48 118-129"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="46 116-127"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="47 117-128"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="47 117-128"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+## Verifique os `scopes`
+
+Nós verificamos agora que todos os escopos necessários, por essa dependência e todos os dependentes (incluindo as *operações de rota*) estão incluídas nos escopos fornecidos pelo token recebido, caso contrário, levantamos uma `HTTPException`.
+
+Para isso, nós utilizamos `security_scopes.scopes`, que contém uma `list` com todos esses escopos como uma `str`.
+
+//// tab | Python 3.10+
+
+```Python hl_lines="129-135"
+{!> ../../docs_src/security/tutorial005_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="129-135"
+{!> ../../docs_src/security/tutorial005_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="130-136"
+{!> ../../docs_src/security/tutorial005_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="128-134"
+{!> ../../docs_src/security/tutorial005_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="129-135"
+{!> ../../docs_src/security/tutorial005_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="129-135"
+{!> ../../docs_src/security/tutorial005.py!}
+```
+
+////
+
+## Árvore de dependência e escopos
+
+Vamos rever novamente essa árvore de dependência e os escopos.
+
+Como a dependência `get_current_active_user` possui uma subdependência em `get_current_user`, o escopo `"me"` declarado em `get_current_active_user` será incluído na lista de escopos necessários em `security_scopes.scopes` passado para `get_current_user`.
+
+A própria *operação de rota* também declara o escopo, `"items"`, então ele também estará na lista de `security_scopes.scopes` passado para o `get_current_user`.
+
+Aqui está como a hierarquia de dependências e escopos parecem:
+
+* A *operação de rota* `read_own_items` possui:
+ * Escopos necessários `["items"]` com a dependência:
+ * `get_current_active_user`:
+ * A função de dependência `get_current_active_user` possui:
+ * Escopos necessários `["me"]` com a dependência:
+ * `get_current_user`:
+ * A função de dependência `get_current_user` possui:
+ * Nenhum escopo necessário.
+ * Uma dependência utilizando `oauth2_scheme`.
+ * Um parâmetro `security_scopes` do tipo `SecurityScopes`:
+ * Este parâmetro `security_scopes` possui uma propriedade `scopes` com uma `list` contendo todos estes escopos declarados acima, então:
+ * `security_scopes.scopes` terá `["me", "items"]` para a *operação de rota* `read_own_items`.
+ * `security_scopes.scopes` terá `["me"]` para a *operação de rota* `read_users_me`, porque ela declarou na dependência `get_current_active_user`.
+ * `security_scopes.scopes` terá `[]` (nada) para a *operação de rota* `read_system_status`, porque ele não declarou nenhum `Security` com `scopes`, e sua dependência, `get_current_user`, não declara nenhum `scopes` também.
+
+/// tip | Dica
+
+A coisa importante e "mágica" aqui é que `get_current_user` terá diferentes listas de `scopes` para validar para cada *operação de rota*.
+
+Tudo depende dos `scopes` declarados em cada *operação de rota* e cada dependência da árvore de dependências para aquela *operação de rota* específica.
+
+///
+
+## Mais detalhes sobre `SecurityScopes`
+
+Você pode utilizar `SecurityScopes` em qualquer lugar, e em diversos lugares. Ele não precisa estar na dependência "raiz".
+
+Ele sempre terá os escopos de segurança declarados nas dependências atuais de `Security` e todos os dependentes para **aquela** *operação de rota* **específica** e **aquela** árvore de dependência **específica**.
+
+Porque o `SecurityScopes` terá todos os escopos declarados por dependentes, você pode utilizá-lo para verificar se o token possui os escopos necessários em uma função de dependência central, e depois declarar diferentes requisitos de escopo em diferentes *operações de rota*.
+
+Todos eles serão validados independentemente para cada *operação de rota*.
+
+## Verifique
+
+Se você abrir os documentos da API, você pode antenticar e especificar quais escopos você quer autorizar.
+
+
+
+Se você não selecionar nenhum escopo, você terá "autenticado", mas quando você tentar acessar `/users/me/` ou `/users/me/items/`, você vai obter um erro dizendo que você não possui as permissões necessárias. Você ainda poderá acessar `/status/`.
+
+E se você selecionar o escopo `me`, mas não o escopo `items`, você poderá acessar `/users/me/`, mas não `/users/me/items/`.
+
+Isso é o que aconteceria se uma aplicação terceira que tentou acessar uma dessas *operações de rota* com um token fornecido por um usuário, dependendo de quantas permissões o usuário forneceu para a aplicação.
+
+## Sobre integrações de terceiros
+
+Neste exemplos nós estamos utilizando o fluxo de senha do OAuth2.
+
+Isso é apropriado quando nós estamos autenticando em nossa própria aplicação, provavelmente com o nosso próprio "*frontend*".
+
+Porque nós podemos confiar nele para receber o `username` e o `password`, pois nós controlamos isso.
+
+Mas se nós estamos construindo uma aplicação OAuth2 que outros poderiam conectar (i.e., se você está construindo um provedor de autenticação equivalente ao Facebook, Google, GitHub, etc.) você deveria utilizar um dos outros fluxos.
+
+O mais comum é o fluxo implícito.
+
+O mais seguro é o fluxo de código, mas ele é mais complexo para implementar, pois ele necessita mais passos. Como ele é mais complexo, muitos provedores terminam sugerindo o fluxo implícito.
+
+/// note | Nota
+
+É comum que cada provedor de autenticação nomeie os seus fluxos de forma diferente, para torná-lo parte de sua marca.
+
+Mas no final, eles estão implementando o mesmo padrão OAuth2.
+
+///
+
+O **FastAPI** inclui utilitários para todos esses fluxos de autenticação OAuth2 em `fastapi.security.oauth2`.
+
+## `Security` em docoradores de `dependências`
+
+Da mesma forma que você pode definir uma `list` de `Depends` no parâmetro de `dependencias` do decorador (como explicado em [Dependências em decoradores de operações de rota](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), você também pode utilizar `Security` com escopos lá.
diff --git a/docs/pt/docs/advanced/settings.md b/docs/pt/docs/advanced/settings.md
index db2b4c9cc..d32b70ed4 100644
--- a/docs/pt/docs/advanced/settings.md
+++ b/docs/pt/docs/advanced/settings.md
@@ -181,7 +181,7 @@ Você pode utilizar todas as ferramentas e funcionalidades de validação que s
//// tab | Pydantic v2
```Python hl_lines="2 5-8 11"
-{!> ../../../docs_src/settings/tutorial001.py!}
+{!> ../../docs_src/settings/tutorial001.py!}
```
////
@@ -195,7 +195,7 @@ Na versão 1 do Pydantic você importaria `BaseSettings` diretamente do módulo
///
```Python hl_lines="2 5-8 11"
-{!> ../../../docs_src/settings/tutorial001_pv1.py!}
+{!> ../../docs_src/settings/tutorial001_pv1.py!}
```
////
@@ -215,7 +215,7 @@ Depois ele irá converter e validar os dados. Assim, quando você utilizar aquel
Depois, Você pode utilizar o novo objeto `settings` na sua aplicação:
```Python hl_lines="18-20"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
### Executando o servidor
@@ -251,13 +251,13 @@ Você também pode incluir essas configurações em um arquivo de um módulo sep
Por exemplo, você pode adicionar um arquivo `config.py` com:
```Python
-{!../../../docs_src/settings/app01/config.py!}
+{!../../docs_src/settings/app01/config.py!}
```
E utilizar essa configuração em `main.py`:
```Python hl_lines="3 11-13"
-{!../../../docs_src/settings/app01/main.py!}
+{!../../docs_src/settings/app01/main.py!}
```
/// dica
@@ -277,7 +277,7 @@ Isso é especialmente útil durante os testes, já que é bastante simples sobre
Baseando-se no exemplo anterior, seu arquivo `config.py` seria parecido com isso:
```Python hl_lines="10"
-{!../../../docs_src/settings/app02/config.py!}
+{!../../docs_src/settings/app02/config.py!}
```
Perceba que dessa vez não criamos uma instância padrão `settings = Settings()`.
@@ -289,7 +289,7 @@ Agora criamos a dependência que retorna um novo objeto `config.Settings()`.
//// tab | Python 3.9+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -297,7 +297,7 @@ Agora criamos a dependência que retorna um novo objeto `config.Settings()`.
//// tab | Python 3.8+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
@@ -311,7 +311,7 @@ Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="5 11-12"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -329,7 +329,7 @@ E então podemos declarar essas configurações como uma dependência na funçã
//// tab | Python 3.9+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -337,7 +337,7 @@ E então podemos declarar essas configurações como uma dependência na funçã
//// tab | Python 3.8+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
@@ -351,7 +351,7 @@ Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="16 18-20"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -361,7 +361,7 @@ Utilize a versão com `Annotated` se possível.
Então seria muito fácil fornecer uma configuração diferente durante a execução dos testes sobrescrevendo a dependência de `get_settings`:
```Python hl_lines="9-10 13 21"
-{!../../../docs_src/settings/app02/test_main.py!}
+{!../../docs_src/settings/app02/test_main.py!}
```
Na sobrescrita da dependência, definimos um novo valor para `admin_email` quando instanciamos um novo objeto `Settings`, e então retornamos esse novo objeto.
@@ -406,7 +406,7 @@ E então adicionar o seguinte código em `config.py`:
//// tab | Pydantic v2
```Python hl_lines="9"
-{!> ../../../docs_src/settings/app03_an/config.py!}
+{!> ../../docs_src/settings/app03_an/config.py!}
```
/// dica
@@ -420,7 +420,7 @@ O atributo `model_config` é usado apenas para configuração do Pydantic. Você
//// tab | Pydantic v1
```Python hl_lines="9-10"
-{!> ../../../docs_src/settings/app03_an/config_pv1.py!}
+{!> ../../docs_src/settings/app03_an/config_pv1.py!}
```
/// dica
@@ -465,7 +465,7 @@ Mas como estamos utilizando o decorador `@lru_cache` acima, o objeto `Settings`
//// tab | Python 3.9+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an_py39/main.py!}
+{!> ../../docs_src/settings/app03_an_py39/main.py!}
```
////
@@ -473,7 +473,7 @@ Mas como estamos utilizando o decorador `@lru_cache` acima, o objeto `Settings`
//// tab | Python 3.8+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an/main.py!}
+{!> ../../docs_src/settings/app03_an/main.py!}
```
////
@@ -487,7 +487,7 @@ Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="1 10"
-{!> ../../../docs_src/settings/app03/main.py!}
+{!> ../../docs_src/settings/app03/main.py!}
```
////
diff --git a/docs/pt/docs/advanced/sub-applications.md b/docs/pt/docs/advanced/sub-applications.md
index 8149edc5a..7f0381cc2 100644
--- a/docs/pt/docs/advanced/sub-applications.md
+++ b/docs/pt/docs/advanced/sub-applications.md
@@ -11,7 +11,7 @@ Se você precisar ter duas aplicações FastAPI independentes, cada uma com seu
Primeiro, crie a aplicação principal, de nível superior, **FastAPI**, e suas *operações de rota*:
```Python hl_lines="3 6-8"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### Sub-aplicação
@@ -21,7 +21,7 @@ Em seguida, crie sua sub-aplicação e suas *operações de rota*.
Essa sub-aplicação é apenas outra aplicação FastAPI padrão, mas esta é a que será "montada":
```Python hl_lines="11 14-16"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### Monte a sub-aplicação
@@ -31,7 +31,7 @@ Na sua aplicação de nível superior, `app`, monte a sub-aplicação, `subapi`.
Neste caso, ela será montada no caminho `/subapi`:
```Python hl_lines="11 19"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### Verifique a documentação automática da API
diff --git a/docs/pt/docs/advanced/templates.md b/docs/pt/docs/advanced/templates.md
index 6d231b3c2..2314fed91 100644
--- a/docs/pt/docs/advanced/templates.md
+++ b/docs/pt/docs/advanced/templates.md
@@ -26,7 +26,7 @@ $ pip install jinja2
* Use o `template` que você criou para renderizar e retornar uma `TemplateResponse`, passe o nome do template, o request object, e um "context" dict com pares chave-valor a serem usados dentro do template do Jinja2.
```Python hl_lines="4 11 15-18"
-{!../../../docs_src/templates/tutorial001.py!}
+{!../../docs_src/templates/tutorial001.py!}
```
/// note
@@ -37,13 +37,13 @@ Além disso, em versões anteriores, o objeto `request` era passado como parte d
///
-/// tip | "Dica"
+/// tip | Dica
Ao declarar `response_class=HTMLResponse`, a documentação entenderá que a resposta será HTML.
///
-/// note | "Detalhes Técnicos"
+/// note | Detalhes Técnicos
Você também poderia usar `from starlette.templating import Jinja2Templates`.
@@ -56,7 +56,7 @@ Você também poderia usar `from starlette.templating import Jinja2Templates`.
Então você pode escrever um template em `templates/item.html`, por exemplo:
```jinja hl_lines="7"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
### Interpolação de Valores no Template
@@ -110,13 +110,13 @@ Por exemplo, com um ID de `42`, isso renderizará:
Você também pode usar `url_for()` dentro do template e usá-lo, por examplo, com o `StaticFiles` que você montou com o `name="static"`.
```jinja hl_lines="4"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
Neste exemplo, ele seria vinculado a um arquivo CSS em `static/styles.css` com:
```CSS hl_lines="4"
-{!../../../docs_src/templates/static/styles.css!}
+{!../../docs_src/templates/static/styles.css!}
```
E como você está usando `StaticFiles`, este arquivo CSS será automaticamente servido pela sua aplicação FastAPI na URL `/static/styles.css`.
diff --git a/docs/pt/docs/advanced/testing-dependencies.md b/docs/pt/docs/advanced/testing-dependencies.md
index 747dd7d06..94594e7e9 100644
--- a/docs/pt/docs/advanced/testing-dependencies.md
+++ b/docs/pt/docs/advanced/testing-dependencies.md
@@ -31,7 +31,7 @@ E então o **FastAPI** chamará a sobreposição no lugar da dependência origin
//// tab | Python 3.10+
```Python hl_lines="26-27 30"
-{!> ../../../docs_src/dependency_testing/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an_py310.py!}
```
////
@@ -39,7 +39,7 @@ E então o **FastAPI** chamará a sobreposição no lugar da dependência origin
//// tab | Python 3.9+
```Python hl_lines="28-29 32"
-{!> ../../../docs_src/dependency_testing/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an_py39.py!}
```
////
@@ -47,40 +47,40 @@ E então o **FastAPI** chamará a sobreposição no lugar da dependência origin
//// tab | Python 3.8+
```Python hl_lines="29-30 33"
-{!> ../../../docs_src/dependency_testing/tutorial001_an.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Prefira utilizar a versão `Annotated` se possível.
///
```Python hl_lines="24-25 28"
-{!> ../../../docs_src/dependency_testing/tutorial001_py310.py!}
+{!> ../../docs_src/dependency_testing/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Prefira utilizar a versão `Annotated` se possível.
///
```Python hl_lines="28-29 32"
-{!> ../../../docs_src/dependency_testing/tutorial001.py!}
+{!> ../../docs_src/dependency_testing/tutorial001.py!}
```
////
-/// tip | "Dica"
+/// tip | Dica
Você pode definir uma sobreposição de dependência para uma dependência que é utilizada em qualquer lugar da sua aplicação **FastAPI**.
@@ -96,7 +96,7 @@ E então você pode redefinir as suas sobreposições (removê-las) definindo o
app.dependency_overrides = {}
```
-/// tip | "Dica"
+/// tip | Dica
Se você quer sobrepor uma dependência apenas para alguns testes, você pode definir a sobreposição no início do testes (dentro da função de teste) e reiniciá-la ao final (no final da função de teste).
diff --git a/docs/pt/docs/advanced/testing-events.md b/docs/pt/docs/advanced/testing-events.md
index 392fb741c..b6796e835 100644
--- a/docs/pt/docs/advanced/testing-events.md
+++ b/docs/pt/docs/advanced/testing-events.md
@@ -3,5 +3,5 @@
Quando você precisa que os seus manipuladores de eventos (`startup` e `shutdown`) sejam executados em seus testes, você pode utilizar o `TestClient` usando a instrução `with`:
```Python hl_lines="9-12 20-24"
-{!../../../docs_src/app_testing/tutorial003.py!}
+{!../../docs_src/app_testing/tutorial003.py!}
```
diff --git a/docs/pt/docs/advanced/testing-websockets.md b/docs/pt/docs/advanced/testing-websockets.md
index f458a05d4..99e1a6db4 100644
--- a/docs/pt/docs/advanced/testing-websockets.md
+++ b/docs/pt/docs/advanced/testing-websockets.md
@@ -5,10 +5,10 @@ Você pode usar o mesmo `TestClient` para testar WebSockets.
Para isso, você utiliza o `TestClient` dentro de uma instrução `with`, conectando com o WebSocket:
```Python hl_lines="27-31"
-{!../../../docs_src/app_testing/tutorial002.py!}
+{!../../docs_src/app_testing/tutorial002.py!}
```
-/// note | "Nota"
+/// note | Nota
Para mais detalhes, confira a documentação do Starlette para testar WebSockets.
diff --git a/docs/pt/docs/advanced/using-request-directly.md b/docs/pt/docs/advanced/using-request-directly.md
index 3dd0a8aef..df7e01833 100644
--- a/docs/pt/docs/advanced/using-request-directly.md
+++ b/docs/pt/docs/advanced/using-request-directly.md
@@ -30,12 +30,12 @@ Vamos imaginar que você deseja obter o endereço de IP/host do cliente dentro d
Para isso você precisa acessar a requisição diretamente.
```Python hl_lines="1 7-8"
-{!../../../docs_src/using_request_directly/tutorial001.py!}
+{!../../docs_src/using_request_directly/tutorial001.py!}
```
Ao declarar o parâmetro com o tipo sendo um `Request` em sua *função de operação de rota*, o **FastAPI** saberá como passar o `Request` neste parâmetro.
-/// tip | "Dica"
+/// tip | Dica
Note que neste caso, nós estamos declarando o parâmetro da rota ao lado do parâmetro da requisição.
@@ -49,7 +49,7 @@ Do mesmo jeito, você pode declarar qualquer outro parâmetro normalmente, e al
Você pode ler mais sobre os detalhes do objeto `Request` no site da documentação oficial do Starlette..
-/// note | "Detalhes Técnicos"
+/// note | Detalhes Técnicos
Você também pode utilizar `from starlette.requests import Request`.
diff --git a/docs/pt/docs/advanced/websockets.md b/docs/pt/docs/advanced/websockets.md
new file mode 100644
index 000000000..694f2bb5d
--- /dev/null
+++ b/docs/pt/docs/advanced/websockets.md
@@ -0,0 +1,188 @@
+# WebSockets
+
+Você pode usar WebSockets com **FastAPI**.
+
+## Instalando `WebSockets`
+
+Garanta que você criou um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, o ativou e instalou o `websockets`:
+
+
+
+Você pode digitar mensagens na caixa de entrada e enviá-las:
+
+
+
+E sua aplicação **FastAPI** com WebSockets responderá de volta:
+
+
+
+Você pode enviar (e receber) muitas mensagens:
+
+
+
+E todas elas usarão a mesma conexão WebSocket.
+
+## Usando `Depends` e outros
+
+Nos endpoints WebSocket você pode importar do `fastapi` e usar:
+
+* `Depends`
+* `Security`
+* `Cookie`
+* `Header`
+* `Path`
+* `Query`
+
+Eles funcionam da mesma forma que para outros endpoints FastAPI/*operações de rota*:
+
+{*../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82]*}
+
+/// info | Informação
+
+Como isso é um WebSocket, não faz muito sentido levantar uma `HTTPException`, em vez disso levantamos uma `WebSocketException`.
+
+Você pode usar um código de fechamento dos códigos válidos definidos na especificação.
+
+///
+
+### Tente os WebSockets com dependências
+
+Se seu arquivo for nomeado `main.py`, execute sua aplicação com:
+
+
+
+## Lidando com desconexões e múltiplos clientes
+
+Quando uma conexão WebSocket é fechada, o `await websocket.receive_text()` levantará uma exceção `WebSocketDisconnect`, que você pode então capturar e lidar como neste exemplo.
+
+{*../../docs_src/websockets/tutorial003_py39.py hl[79:81]*}
+
+Para testar:
+
+* Abrar o aplicativo com várias abas do navegador.
+* Escreva mensagens a partir delas.
+* Então feche uma das abas.
+
+Isso levantará a exceção `WebSocketDisconnect`, e todos os outros clientes receberão uma mensagem como:
+
+```
+Client #1596980209979 left the chat
+```
+
+/// tip | Dica
+
+O app acima é um exemplo mínimo e simples para demonstrar como lidar e transmitir mensagens para várias conexões WebSocket.
+
+Mas tenha em mente que, como tudo é manipulado na memória, em uma única lista, ele só funcionará enquanto o processo estiver em execução e só funcionará com um único processo.
+
+Se você precisa de algo fácil de integrar com o FastAPI, mas que seja mais robusto, suportado por Redis, PostgreSQL ou outros, verifique o encode/broadcaster.
+
+///
+
+## Mais informações
+
+Para aprender mais sobre as opções, verifique a documentação do Starlette para:
+
+* A classe `WebSocket`.
+* Manipulação de WebSockets baseada em classes.
diff --git a/docs/pt/docs/advanced/wsgi.md b/docs/pt/docs/advanced/wsgi.md
index 2c7ac1ffe..e6d08c8db 100644
--- a/docs/pt/docs/advanced/wsgi.md
+++ b/docs/pt/docs/advanced/wsgi.md
@@ -13,7 +13,7 @@ Em seguinda, encapsular a aplicação WSGI (e.g. Flask) com o middleware.
E então **"montar"** em um caminho de rota.
```Python hl_lines="2-3 23"
-{!../../../docs_src/wsgi/tutorial001.py!}
+{!../../docs_src/wsgi/tutorial001.py!}
```
## Conferindo
diff --git a/docs/pt/docs/alternatives.md b/docs/pt/docs/alternatives.md
index d3a304fa7..29c9693bb 100644
--- a/docs/pt/docs/alternatives.md
+++ b/docs/pt/docs/alternatives.md
@@ -30,13 +30,13 @@ Ele é utilizado por muitas companhias incluindo Mozilla, Red Hat e Eventbrite.
Ele foi um dos primeiros exemplos de **documentação automática de API**, e essa foi especificamente uma das primeiras idéias que inspirou "a busca por" **FastAPI**.
-/// note | "Nota"
+/// note | Nota
Django REST Framework foi criado por Tom Christie. O mesmo criador de Starlette e Uvicorn, nos quais **FastAPI** é baseado.
///
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Ter uma documentação automática da API em interface web.
@@ -56,7 +56,7 @@ Esse desacoplamento de partes, e sendo um "microframework" que pode ser extendid
Dada a simplicidade do Flask, parecia uma ótima opção para construção de APIs. A próxima coisa a procurar era um "Django REST Framework" para Flask.
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Ser um microframework. Fazer ele fácil para misturar e combinar com ferramentas e partes necessárias.
@@ -98,7 +98,7 @@ def read_url():
Veja as similaridades em `requests.get(...)` e `@app.get(...)`.
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
* Ter uma API simples e intuitiva.
* Utilizar nomes de métodos HTTP (operações) diretamente, de um jeito direto e intuitivo.
@@ -118,7 +118,7 @@ Em algum ponto, Swagger foi dado para a Fundação Linux, e foi renomeado OpenAP
Isso acontece porquê quando alguém fala sobre a versão 2.0 é comum dizer "Swagger", e para a versão 3+, "OpenAPI".
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Adotar e usar um padrão aberto para especificações API, ao invés de algum esquema customizado.
@@ -147,7 +147,7 @@ Esses recursos são o que Marshmallow foi construído para fornecer. Ele é uma
Mas ele foi criado antes da existência do _type hints_ do Python. Então, para definir todo o _schema_ você precisa utilizar específicas ferramentas e classes fornecidas pelo Marshmallow.
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Usar código para definir "schemas" que forneçam, automaticamente, tipos de dados e validação.
@@ -169,7 +169,7 @@ Webargs foi criado pelos mesmos desenvolvedores do Marshmallow.
///
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Ter validação automática de dados vindos de requisições.
@@ -199,7 +199,7 @@ APISpec foi criado pelos mesmos desenvolvedores do Marshmallow.
///
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Dar suporte a padrões abertos para APIs, OpenAPI.
@@ -231,7 +231,7 @@ Flask-apispec foi criado pelos mesmos desenvolvedores do Marshmallow.
///
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Gerar _schema_ OpenAPI automaticamente, a partir do mesmo código que define serialização e validação.
@@ -251,7 +251,7 @@ Mas como os dados TypeScript não são preservados após a compilação para o J
Ele também não controla modelos aninhados muito bem. Então, se o corpo JSON na requisição for um objeto JSON que contém campos internos que contém objetos JSON aninhados, ele não consegue ser validado e documentado apropriadamente.
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Usar tipos Python para ter um ótimo suporte do editor.
@@ -263,7 +263,7 @@ Ter um sistema de injeção de dependência poderoso. Achar um jeito de minimiza
Ele foi um dos primeiros frameworks Python extremamente rápido baseado em `asyncio`. Ele foi feito para ser muito similar ao Flask.
-/// note | "Detalhes técnicos"
+/// note | Detalhes técnicos
Ele utiliza `uvloop` ao invés do '_loop_' `asyncio` padrão do Python. É isso que deixa ele tão rápido.
@@ -271,7 +271,7 @@ Ele claramente inspirou Uvicorn e Starlette, que são atualmente mais rápidos q
///
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Achar um jeito de ter uma performance insana.
@@ -289,7 +289,7 @@ Ele é projetado para ter funções que recebem dois parâmetros, uma "requisiç
Então, validação de dados, serialização e documentação tem que ser feitos no código, não automaticamente. Ou eles terão que ser implementados como um framework acima do Falcon, como o Hug. Essa mesma distinção acontece em outros frameworks que são inspirados pelo design do Falcon, tendo um objeto de requisição e um objeto de resposta como parâmetros.
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Achar jeitos de conseguir melhor performance.
@@ -315,7 +315,7 @@ O sistema de injeção de dependência exige pré-registro das dependências e a
Rotas são declaradas em um único lugar, usando funções declaradas em outros lugares (ao invés de usar decoradores que possam ser colocados diretamente acima da função que controla o _endpoint_). Isso é mais perto de como o Django faz isso do que como Flask (e Starlette) faz. Ele separa no código coisas que são relativamente amarradas.
-/// check | "**FastAPI** inspirado para"
+/// check | **FastAPI** inspirado para
Definir validações extras para tipos de dados usando valores "padrão" de atributos dos modelos. Isso melhora o suporte do editor, e não estava disponível no Pydantic antes.
@@ -323,7 +323,7 @@ Isso na verdade inspirou a atualização de partes do Pydantic, para dar suporte
///
-### Hug
+### Hug
Hug foi um dos primeiros frameworks a implementar a declaração de tipos de parâmetros usando Python _type hints_. Isso foi uma ótima idéia que inspirou outras ferramentas a fazer o mesmo.
@@ -343,7 +343,7 @@ Hug foi criado por Timothy Crosley, o mesmo criador do Versionamento Semântico.
-
-Você pode criar aplicações para produção com **FastAPI** bem agora (e você provavelmente já faça isso por um tempo), você tem que ter certeza de utilizar uma versão que funcione corretamente com o resto do seu código.
-
-### Anote sua versão `fastapi`
-
-A primeira coisa que você deve fazer é "fixar" a versão do **FastAPI** que está utilizando para a última versão específica que você sabe que funciona corretamente para a sua aplicação.
-
-Por exemplo, vamos dizer que você esteja utilizando a versão `0.45.0` no seu _app_.
-
-Se você usa um arquivo `requirements.txt`, dá para especificar a versão assim:
-
-```txt
-fastapi==0.45.0
-```
-
-isso significa que você pode usar exatamente a versão `0.45.0`.
-
-Ou você poderia fixar assim:
-
-```txt
-fastapi>=0.45.0,<0.46.0
-```
-
-o que significa que você pode usar as versões `0.45.0` ou acima, mas menor que `0.46.0`. Por exemplo, a versão `0.45.2` poderia ser aceita.
-
-Se você usa qualquer outra ferramenta para gerenciar suas instalações, como Poetry, Pipenv ou outro, todos terão um modo que você possa usar para definir versões específicas para seus pacotes.
-
-### Versões disponíveis
-
-Você pode ver as versões disponíveis (por exemplo, para verificar qual é a versão atual) nas [Notas de Lançamento](release-notes.md){.internal-link target=_blank}.
-
-### Sobre as versões
-
-Seguindo as convenções do Versionamento Semântico, qualquer versão abaixo de `1.0.0` pode potencialmente adicionar mudanças que quebrem.
-
-FastAPI também segue a convenção que qualquer versão de _"PATCH"_ seja para ajustes de _bugs_ e mudanças que não quebrem a aplicação.
-
-/// tip
-
-O _"PATCH"_ é o último número, por exemplo, em `0.2.3`, a versão do _PATCH_ é `3`.
-
-///
-
-Então, você poderia ser capaz de fixar para uma versão como:
-
-```txt
-fastapi>=0.45.0,<0.46.0
-```
-
-Mudanças que quebram e novos recursos são adicionados em versões _"MINOR"_.
-
-/// tip
-
-O _"MINOR"_ é o número do meio, por exemplo, em `0.2.3`, a versão _MINOR_ é `2`.
-
-///
-
-### Atualizando as versões FastAPI
-
-Você pode adicionar testes em sua aplicação.
-
-Com o **FastAPI** é muito fácil (graças ao Starlette), verifique a documentação: [Testando](tutorial/testing.md){.internal-link target=_blank}
-
-Após você ter os testes, então você pode fazer o _upgrade_ da versão **FastAPI** para uma mais recente, e ter certeza que todo seu código esteja funcionando corretamente rodando seus testes.
-
-Se tudo estiver funcionando, ou após você fazer as alterações necessárias, e todos seus testes estiverem passando, então você poderá fixar o `fastapi` para a versão mais recente.
-
-### Sobre Starlette
-
-Você não deve fixar a versão do `starlette`.
-
-Versões diferentes do **FastAPI** irão utilizar uma versão mais nova específica do Starlette.
-
-Então, você pode deixar que o **FastAPI** use a versão correta do Starlette.
-
-### Sobre Pydantic
-
-Pydantic inclui os testes para **FastAPI** em seus próprios testes, então novas versões do Pydantic (acima de `1.0.0`) são sempre compatíveis com FastAPI.
-
-Você pode fixar o Pydantic para qualquer versão acima de `1.0.0` e abaixo de `2.0.0` que funcionará.
-
-Por exemplo:
-
-```txt
-pydantic>=1.2.0,<2.0.0
-```
-
-## Docker
-
-Nessa seção você verá instruções e _links_ para guias de saber como:
-
-* Fazer uma imagem/container da sua aplicação **FastAPI** com máxima performance. Em aproximadamente **5 min**.
-* (Opcionalmente) entender o que você, como desenvolvedor, precisa saber sobre HTTPS.
-* Inicializar um _cluster_ Docker Swarm Mode com HTTPS automático, mesmo em um simples servidor de $5 dólares/mês. Em aproximadamente **20 min**.
-* Gere e implante uma aplicação **FastAPI** completa, usando seu _cluster_ Docker Swarm, com HTTPS etc. Em aproxiamadamente **10 min**.
-
-Você pode usar **Docker** para implantação. Ele tem várias vantagens como segurança, replicabilidade, desenvolvimento simplificado etc.
-
-Se você está usando Docker, você pode utilizar a imagem Docker oficial:
-
-### tiangolo/uvicorn-gunicorn-fastapi
-
-Essa imagem tem um mecanismo incluído de "auto-ajuste", para que você possa apenas adicionar seu código e ter uma alta performance automaticamente. E sem fazer sacrifícios.
-
-Mas você pode ainda mudar e atualizar todas as configurações com variáveis de ambiente ou arquivos de configuração.
-
-/// tip
-
-Para ver todas as configurações e opções, vá para a página da imagem do Docker: tiangolo/uvicorn-gunicorn-fastapi.
-
-///
-
-### Crie um `Dockerfile`
-
-* Vá para o diretório de seu projeto.
-* Crie um `Dockerfile` com:
-
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
-
-COPY ./app /app
-```
-
-#### Grandes aplicações
-
-Se você seguiu a seção sobre criação de [Grandes Aplicações com Múltiplos Arquivos](tutorial/bigger-applications.md){.internal-link target=_blank}, seu `Dockerfile` poderia parecer como:
-
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
-
-COPY ./app /app/app
-```
-
-#### Raspberry Pi e outras arquiteturas
-
-Se você estiver rodando Docker em um Raspberry Pi (que possui um processador ARM) ou qualquer outra arquitetura, você pode criar um `Dockerfile` do zero, baseado em uma imagem base Python (que é multi-arquitetural) e utilizar Uvicorn sozinho.
-
-Nesse caso, seu `Dockerfile` poderia parecer assim:
-
-```Dockerfile
-FROM python:3.7
-
-RUN pip install fastapi uvicorn
-
-EXPOSE 80
-
-COPY ./app /app
-
-CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
-```
-
-### Crie o código **FastAPI**
-
-* Crie um diretório `app` e entre nele.
-* Crie um arquivo `main.py` com:
-
-```Python
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/")
-def read_root():
- return {"Hello": "World"}
-
-
-@app.get("/items/{item_id}")
-def read_item(item_id: int, q: str = None):
- return {"item_id": item_id, "q": q}
-```
-
-* Você deve ter uma estrutura de diretórios assim:
-
-```
-.
-├── app
-│ └── main.py
-└── Dockerfile
-```
-
-### Construa a imagem Docker
-
-* Vá para o diretório do projeto (onde seu `Dockerfile` está, contendo seu diretório `app`.
-* Construa sua imagem FastAPI:
-
-
+
+---
+
+Agora que sabemos a diferença entre os termos **processo** e **programa**, vamos continuar falando sobre implantações.
+
+## Executando na inicialização
+
+Na maioria dos casos, quando você cria uma API web, você quer que ela esteja **sempre em execução**, ininterrupta, para que seus clientes possam sempre acessá-la. Isso é claro, a menos que você tenha um motivo específico para querer que ela seja executada somente em certas situações, mas na maioria das vezes você quer que ela esteja constantemente em execução e **disponível**.
+
+### Em um servidor remoto
+
+Ao configurar um servidor remoto (um servidor em nuvem, uma máquina virtual, etc.), a coisa mais simples que você pode fazer é usar `fastapi run` (que usa Uvicorn) ou algo semelhante, manualmente, da mesma forma que você faz ao desenvolver localmente.
+
+E funcionará e será útil **durante o desenvolvimento**.
+
+Mas se sua conexão com o servidor for perdida, o **processo em execução** provavelmente morrerá.
+
+E se o servidor for reiniciado (por exemplo, após atualizações ou migrações do provedor de nuvem), você provavelmente **não notará**. E por causa disso, você nem saberá que precisa reiniciar o processo manualmente. Então, sua API simplesmente permanecerá inativa. 😱
+
+### Executar automaticamente na inicialização
+
+Em geral, você provavelmente desejará que o programa do servidor (por exemplo, Uvicorn) seja iniciado automaticamente na inicialização do servidor e, sem precisar de nenhuma **intervenção humana**, tenha um processo sempre em execução com sua API (por exemplo, Uvicorn executando seu aplicativo FastAPI).
+
+### Programa separado
+
+Para conseguir isso, você normalmente terá um **programa separado** que garantiria que seu aplicativo fosse executado na inicialização. E em muitos casos, ele também garantiria que outros componentes ou aplicativos também fossem executados, por exemplo, um banco de dados.
+
+### Ferramentas de exemplo para executar na inicialização
+
+Alguns exemplos de ferramentas que podem fazer esse trabalho são:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker em Modo Swarm
+* Systemd
+* Supervisor
+* Gerenciado internamente por um provedor de nuvem como parte de seus serviços
+* Outros...
+
+Darei exemplos mais concretos nos próximos capítulos.
+
+## Reinicializações
+
+Semelhante a garantir que seu aplicativo seja executado na inicialização, você provavelmente também deseja garantir que ele seja **reiniciado** após falhas.
+
+### Nós cometemos erros
+
+Nós, como humanos, cometemos **erros** o tempo todo. O software quase *sempre* tem **bugs** escondidos em lugares diferentes. 🐛
+
+E nós, como desenvolvedores, continuamos aprimorando o código à medida que encontramos esses bugs e implementamos novos recursos (possivelmente adicionando novos bugs também 😅).
+
+### Pequenos erros são tratados automaticamente
+
+Ao criar APIs da web com FastAPI, se houver um erro em nosso código, o FastAPI normalmente o conterá na única solicitação que acionou o erro. 🛡
+
+O cliente receberá um **Erro Interno do Servidor 500** para essa solicitação, mas o aplicativo continuará funcionando para as próximas solicitações em vez de travar completamente.
+
+### Erros maiores - Travamentos
+
+No entanto, pode haver casos em que escrevemos algum código que **trava todo o aplicativo**, fazendo com que o Uvicorn e o Python travem. 💥
+
+E ainda assim, você provavelmente não gostaria que o aplicativo permanecesse inativo porque houve um erro em um lugar, você provavelmente quer que ele **continue em execução** pelo menos para as *operações de caminho* que não estão quebradas.
+
+### Reiniciar após falha
+
+Mas nos casos com erros realmente graves que travam o **processo** em execução, você vai querer um componente externo que seja responsável por **reiniciar** o processo, pelo menos algumas vezes...
+
+/// tip | Dica
+
+...Embora se o aplicativo inteiro estiver **travando imediatamente**, provavelmente não faça sentido reiniciá-lo para sempre. Mas nesses casos, você provavelmente notará isso durante o desenvolvimento, ou pelo menos logo após a implantação.
+
+Então, vamos nos concentrar nos casos principais, onde ele pode travar completamente em alguns casos específicos **no futuro**, e ainda faz sentido reiniciá-lo.
+
+///
+
+Você provavelmente gostaria de ter a coisa responsável por reiniciar seu aplicativo como um **componente externo**, porque a essa altura, o mesmo aplicativo com Uvicorn e Python já havia travado, então não há nada no mesmo código do mesmo aplicativo que possa fazer algo a respeito.
+
+### Ferramentas de exemplo para reiniciar automaticamente
+
+Na maioria dos casos, a mesma ferramenta usada para **executar o programa na inicialização** também é usada para lidar com **reinicializações** automáticas.
+
+Por exemplo, isso poderia ser resolvido por:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker no Modo Swarm
+* Systemd
+* Supervisor
+* Gerenciado internamente por um provedor de nuvem como parte de seus serviços
+* Outros...
+
+## Replicação - Processos e Memória
+
+Com um aplicativo FastAPI, usando um programa de servidor como o comando `fastapi` que executa o Uvicorn, executá-lo uma vez em **um processo** pode atender a vários clientes simultaneamente.
+
+Mas em muitos casos, você desejará executar vários processos de trabalho ao mesmo tempo.
+
+### Processos Múltiplos - Trabalhadores
+
+Se você tiver mais clientes do que um único processo pode manipular (por exemplo, se a máquina virtual não for muito grande) e tiver **vários núcleos** na CPU do servidor, você poderá ter **vários processos** em execução com o mesmo aplicativo ao mesmo tempo e distribuir todas as solicitações entre eles.
+
+Quando você executa **vários processos** do mesmo programa de API, eles são comumente chamados de **trabalhadores**.
+
+### Processos do Trabalhador e Portas
+
+Lembra da documentação [Sobre HTTPS](https.md){.internal-link target=_blank} que diz que apenas um processo pode escutar em uma combinação de porta e endereço IP em um servidor?
+
+Isso ainda é verdade.
+
+Então, para poder ter **vários processos** ao mesmo tempo, tem que haver um **único processo escutando em uma porta** que então transmite a comunicação para cada processo de trabalho de alguma forma.
+
+### Memória por Processo
+
+Agora, quando o programa carrega coisas na memória, por exemplo, um modelo de aprendizado de máquina em uma variável, ou o conteúdo de um arquivo grande em uma variável, tudo isso **consome um pouco da memória (RAM)** do servidor.
+
+E vários processos normalmente **não compartilham nenhuma memória**. Isso significa que cada processo em execução tem suas próprias coisas, variáveis e memória. E se você estiver consumindo uma grande quantidade de memória em seu código, **cada processo** consumirá uma quantidade equivalente de memória.
+
+### Memória do servidor
+
+Por exemplo, se seu código carrega um modelo de Machine Learning com **1 GB de tamanho**, quando você executa um processo com sua API, ele consumirá pelo menos 1 GB de RAM. E se você iniciar **4 processos** (4 trabalhadores), cada um consumirá 1 GB de RAM. Então, no total, sua API consumirá **4 GB de RAM**.
+
+E se o seu servidor remoto ou máquina virtual tiver apenas 3 GB de RAM, tentar carregar mais de 4 GB de RAM causará problemas. 🚨
+
+### Processos Múltiplos - Um Exemplo
+
+Neste exemplo, há um **Processo Gerenciador** que inicia e controla dois **Processos de Trabalhadores**.
+
+Este Processo de Gerenciador provavelmente seria o que escutaria na **porta** no IP. E ele transmitiria toda a comunicação para os processos de trabalho.
+
+Esses processos de trabalho seriam aqueles que executariam seu aplicativo, eles executariam os cálculos principais para receber uma **solicitação** e retornar uma **resposta**, e carregariam qualquer coisa que você colocasse em variáveis na RAM.
+
+fastapi run --workers 4 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 - Production mode ───────────╮ + │ │ + │ Serving at: http://0.0.0.0:8000 │ + │ │ + │ API docs: http://0.0.0.0:8000/docs │ + │ │ + │ Running in production mode, for development use: │ + │ │ + │ fastapi dev │ + │ │ + ╰─────────────────────────────────────────────────────╯ + +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: 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. ++``` + +
+
+Mas você pode desabilitá-lo definindo `syntaxHighlight` como `False`:
+
+```Python hl_lines="3"
+{!../../docs_src/configure_swagger_ui/tutorial001.py!}
+```
+
+...e então o Swagger UI não mostrará mais o destaque de sintaxe:
+
+
+
+## Alterar o tema
+
+Da mesma forma que você pode definir o tema de destaque de sintaxe com a chave `"syntaxHighlight.theme"` (observe que há um ponto no meio):
+
+```Python hl_lines="3"
+{!../../docs_src/configure_swagger_ui/tutorial002.py!}
+```
+
+Essa configuração alteraria o tema de cores de destaque de sintaxe:
+
+
+
+## Alterar parâmetros de UI padrão do Swagger
+
+O FastAPI inclui alguns parâmetros de configuração padrão apropriados para a maioria dos casos de uso.
+
+Inclui estas configurações padrão:
+
+```Python
+{!../../fastapi/openapi/docs.py[ln:7-23]!}
+```
+
+Você pode substituir qualquer um deles definindo um valor diferente no argumento `swagger_ui_parameters`.
+
+Por exemplo, para desabilitar `deepLinking` você pode passar essas configurações para `swagger_ui_parameters`:
+
+```Python hl_lines="3"
+{!../../docs_src/configure_swagger_ui/tutorial003.py!}
+```
+
+## Outros parâmetros da UI do Swagger
+
+Para ver todas as outras configurações possíveis que você pode usar, leia a documentação oficial dos parâmetros da UI do Swagger.
+
+## Configurações somente JavaScript
+
+A interface do usuário do Swagger também permite que outras configurações sejam objetos **somente JavaScript** (por exemplo, funções JavaScript).
+
+O FastAPI também inclui estas configurações de `predefinições` somente para JavaScript:
+
+```JavaScript
+presets: [
+ SwaggerUIBundle.presets.apis,
+ SwaggerUIBundle.SwaggerUIStandalonePreset
+]
+```
+
+Esses são objetos **JavaScript**, não strings, então você não pode passá-los diretamente do código Python.
+
+Se você precisar usar configurações somente JavaScript como essas, você pode usar um dos métodos acima. Sobrescreva todas as *operações de rotas* do Swagger UI e escreva manualmente qualquer JavaScript que você precisar.
diff --git a/docs/pt/docs/how-to/custom-docs-ui-assets.md b/docs/pt/docs/how-to/custom-docs-ui-assets.md
new file mode 100644
index 000000000..00dd144c9
--- /dev/null
+++ b/docs/pt/docs/how-to/custom-docs-ui-assets.md
@@ -0,0 +1,205 @@
+# Recursos Estáticos Personalizados para a UI de Documentação (Hospedagem Própria)
+
+A documentação da API usa **Swagger UI** e **ReDoc**, e cada um deles precisa de alguns arquivos JavaScript e CSS.
+
+Por padrão, esses arquivos são fornecidos por um CDN.
+
+Mas é possível personalizá-los, você pode definir um CDN específico ou providenciar os arquivos você mesmo.
+
+## CDN Personalizado para JavaScript e CSS
+
+Vamos supor que você deseja usar um CDN diferente, por exemplo, você deseja usar `https://unpkg.com/`.
+
+Isso pode ser útil se, por exemplo, você mora em um país que restringe algumas URLs.
+
+### Desativar a documentação automática
+
+O primeiro passo é desativar a documentação automática, pois por padrão, ela usa o CDN padrão.
+
+Para desativá-los, defina suas URLs como `None` ao criar seu aplicativo `FastAPI`:
+
+```Python hl_lines="8"
+{!../../docs_src/custom_docs_ui/tutorial001.py!}
+```
+
+### Incluir a documentação personalizada
+
+Agora você pode criar as *operações de rota* para a documentação personalizada.
+
+Você pode reutilizar as funções internas do FastAPI para criar as páginas HTML para a documentação e passar os argumentos necessários:
+
+* `openapi_url`: a URL onde a página HTML para a documentação pode obter o esquema OpenAPI para a sua API. Você pode usar aqui o atributo `app.openapi_url`.
+* `title`: o título da sua API.
+* `oauth2_redirect_url`: você pode usar `app.swagger_ui_oauth2_redirect_url` aqui para usar o padrão.
+* `swagger_js_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **JavaScript**. Este é o URL do CDN personalizado.
+* `swagger_css_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **CSS**. Este é o URL do CDN personalizado.
+
+E de forma semelhante para o ReDoc...
+
+```Python hl_lines="2-6 11-19 22-24 27-33"
+{!../../docs_src/custom_docs_ui/tutorial001.py!}
+```
+
+/// tip | Dica
+
+A *operação de rota* para `swagger_ui_redirect` é um auxiliar para quando você usa OAuth2.
+
+Se você integrar sua API com um provedor OAuth2, você poderá autenticar e voltar para a documentação da API com as credenciais adquiridas. E interagir com ela usando a autenticação OAuth2 real.
+
+Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse auxiliar de "redirecionamento".
+
+///
+
+### Criar uma *operação de rota* para testar
+
+Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
+
+```Python hl_lines="36-38"
+{!../../docs_src/custom_docs_ui/tutorial001.py!}
+```
+
+### Teste
+
+Agora, você deve ser capaz de ir para a documentação em http://127.0.0.1:8000/docs, e recarregar a página, ela carregará esses recursos do novo CDN.
+
+## Hospedagem Própria de JavaScript e CSS para a documentação
+
+Hospedar o JavaScript e o CSS pode ser útil se, por exemplo, você precisa que seu aplicativo continue funcionando mesmo offline, sem acesso aberto à Internet, ou em uma rede local.
+
+Aqui você verá como providenciar esses arquivos você mesmo, no mesmo aplicativo FastAPI, e configurar a documentação para usá-los.
+
+### Estrutura de Arquivos do Projeto
+
+Vamos supor que a estrutura de arquivos do seu projeto se pareça com isso:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+```
+
+Agora crie um diretório para armazenar esses arquivos estáticos.
+
+Sua nova estrutura de arquivos poderia se parecer com isso:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static/
+```
+
+### Baixe os arquivos
+
+Baixe os arquivos estáticos necessários para a documentação e coloque-os no diretório `static/`.
+
+Você provavelmente pode clicar com o botão direito em cada link e selecionar uma opção semelhante a `Salvar link como...`.
+
+**Swagger UI** usa os arquivos:
+
+* `swagger-ui-bundle.js`
+* `swagger-ui.css`
+
+E o **ReDoc** usa os arquivos:
+
+* `redoc.standalone.js`
+
+Depois disso, sua estrutura de arquivos deve se parecer com:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static
+ ├── redoc.standalone.js
+ ├── swagger-ui-bundle.js
+ └── swagger-ui.css
+```
+
+### Prover os arquivos estáticos
+
+* Importe `StaticFiles`.
+* "Monte" a instância `StaticFiles()` em um caminho específico.
+
+```Python hl_lines="7 11"
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+### Teste os arquivos estáticos
+
+Inicialize seu aplicativo e vá para http://127.0.0.1:8000/static/redoc.standalone.js.
+
+Você deverá ver um arquivo JavaScript muito longo para o **ReDoc**.
+
+Esse arquivo pode começar com algo como:
+
+```JavaScript
+/*!
+ * ReDoc - OpenAPI/Swagger-generated API Reference Documentation
+ * -------------------------------------------------------------
+ * Version: "2.0.0-rc.18"
+ * Repo: https://github.com/Redocly/redoc
+ */
+!function(e,t){"object"==typeof exports&&"object"==typeof m
+
+...
+```
+
+Isso confirma que você está conseguindo fornecer arquivos estáticos do seu aplicativo e que você colocou os arquivos estáticos para a documentação no local correto.
+
+Agora, podemos configurar o aplicativo para usar esses arquivos estáticos para a documentação.
+
+### Desativar a documentação automática para arquivos estáticos
+
+Da mesma forma que ao usar um CDN personalizado, o primeiro passo é desativar a documentação automática, pois ela usa o CDN padrão.
+
+Para desativá-los, defina suas URLs como `None` ao criar seu aplicativo `FastAPI`:
+
+```Python hl_lines="9"
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+### Incluir a documentação personalizada para arquivos estáticos
+
+E da mesma forma que com um CDN personalizado, agora você pode criar as *operações de rota* para a documentação personalizada.
+
+Novamente, você pode reutilizar as funções internas do FastAPI para criar as páginas HTML para a documentação e passar os argumentos necessários:
+
+* `openapi_url`: a URL onde a página HTML para a documentação pode obter o esquema OpenAPI para a sua API. Você pode usar aqui o atributo `app.openapi_url`.
+* `title`: o título da sua API.
+* `oauth2_redirect_url`: Você pode usar `app.swagger_ui_oauth2_redirect_url` aqui para usar o padrão.
+* `swagger_js_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **JavaScript**. Este é o URL do CDN personalizado. **Este é o URL que seu aplicativo está fornecendo**.
+* `swagger_css_url`: a URL onde a página HTML para a sua documentação do Swagger UI pode obter o arquivo **CSS**. **Esse é o que seu aplicativo está fornecendo**.
+
+E de forma semelhante para o ReDoc...
+
+```Python hl_lines="2-6 14-22 25-27 30-36"
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+/// tip | Dica
+
+A *operação de rota* para `swagger_ui_redirect` é um auxiliar para quando você usa OAuth2.
+
+Se você integrar sua API com um provedor OAuth2, você poderá autenticar e voltar para a documentação da API com as credenciais adquiridas. E, então, interagir com ela usando a autenticação OAuth2 real.
+
+Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse auxiliar de "redirect".
+
+///
+
+### Criar uma *operação de rota* para testar arquivos estáticos
+
+Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
+
+```Python hl_lines="39-41"
+{!../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+### Teste a UI de Arquivos Estáticos
+
+Agora, você deve ser capaz de desconectar o WiFi, ir para a documentação em http://127.0.0.1:8000/docs, e recarregar a página.
+
+E mesmo sem Internet, você será capaz de ver a documentação da sua API e interagir com ela.
diff --git a/docs/pt/docs/how-to/custom-request-and-route.md b/docs/pt/docs/how-to/custom-request-and-route.md
new file mode 100644
index 000000000..64325eed9
--- /dev/null
+++ b/docs/pt/docs/how-to/custom-request-and-route.md
@@ -0,0 +1,121 @@
+# Requisições Personalizadas e Classes da APIRoute
+
+Em algum casos, você pode querer sobreescrever a lógica usada pelas classes `Request`e `APIRoute`.
+
+Em particular, isso pode ser uma boa alternativa para uma lógica em um middleware
+
+Por exemplo, se você quiser ler ou manipular o corpo da requisição antes que ele seja processado pela sua aplicação.
+
+/// danger | Perigo
+
+Isso é um recurso "avançado".
+
+Se você for um iniciante em **FastAPI** você deve considerar pular essa seção.
+
+///
+
+## Casos de Uso
+
+Alguns casos de uso incluem:
+
+* Converter requisições não-JSON para JSON (por exemplo, `msgpack`).
+* Descomprimir corpos de requisição comprimidos com gzip.
+* Registrar automaticamente todos os corpos de requisição.
+
+## Manipulando codificações de corpo de requisição personalizadas
+
+Vamos ver como usar uma subclasse personalizada de `Request` para descomprimir requisições gzip.
+
+E uma subclasse de `APIRoute` para usar essa classe de requisição personalizada.
+
+### Criar uma classe `GzipRequest` personalizada
+
+/// tip | Dica
+
+Isso é um exemplo de brincadeira para demonstrar como funciona, se você precisar de suporte para Gzip, você pode usar o [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank} fornecido.
+
+///
+
+Primeiro, criamos uma classe `GzipRequest`, que irá sobrescrever o método `Request.body()` para descomprimir o corpo na presença de um cabeçalho apropriado.
+
+Se não houver `gzip` no cabeçalho, ele não tentará descomprimir o corpo.
+
+Dessa forma, a mesma classe de rota pode lidar com requisições comprimidas ou não comprimidas.
+
+```Python hl_lines="8-15"
+{!../../docs_src/custom_request_and_route/tutorial001.py!}
+```
+
+### Criar uma classe `GzipRoute` personalizada
+
+Em seguida, criamos uma subclasse personalizada de `fastapi.routing.APIRoute` que fará uso do `GzipRequest`.
+
+Dessa vez, ele irá sobrescrever o método `APIRoute.get_route_handler()`.
+
+Esse método retorna uma função. E essa função é o que irá receber uma requisição e retornar uma resposta.
+
+Aqui nós usamos para criar um `GzipRequest` a partir da requisição original.
+
+```Python hl_lines="18-26"
+{!../../docs_src/custom_request_and_route/tutorial001.py!}
+```
+
+/// note | Detalhes Técnicos
+
+Um `Request` também tem um `request.receive`, que é uma função para "receber" o corpo da requisição.
+
+Um `Request` também tem um `request.receive`, que é uma função para "receber" o corpo da requisição.
+
+O dicionário `scope` e a função `receive` são ambos parte da especificação ASGI.
+
+E essas duas coisas, `scope` e `receive`, são o que é necessário para criar uma nova instância de `Request`.
+
+Para aprender mais sobre o `Request` confira a documentação do Starlette sobre Requests.
+
+///
+
+A única coisa que a função retornada por `GzipRequest.get_route_handler` faz de diferente é converter o `Request` para um `GzipRequest`.
+
+Fazendo isso, nosso `GzipRequest` irá cuidar de descomprimir os dados (se necessário) antes de passá-los para nossas *operações de rota*.
+
+Depois disso, toda a lógica de processamento é a mesma.
+
+Mas por causa das nossas mudanças em `GzipRequest.body`, o corpo da requisição será automaticamente descomprimido quando for carregado pelo **FastAPI** quando necessário.
+
+## Acessando o corpo da requisição em um manipulador de exceção
+
+/// tip | Dica
+
+Para resolver esse mesmo problema, é provavelmente muito mais fácil usar o `body` em um manipulador personalizado para `RequestValidationError` ([Tratando Erros](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
+
+Mas esse exemplo ainda é valido e mostra como interagir com os componentes internos.
+
+///
+
+Também podemos usar essa mesma abordagem para acessar o corpo da requisição em um manipulador de exceção.
+
+Tudo que precisamos fazer é manipular a requisição dentro de um bloco `try`/`except`:
+
+```Python hl_lines="13 15"
+{!../../docs_src/custom_request_and_route/tutorial002.py!}
+```
+
+Se uma exceção ocorrer, a instância `Request` ainda estará em escopo, então podemos ler e fazer uso do corpo da requisição ao lidar com o erro:
+
+```Python hl_lines="16-18"
+{!../../docs_src/custom_request_and_route/tutorial002.py!}
+```
+
+## Classe `APIRoute` personalizada em um router
+
+você também pode definir o parametro `route_class` de uma `APIRouter`;
+
+```Python hl_lines="26"
+{!../../docs_src/custom_request_and_route/tutorial003.py!}
+```
+
+Nesse exemplo, as *operações de rota* sob o `router` irão usar a classe `TimedRoute` personalizada, e terão um cabeçalho extra `X-Response-Time` na resposta com o tempo que levou para gerar a resposta:
+
+```Python hl_lines="13-20"
+{!../../docs_src/custom_request_and_route/tutorial003.py!}
+```
diff --git a/docs/pt/docs/how-to/extending-openapi.md b/docs/pt/docs/how-to/extending-openapi.md
new file mode 100644
index 000000000..40917325b
--- /dev/null
+++ b/docs/pt/docs/how-to/extending-openapi.md
@@ -0,0 +1,91 @@
+
+# Extendendo o OpenAPI
+
+Existem alguns casos em que pode ser necessário modificar o esquema OpenAPI gerado.
+
+Nesta seção, você verá como fazer isso.
+
+## O processo normal
+
+O processo normal (padrão) é o seguinte:
+
+Uma aplicação (instância) do `FastAPI` possui um método `.openapi()` que deve retornar o esquema OpenAPI.
+
+Como parte da criação do objeto de aplicação, uma *operação de rota* para `/openapi.json` (ou para o que você definir como `openapi_url`) é registrada.
+
+Ela apenas retorna uma resposta JSON com o resultado do método `.openapi()` da aplicação.
+
+Por padrão, o que o método `.openapi()` faz é verificar se a propriedade `.openapi_schema` tem conteúdo e retorná-lo.
+
+Se não tiver, ele gera o conteúdo usando a função utilitária em `fastapi.openapi.utils.get_openapi`.
+
+E essa função `get_openapi()` recebe como parâmetros:
+
+* `title`: O título do OpenAPI, exibido na documentação.
+* `version`: A versão da sua API, por exemplo, `2.5.0`.
+* `openapi_version`: A versão da especificação OpenAPI utilizada. Por padrão, a mais recente: `3.1.0`.
+* `summary`: Um resumo curto da API.
+* `description`: A descrição da sua API, que pode incluir markdown e será exibida na documentação.
+* `routes`: Uma lista de rotas, que são cada uma das *operações de rota* registradas. Elas são obtidas de `app.routes`.
+
+/// info | Informação
+
+O parâmetro `summary` está disponível no OpenAPI 3.1.0 e superior, suportado pelo FastAPI 0.99.0 e superior.
+
+///
+
+## Sobrescrevendo os padrões
+
+Com as informações acima, você pode usar a mesma função utilitária para gerar o esquema OpenAPI e sobrescrever cada parte que precisar.
+
+Por exemplo, vamos adicionar Extensão OpenAPI do ReDoc para incluir um logo personalizado.
+
+### **FastAPI** Normal
+
+Primeiro, escreva toda a sua aplicação **FastAPI** normalmente:
+
+```Python hl_lines="1 4 7-9"
+{!../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Gerar o esquema OpenAPI
+
+Em seguida, use a mesma função utilitária para gerar o esquema OpenAPI, dentro de uma função `custom_openapi()`:
+
+```Python hl_lines="2 15-21"
+{!../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Modificar o esquema OpenAPI
+
+Agora, você pode adicionar a extensão do ReDoc, incluindo um `x-logo` personalizado ao "objeto" `info` no esquema OpenAPI:
+
+```Python hl_lines="22-24"
+{!../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Armazenar em cache o esquema OpenAPI
+
+Você pode usar a propriedade `.openapi_schema` como um "cache" para armazenar o esquema gerado.
+
+Dessa forma, sua aplicação não precisará gerar o esquema toda vez que um usuário abrir a documentação da sua API.
+
+Ele será gerado apenas uma vez, e o mesmo esquema armazenado em cache será utilizado nas próximas requisições.
+
+```Python hl_lines="13-14 25-26"
+{!../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Sobrescrever o método
+
+Agora, você pode substituir o método `.openapi()` pela sua nova função.
+
+```Python hl_lines="29"
+{!../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Verificar
+
+Uma vez que você acessar http://127.0.0.1:8000/redoc, verá que está usando seu logo personalizado (neste exemplo, o logo do **FastAPI**):
+
+
diff --git a/docs/pt/docs/how-to/graphql.md b/docs/pt/docs/how-to/graphql.md
new file mode 100644
index 000000000..250135e23
--- /dev/null
+++ b/docs/pt/docs/how-to/graphql.md
@@ -0,0 +1,62 @@
+# GraphQL
+
+Como o **FastAPI** é baseado no padrão **ASGI**, é muito fácil integrar qualquer biblioteca **GraphQL** também compatível com ASGI.
+
+Você pode combinar *operações de rota* normais do FastAPI com GraphQL na mesma aplicação.
+
+/// tip | Dica
+
+**GraphQL** resolve alguns casos de uso muito específicos.
+
+Ele tem **vantagens** e **desvantagens** quando comparado a **web APIs** comuns.
+
+Certifique-se de avaliar se os **benefícios** para o seu caso de uso compensam as **desvantagens**. 🤓
+
+///
+
+## Bibliotecas GraphQL
+
+Aqui estão algumas das bibliotecas **GraphQL** que têm suporte **ASGI**. Você pode usá-las com **FastAPI**:
+
+* Strawberry 🍓
+ * Com docs para FastAPI
+* Ariadne
+ * Com docs para FastAPI
+* Tartiflette
+ * Com Tartiflette ASGI para fornecer integração ASGI
+* Graphene
+ * Com starlette-graphene3
+
+## GraphQL com Strawberry
+
+Se você precisar ou quiser trabalhar com **GraphQL**, **Strawberry** é a biblioteca **recomendada** pois tem o design mais próximo ao design do **FastAPI**, ela é toda baseada em **type annotations**.
+
+Dependendo do seu caso de uso, você pode preferir usar uma biblioteca diferente, mas se você me perguntasse, eu provavelmente sugeriria que você experimentasse o **Strawberry**.
+
+Aqui está uma pequena prévia de como você poderia integrar Strawberry com FastAPI:
+
+```Python hl_lines="3 22 25-26"
+{!../../docs_src/graphql/tutorial001.py!}
+```
+
+Você pode aprender mais sobre Strawberry na documentação do Strawberry.
+
+E também na documentação sobre Strawberry com FastAPI.
+
+## Antigo `GraphQLApp` do Starlette
+
+Versões anteriores do Starlette incluiam uma classe `GraphQLApp` para integrar com Graphene.
+
+Ela foi descontinuada do Starlette, mas se você tem código que a utilizava, você pode facilmente **migrar** para starlette-graphene3, que cobre o mesmo caso de uso e tem uma **interface quase idêntica**.
+
+/// tip | Dica
+
+Se você precisa de GraphQL, eu ainda recomendaria que você desse uma olhada no Strawberry, pois ele é baseado em type annotations em vez de classes e tipos personalizados.
+
+///
+
+## Saiba Mais
+
+Você pode aprender mais sobre **GraphQL** na documentação oficial do GraphQL.
+
+Você também pode ler mais sobre cada uma das bibliotecas descritas acima em seus links.
diff --git a/docs/pt/docs/how-to/separate-openapi-schemas.md b/docs/pt/docs/how-to/separate-openapi-schemas.md
new file mode 100644
index 000000000..50d321d4c
--- /dev/null
+++ b/docs/pt/docs/how-to/separate-openapi-schemas.md
@@ -0,0 +1,258 @@
+# Esquemas OpenAPI Separados para Entrada e Saída ou Não
+
+Ao usar **Pydantic v2**, o OpenAPI gerado é um pouco mais exato e **correto** do que antes. 😎
+
+Inclusive, em alguns casos, ele terá até **dois JSON Schemas** no OpenAPI para o mesmo modelo Pydantic, para entrada e saída, dependendo se eles possuem **valores padrão**.
+
+Vamos ver como isso funciona e como alterar se for necessário.
+
+## Modelos Pydantic para Entrada e Saída
+
+Digamos que você tenha um modelo Pydantic com valores padrão, como este:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="7"
+{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
+
+# Code below omitted 👇
+```
+
+
+
+
+
+
+
-Com isso, você pode rolar, vendo as opções, até encontrar o que "toca uma campainha":
+Com isso, você pode rolar, vendo as opções, até encontrar o que "soa familiar":
## Mais motivação
-Marque esta função, ela já possui type hints:
+Verifique esta função, ela já possui type hints:
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
-```
+{* ../../docs_src/python_types/tutorial003.py hl[1] *}
-Como o editor conhece os tipos de variáveis, você não apenas obtém a conclusão, mas também as verificações de erro:
+Como o editor conhece os tipos de variáveis, você não obtém apenas o preenchimento automático, mas também as verificações de erro:
-Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str (age)`:
+Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`:
-```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
-```
+{* ../../docs_src/python_types/tutorial004.py hl[2] *}
-## Tipos de declaração
+## Declarando Tipos
Você acabou de ver o local principal para declarar type hints. Como parâmetros de função.
@@ -143,47 +133,83 @@ Você pode usar, por exemplo:
* `bool`
* `bytes`
-```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
-```
+{* ../../docs_src/python_types/tutorial005.py hl[1] *}
### Tipos genéricos com parâmetros de tipo
Existem algumas estruturas de dados que podem conter outros valores, como `dict`, `list`, `set` e `tuple`. E os valores internos também podem ter seu próprio tipo.
-Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão `typing`.
+Estes tipos que possuem tipos internos são chamados de tipos "**genéricos**". E é possível declará-los mesmo com os seus tipos internos.
-Ele existe especificamente para suportar esses type hints.
+Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão `typing`. Ele existe especificamente para suportar esses type hints.
-#### `List`
+#### Versões mais recentes do Python
-Por exemplo, vamos definir uma variável para ser uma `lista` de `str`.
+A sintaxe utilizando `typing` é **compatível** com todas as versões, desde o Python 3.6 até as últimas, incluindo o Python 3.9, 3.10, etc.
-Em `typing`, importe `List` (com um `L` maiúsculo):
+Conforme o Python evolui, **novas versões** chegam com suporte melhorado para esses type annotations, e em muitos casos, você não precisará nem importar e utilizar o módulo `typing` para declarar os type annotations.
+
+Se você pode escolher uma versão mais recente do Python para o seu projeto, você poderá aproveitar isso ao seu favor.
+
+Em todos os documentos existem exemplos compatíveis com cada versão do Python (quando existem diferenças).
+
+Por exemplo, "**Python 3.6+**" significa que é compatível com o Python 3.6 ou superior (incluindo o 3.7, 3.8, 3.9, 3.10, etc). E "**Python 3.9+**" significa que é compatível com o Python 3.9 ou mais recente (incluindo o 3.10, etc).
+
+Se você pode utilizar a **versão mais recente do Python**, utilize os exemplos para as últimas versões. Eles terão as **melhores e mais simples sintaxes**, como por exemplo, "**Python 3.10+**".
+
+#### List
+
+Por exemplo, vamos definir uma variável para ser uma `list` de `str`.
+
+//// tab | Python 3.9+
+
+Declare uma variável com a mesma sintaxe com dois pontos (`:`)
+
+Como tipo, coloque `list`.
+
+Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial006.py!}
+{!> ../../docs_src/python_types/tutorial006_py39.py!}
```
-Declare a variável com a mesma sintaxe de dois pontos (`:`).
+////
-Como o tipo, coloque a `List`.
+//// tab | Python 3.8+
-Como a lista é um tipo que contém alguns tipos internos, você os coloca entre colchetes:
+De `typing`, importe `List` (com o `L` maiúsculo):
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial006.py!}
+```
+
+Declare uma variável com a mesma sintaxe com dois pontos (`:`)
+
+Como tipo, coloque o `List` que você importou de `typing`.
+
+Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
```Python hl_lines="4"
-{!../../../docs_src/python_types/tutorial006.py!}
+{!> ../../docs_src/python_types/tutorial006.py!}
```
-/// tip | "Dica"
+////
-Esses tipos internos entre colchetes são chamados de "parâmetros de tipo".
+/// info | Informação
-Nesse caso, `str` é o parâmetro de tipo passado para `List`.
+Estes tipos internos dentro dos colchetes são chamados "parâmetros de tipo" (type parameters).
+
+Neste caso, `str` é o parâmetro de tipo passado para `List` (ou `list` no Python 3.9 ou superior).
///
-Isso significa que: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`".
+Isso significa: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`".
+
+/// tip | Dica
+
+Se você usa o Python 3.9 ou superior, você não precisa importar `List` de `typing`. Você pode utilizar o mesmo tipo `list` no lugar.
+
+///
Ao fazer isso, seu editor pode fornecer suporte mesmo durante o processamento de itens da lista:
@@ -195,20 +221,32 @@ Observe que a variável `item` é um dos elementos da lista `items`.
E, ainda assim, o editor sabe que é um `str` e fornece suporte para isso.
-#### `Tuple` e `Set`
+#### Tuple e Set
Você faria o mesmo para declarar `tuple`s e `set`s:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial007.py!}
+//// 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!}
+```
+
+////
+
Isso significa que:
* A variável `items_t` é uma `tuple` com 3 itens, um `int`, outro `int` e uma `str`.
* A variável `items_s` é um `set`, e cada um de seus itens é do tipo `bytes`.
-#### `Dict`
+#### Dict
Para definir um `dict`, você passa 2 parâmetros de tipo, separados por vírgulas.
@@ -216,38 +254,181 @@ O primeiro parâmetro de tipo é para as chaves do `dict`.
O segundo parâmetro de tipo é para os valores do `dict`:
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial008.py!}
+//// 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!}
+```
+
+////
+
Isso significa que:
* A variável `prices` é um dict`:
* As chaves deste `dict` são do tipo `str` (digamos, o nome de cada item).
* Os valores deste `dict` são do tipo `float` (digamos, o preço de cada item).
-#### `Opcional`
+#### Union
-Você também pode usar o `Opcional` para declarar que uma variável tem um tipo, como `str`, mas que é "opcional", o que significa que também pode ser `None`:
+Você pode declarar que uma variável pode ser de qualquer um dentre **diversos tipos**. Por exemplo, um `int` ou um `str`.
-```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+No Python 3.6 e superior (incluindo o Python 3.10), você pode utilizar o tipo `Union` de `typing`, e colocar dentro dos colchetes os possíveis tipos aceitáveis.
+
+No Python 3.10 também existe uma **nova sintaxe** onde você pode colocar os possívels tipos separados por uma barra vertical (`|`).
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
-O uso de `Opcional [str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial008b.py!}
+```
+
+////
+
+Em ambos os casos, isso significa que `item` poderia ser um `int` ou um `str`.
+
+
+#### Possívelmente `None`
+
+Você pode declarar que um valor pode ter um tipo, como `str`, mas que ele também pode ser `None`.
+
+No Python 3.6 e superior (incluindo o Python 3.10) você pode declará-lo importando e utilizando `Optional` do módulo `typing`.
+
+```Python hl_lines="1 4"
+{!../../docs_src/python_types/tutorial009.py!}
+```
+
+O uso de `Optional[str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
+
+`Optional[Something]` é na verdade um atalho para `Union[Something, None]`, eles são equivalentes.
+
+Isso também significa que no Python 3.10, você pode utilizar `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+ alternative
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial009b.py!}
+```
+
+////
+
+#### Utilizando `Union` ou `Optional`
+
+Se você está utilizando uma versão do Python abaixo da 3.10, aqui vai uma dica do meu ponto de vista bem **subjetivo**:
+
+* 🚨 Evite utilizar `Optional[SomeType]`
+* No lugar, ✨ **use `Union[SomeType, None]`** ✨.
+
+Ambos são equivalentes, e no final das contas, eles são o mesmo. Mas eu recomendaria o `Union` ao invés de `Optional` porque a palavra **Optional** parece implicar que o valor é opcional, quando na verdade significa "isso pode ser `None`", mesmo que ele não seja opcional e ainda seja obrigatório.
+
+Eu penso que `Union[SomeType, None]` é mais explícito sobre o que ele significa.
+
+Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os seus colegas de trabalho pensam sobre o código.
+
+Por exemplo, vamos pegar esta função:
+
+{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+
+O paâmetro `name` é definido como `Optional[str]`, mas ele **não é opcional**, você não pode chamar a função sem o parâmetro:
+
+```Python
+say_hi() # Oh, no, this throws an error! 😱
+```
+
+O parâmetro `name` **ainda é obrigatório** (não *opicional*) porque ele não possui um valor padrão. Mesmo assim, `name` aceita `None` como valor:
+
+```Python
+say_hi(name=None) # This works, None is valid 🎉
+```
+
+A boa notícia é, quando você estiver no Python 3.10 você não precisará se preocupar mais com isso, pois você poderá simplesmente utilizar o `|` para definir uniões de tipos:
+
+{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
+
+E então você não precisará mais se preocupar com nomes como `Optional` e `Union`. 😎
#### Tipos genéricos
-Esses tipos que usam parâmetros de tipo entre colchetes, como:
+Esses tipos que usam parâmetros de tipo entre colchetes são chamados **tipos genéricos** ou **genéricos**. Por exemplo:
+
+//// tab | Python 3.10+
+
+Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+E o mesmo como no Python 3.8, do módulo `typing`:
+
+* `Union`
+* `Optional` (o mesmo que com o 3.8)
+* ...entro outros.
+
+No Python 3.10, como uma alternativa para a utilização dos genéricos `Union` e `Optional`, você pode usar a barra vertical (`|`) para declarar uniões de tipos. Isso é muito melhor e mais simples.
+
+////
+
+//// tab | Python 3.9+
+
+Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+E o mesmo como no Python 3.8, do módulo `typing`:
+
+* `Union`
+* `Optional`
+* ...entro outros.
+
+////
+
+//// tab | Python 3.8+
* `List`
* `Tuple`
* `Set`
* `Dict`
-* `Opcional`
-* ...e outros.
+* `Union`
+* `Optional`
+* ...entro outros.
-são chamados **tipos genéricos** ou **genéricos**.
+////
### Classes como tipos
@@ -255,23 +436,23 @@ Você também pode declarar uma classe como o tipo de uma variável.
Digamos que você tenha uma classe `Person`, com um nome:
-```Python hl_lines="1 2 3"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
Então você pode declarar que uma variável é do tipo `Person`:
-```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
-```
+{* ../../docs_src/python_types/tutorial010.py hl[6] *}
E então, novamente, você recebe todo o suporte do editor:
+Perceba que isso significa que "`one_person` é uma **instância** da classe `Person`".
+
+Isso não significa que "`one_person` é a **classe** chamada `Person`".
+
## Modelos Pydantic
- Pydantic é uma biblioteca Python para executar a validação de dados.
+O Pydantic é uma biblioteca Python para executar a validação de dados.
Você declara a "forma" dos dados como classes com atributos.
@@ -283,21 +464,93 @@ E você recebe todo o suporte do editor com esse objeto resultante.
Retirado dos documentos oficiais dos Pydantic:
+//// tab | Python 3.10+
+
```Python
-{!../../../docs_src/python_types/tutorial011.py!}
+{!> ../../docs_src/python_types/tutorial011_py310.py!}
```
-/// info | "Informação"
+////
-Para saber mais sobre o Pydantic, verifique seus documentos .
+//// tab | Python 3.9+
+
+```Python
+{!> ../../docs_src/python_types/tutorial011_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python
+{!> ../../docs_src/python_types/tutorial011.py!}
+```
+
+////
+
+/// info | Informação
+
+Para saber mais sobre o Pydantic, verifique a sua documentação.
///
-**FastAPI** é todo baseado em Pydantic.
+O **FastAPI** é todo baseado em Pydantic.
Você verá muito mais disso na prática no [Tutorial - Guia do usuário](tutorial/index.md){.internal-link target=_blank}.
-## Type hints em **FastAPI**
+/// tip | Dica
+
+O Pydantic tem um comportamento especial quando você usa `Optional` ou `Union[Something, None]` sem um valor padrão. Você pode ler mais sobre isso na documentação do Pydantic sobre campos Opcionais Obrigatórios.
+
+///
+
+
+## Type Hints com Metadados de Anotações
+
+O Python possui uma funcionalidade que nos permite incluir **metadados adicionais** nos type hints utilizando `Annotated`.
+
+//// tab | Python 3.9+
+
+No Python 3.9, `Annotated` é parte da biblioteca padrão, então você pode importá-lo de `typing`.
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial013_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+Em versões abaixo do Python 3.9, você importa `Annotated` de `typing_extensions`.
+
+Ele já estará instalado com o **FastAPI**.
+
+```Python hl_lines="1 4"
+{!> ../../docs_src/python_types/tutorial013.py!}
+```
+
+////
+
+O Python em si não faz nada com este `Annotated`. E para editores e outras ferramentas, o tipo ainda é `str`.
+
+Mas você pode utilizar este espaço dentro do `Annotated` para fornecer ao **FastAPI** metadata adicional sobre como você deseja que a sua aplicação se comporte.
+
+O importante aqui de se lembrar é que **o primeiro *type parameter*** que você informar ao `Annotated` é o **tipo de fato**. O resto é apenas metadado para outras ferramentas.
+
+Por hora, você precisa apenas saber que o `Annotated` existe, e que ele é Python padrão. 😎
+
+Mais tarde você verá o quão **poderoso** ele pode ser.
+
+/// tip | Dica
+
+O fato de que isso é **Python padrão** significa que você ainda obtém a **melhor experiência de desenvolvedor possível** no seu editor, com as ferramentas que você utiliza para analisar e refatorar o seu código, etc. ✨
+
+E também que o seu código será muito compatível com diversas outras ferramentas e bibliotecas Python. 🚀
+
+///
+
+
+## Type hints no **FastAPI**
O **FastAPI** aproveita esses type hints para fazer várias coisas.
@@ -306,20 +559,20 @@ Com o **FastAPI**, você declara parâmetros com type hints e obtém:
* **Suporte ao editor**.
* **Verificações de tipo**.
-... e **FastAPI** usa as mesmas declarações para:
+... e o **FastAPI** usa as mesmas declarações para:
-* **Definir requisitos**: dos parâmetros do caminho da solicitação, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
+* **Definir requisitos**: dos parâmetros de rota, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
* **Converter dados**: da solicitação para o tipo necessário.
* **Validar dados**: provenientes de cada solicitação:
- * A geração de **erros automáticos** retornou ao cliente quando os dados são inválidos.
-* **Documente** a API usando OpenAPI:
+ * Gerando **erros automáticos** retornados ao cliente quando os dados são inválidos.
+* **Documentar** a API usando OpenAPI:
* que é usado pelas interfaces de usuário da documentação interativa automática.
Tudo isso pode parecer abstrato. Não se preocupe. Você verá tudo isso em ação no [Tutorial - Guia do usuário](tutorial/index.md){.internal-link target=_blank}.
O importante é que, usando tipos padrão de Python, em um único local (em vez de adicionar mais classes, decoradores, etc.), o **FastAPI** fará muito trabalho para você.
-/// info | "Informação"
+/// info | Informação
Se você já passou por todo o tutorial e voltou para ver mais sobre os tipos, um bom recurso é a "cheat sheet" do `mypy` .
diff --git a/docs/pt/docs/tutorial/background-tasks.md b/docs/pt/docs/tutorial/background-tasks.md
index 625fa2b11..6a69ae2af 100644
--- a/docs/pt/docs/tutorial/background-tasks.md
+++ b/docs/pt/docs/tutorial/background-tasks.md
@@ -15,9 +15,7 @@ Isso inclui, por exemplo:
Primeiro, importe `BackgroundTasks` e defina um parâmetro em sua _função de operação de caminho_ com uma declaração de tipo de `BackgroundTasks`:
-```Python hl_lines="1 13"
-{!../../../docs_src/background_tasks/tutorial001.py!}
-```
+{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
O **FastAPI** criará o objeto do tipo `BackgroundTasks` para você e o passará como esse parâmetro.
@@ -33,17 +31,13 @@ Nesse caso, a função de tarefa gravará em um arquivo (simulando o envio de um
E como a operação de gravação não usa `async` e `await`, definimos a função com `def` normal:
-```Python hl_lines="6-9"
-{!../../../docs_src/background_tasks/tutorial001.py!}
-```
+{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
## Adicionar a tarefa em segundo plano
Dentro de sua _função de operação de caminho_, passe sua função de tarefa para o objeto _tarefas em segundo plano_ com o método `.add_task()`:
-```Python hl_lines="14"
-{!../../../docs_src/background_tasks/tutorial001.py!}
-```
+{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
`.add_task()` recebe como argumentos:
@@ -57,9 +51,7 @@ Usar `BackgroundTasks` também funciona com o sistema de injeção de dependênc
O **FastAPI** sabe o que fazer em cada caso e como reutilizar o mesmo objeto, de forma que todas as tarefas em segundo plano sejam mescladas e executadas em segundo plano posteriormente:
-```Python hl_lines="13 15 22 25"
-{!../../../docs_src/background_tasks/tutorial002.py!}
-```
+{* ../../docs_src/background_tasks/tutorial002.py hl[13,15,22,25] *}
Neste exemplo, as mensagens serão gravadas no arquivo `log.txt` _após_ o envio da resposta.
diff --git a/docs/pt/docs/tutorial/bigger-applications.md b/docs/pt/docs/tutorial/bigger-applications.md
index 7137bf865..a094005fd 100644
--- a/docs/pt/docs/tutorial/bigger-applications.md
+++ b/docs/pt/docs/tutorial/bigger-applications.md
@@ -4,7 +4,7 @@ Se você está construindo uma aplicação ou uma API web, é raro que você pos
**FastAPI** oferece uma ferramenta conveniente para estruturar sua aplicação, mantendo toda a flexibilidade.
-/// info | "Informação"
+/// info | Informação
Se você vem do Flask, isso seria o equivalente aos Blueprints do Flask.
@@ -29,7 +29,7 @@ Digamos que você tenha uma estrutura de arquivos como esta:
│ └── admin.py
```
-/// tip | "Dica"
+/// tip | Dica
Existem vários arquivos `__init__.py` presentes em cada diretório ou subdiretório.
@@ -86,7 +86,7 @@ Você pode criar as *operações de rotas* para esse módulo usando o `APIRouter
você o importa e cria uma "instância" da mesma maneira que faria com a classe `FastAPI`:
```Python hl_lines="1 3" title="app/routers/users.py"
-{!../../../docs_src/bigger_applications/app/routers/users.py!}
+{!../../docs_src/bigger_applications/app/routers/users.py!}
```
### *Operações de Rota* com `APIRouter`
@@ -96,7 +96,7 @@ E então você o utiliza para declarar suas *operações de rota*.
Utilize-o da mesma maneira que utilizaria a classe `FastAPI`:
```Python hl_lines="6 11 16" title="app/routers/users.py"
-{!../../../docs_src/bigger_applications/app/routers/users.py!}
+{!../../docs_src/bigger_applications/app/routers/users.py!}
```
Você pode pensar em `APIRouter` como uma classe "mini `FastAPI`".
@@ -105,7 +105,7 @@ Todas as mesmas opções são suportadas.
Todos os mesmos `parameters`, `responses`, `dependencies`, `tags`, etc.
-/// tip | "Dica"
+/// tip | Dica
Neste exemplo, a variável é chamada de `router`, mas você pode nomeá-la como quiser.
@@ -124,7 +124,7 @@ Agora usaremos uma dependência simples para ler um cabeçalho `X-Token` persona
//// tab | Python 3.9+
```Python hl_lines="3 6-8" title="app/dependencies.py"
-{!> ../../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
+{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
```
////
@@ -132,26 +132,26 @@ Agora usaremos uma dependência simples para ler um cabeçalho `X-Token` persona
//// tab | Python 3.8+
```Python hl_lines="1 5-7" title="app/dependencies.py"
-{!> ../../../docs_src/bigger_applications/app_an/dependencies.py!}
+{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Prefira usar a versão `Annotated` se possível.
///
```Python hl_lines="1 4-6" title="app/dependencies.py"
-{!> ../../../docs_src/bigger_applications/app/dependencies.py!}
+{!> ../../docs_src/bigger_applications/app/dependencies.py!}
```
////
-/// tip | "Dica"
+/// tip | Dica
Estamos usando um cabeçalho inventado para simplificar este exemplo.
@@ -182,7 +182,7 @@ Sabemos que todas as *operações de rota* neste módulo têm o mesmo:
Então, em vez de adicionar tudo isso a cada *operação de rota*, podemos adicioná-lo ao `APIRouter`.
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
-{!../../../docs_src/bigger_applications/app/routers/items.py!}
+{!../../docs_src/bigger_applications/app/routers/items.py!}
```
Como o caminho de cada *operação de rota* deve começar com `/`, como em:
@@ -201,7 +201,7 @@ Também podemos adicionar uma lista de `tags` e `responses` extras que serão ap
E podemos adicionar uma lista de `dependencies` que serão adicionadas a todas as *operações de rota* no roteador e serão executadas/resolvidas para cada solicitação feita a elas.
-/// tip | "Dica"
+/// tip | Dica
Observe que, assim como [dependências em *decoradores de operação de rota*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, nenhum valor será passado para sua *função de operação de rota*.
@@ -222,7 +222,7 @@ O resultado final é que os caminhos dos itens agora são:
* As dependências do roteador são executadas primeiro, depois as [`dependencies` no decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} e, em seguida, as dependências de parâmetros normais.
* Você também pode adicionar [dependências de `Segurança` com `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
-/// tip | "Dica"
+/// tip | Dica
Ter `dependências` no `APIRouter` pode ser usado, por exemplo, para exigir autenticação para um grupo inteiro de *operações de rota*. Mesmo que as dependências não sejam adicionadas individualmente a cada uma delas.
@@ -243,12 +243,12 @@ E precisamos obter a função de dependência do módulo `app.dependencies`, o a
Então usamos uma importação relativa com `..` para as dependências:
```Python hl_lines="3" title="app/routers/items.py"
-{!../../../docs_src/bigger_applications/app/routers/items.py!}
+{!../../docs_src/bigger_applications/app/routers/items.py!}
```
#### Como funcionam as importações relativas
-/// tip | "Dica"
+/// tip | Dica
Se você sabe perfeitamente como funcionam as importações, continue para a próxima seção abaixo.
@@ -316,10 +316,10 @@ Não estamos adicionando o prefixo `/items` nem `tags=["items"]` a cada *operaç
Mas ainda podemos adicionar _mais_ `tags` que serão aplicadas a uma *operação de rota* específica, e também algumas `respostas` extras específicas para essa *operação de rota*:
```Python hl_lines="30-31" title="app/routers/items.py"
-{!../../../docs_src/bigger_applications/app/routers/items.py!}
+{!../../docs_src/bigger_applications/app/routers/items.py!}
```
-/// tip | "Dica"
+/// tip | Dica
Esta última operação de caminho terá a combinação de tags: `["items", "custom"]`.
@@ -344,7 +344,7 @@ Você importa e cria uma classe `FastAPI` normalmente.
E podemos até declarar [dependências globais](dependencies/global-dependencies.md){.internal-link target=_blank} que serão combinadas com as dependências para cada `APIRouter`:
```Python hl_lines="1 3 7" title="app/main.py"
-{!../../../docs_src/bigger_applications/app/main.py!}
+{!../../docs_src/bigger_applications/app/main.py!}
```
### Importe o `APIRouter`
@@ -352,7 +352,7 @@ E podemos até declarar [dependências globais](dependencies/global-dependencies
Agora importamos os outros submódulos que possuem `APIRouter`s:
```Python hl_lines="4-5" title="app/main.py"
-{!../../../docs_src/bigger_applications/app/main.py!}
+{!../../docs_src/bigger_applications/app/main.py!}
```
Como os arquivos `app/routers/users.py` e `app/routers/items.py` são submódulos que fazem parte do mesmo pacote Python `app`, podemos usar um único ponto `.` para importá-los usando "importações relativas".
@@ -381,7 +381,7 @@ Também poderíamos importá-los como:
from app.routers import items, users
```
-/// info | "Informação"
+/// info | Informação
A primeira versão é uma "importação relativa":
@@ -417,7 +417,7 @@ o `router` de `users` sobrescreveria o de `items` e não poderíamos usá-los ao
Então, para poder usar ambos no mesmo arquivo, importamos os submódulos diretamente:
```Python hl_lines="5" title="app/main.py"
-{!../../../docs_src/bigger_applications/app/main.py!}
+{!../../docs_src/bigger_applications/app/main.py!}
```
### Incluir o `APIRouter`s para `usuários` e `itens`
@@ -425,10 +425,10 @@ Então, para poder usar ambos no mesmo arquivo, importamos os submódulos direta
Agora, vamos incluir os `roteadores` dos submódulos `usuários` e `itens`:
```Python hl_lines="10-11" title="app/main.py"
-{!../../../docs_src/bigger_applications/app/main.py!}
+{!../../docs_src/bigger_applications/app/main.py!}
```
-/// info | "Informação"
+/// info | Informação
`users.router` contém o `APIRouter` dentro do arquivo `app/routers/users.py`.
@@ -440,7 +440,7 @@ Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo prin
Ele incluirá todas as rotas daquele roteador como parte dele.
-/// note | "Detalhe Técnico"
+/// note | Detalhe Técnico
Na verdade, ele criará internamente uma *operação de rota* para cada *operação de rota* que foi declarada no `APIRouter`.
@@ -467,7 +467,7 @@ Ele contém um `APIRouter` com algumas *operações de rota* de administração
Para este exemplo, será super simples. Mas digamos que, como ele é compartilhado com outros projetos na organização, não podemos modificá-lo e adicionar um `prefix`, `dependencies`, `tags`, etc. diretamente ao `APIRouter`:
```Python hl_lines="3" title="app/internal/admin.py"
-{!../../../docs_src/bigger_applications/app/internal/admin.py!}
+{!../../docs_src/bigger_applications/app/internal/admin.py!}
```
Mas ainda queremos definir um `prefixo` personalizado ao incluir o `APIRouter` para que todas as suas *operações de rota* comecem com `/admin`, queremos protegê-lo com as `dependências` que já temos para este projeto e queremos incluir `tags` e `responses`.
@@ -475,7 +475,7 @@ Mas ainda queremos definir um `prefixo` personalizado ao incluir o `APIRouter` p
Podemos declarar tudo isso sem precisar modificar o `APIRouter` original passando esses parâmetros para `app.include_router()`:
```Python hl_lines="14-17" title="app/main.py"
-{!../../../docs_src/bigger_applications/app/main.py!}
+{!../../docs_src/bigger_applications/app/main.py!}
```
Dessa forma, o `APIRouter` original permanecerá inalterado, para que possamos compartilhar o mesmo arquivo `app/internal/admin.py` com outros projetos na organização.
@@ -498,12 +498,12 @@ Também podemos adicionar *operações de rota* diretamente ao aplicativo `FastA
Aqui fazemos isso... só para mostrar que podemos 🤷:
```Python hl_lines="21-23" title="app/main.py"
-{!../../../docs_src/bigger_applications/app/main.py!}
+{!../../docs_src/bigger_applications/app/main.py!}
```
e funcionará corretamente, junto com todas as outras *operações de rota* adicionadas com `app.include_router()`.
-/// info | "Detalhes Técnicos"
+/// info | Detalhes Técnicos
**Observação**: este é um detalhe muito técnico que você provavelmente pode **simplesmente pular**.
diff --git a/docs/pt/docs/tutorial/body-fields.md b/docs/pt/docs/tutorial/body-fields.md
index cce37cd55..ac0b85ab5 100644
--- a/docs/pt/docs/tutorial/body-fields.md
+++ b/docs/pt/docs/tutorial/body-fields.md
@@ -7,10 +7,10 @@ Da mesma forma que você pode declarar validações adicionais e metadados nos p
Primeiro, você tem que importá-lo:
```Python hl_lines="4"
-{!../../../docs_src/body_fields/tutorial001.py!}
+{!../../docs_src/body_fields/tutorial001.py!}
```
-/// warning | "Aviso"
+/// warning | Aviso
Note que `Field` é importado diretamente do `pydantic`, não do `fastapi` como todo o resto (`Query`, `Path`, `Body`, etc).
@@ -21,12 +21,12 @@ Note que `Field` é importado diretamente do `pydantic`, não do `fastapi` como
Você pode então utilizar `Field` com atributos do modelo:
```Python hl_lines="11-14"
-{!../../../docs_src/body_fields/tutorial001.py!}
+{!../../docs_src/body_fields/tutorial001.py!}
```
`Field` funciona da mesma forma que `Query`, `Path` e `Body`, ele possui todos os mesmos parâmetros, etc.
-/// note | "Detalhes técnicos"
+/// note | Detalhes técnicos
Na realidade, `Query`, `Path` e outros que você verá em seguida, criam objetos de subclasses de uma classe `Param` comum, que é ela mesma uma subclasse da classe `FieldInfo` do Pydantic.
@@ -38,7 +38,7 @@ Lembre-se que quando você importa `Query`, `Path`, e outros de `fastapi`, esse
///
-/// tip | "Dica"
+/// tip | Dica
Note como cada atributo do modelo com um tipo, valor padrão e `Field` possuem a mesma estrutura que parâmetros de *funções de operações de rota*, com `Field` ao invés de `Path`, `Query` e `Body`.
diff --git a/docs/pt/docs/tutorial/body-multiple-params.md b/docs/pt/docs/tutorial/body-multiple-params.md
index d36dd60b3..ad4931b11 100644
--- a/docs/pt/docs/tutorial/body-multiple-params.md
+++ b/docs/pt/docs/tutorial/body-multiple-params.md
@@ -11,7 +11,7 @@ E você também pode declarar parâmetros de corpo como opcionais, definindo o v
//// tab | Python 3.10+
```Python hl_lines="17-19"
-{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
+{!> ../../docs_src/body_multiple_params/tutorial001_py310.py!}
```
////
@@ -19,12 +19,12 @@ E você também pode declarar parâmetros de corpo como opcionais, definindo o v
//// tab | Python 3.8+
```Python hl_lines="19-21"
-{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
+{!> ../../docs_src/body_multiple_params/tutorial001.py!}
```
////
-/// note | "Nota"
+/// note | Nota
Repare que, neste caso, o `item` que seria capturado a partir do corpo é opcional. Visto que ele possui `None` como valor padrão.
@@ -48,7 +48,7 @@ Mas você pode também declarar múltiplos parâmetros de corpo, por exemplo, `i
//// tab | Python 3.10+
```Python hl_lines="20"
-{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
+{!> ../../docs_src/body_multiple_params/tutorial002_py310.py!}
```
////
@@ -56,7 +56,7 @@ Mas você pode também declarar múltiplos parâmetros de corpo, por exemplo, `i
//// tab | Python 3.8+
```Python hl_lines="22"
-{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
+{!> ../../docs_src/body_multiple_params/tutorial002.py!}
```
////
@@ -80,7 +80,7 @@ Então, ele usará o nome dos parâmetros como chaves (nome dos campos) no corpo
}
```
-/// note | "Nota"
+/// note | Nota
Repare que mesmo que o `item` esteja declarado da mesma maneira que antes, agora é esperado que ele esteja dentro do corpo com uma chave `item`.
@@ -103,7 +103,7 @@ Mas você pode instruir o **FastAPI** para tratá-lo como outra chave do corpo u
//// tab | Python 3.8+
```Python hl_lines="22"
-{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
+{!> ../../docs_src/body_multiple_params/tutorial003.py!}
```
////
@@ -111,7 +111,7 @@ Mas você pode instruir o **FastAPI** para tratá-lo como outra chave do corpo u
//// tab | Python 3.10+
```Python hl_lines="20"
-{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
+{!> ../../docs_src/body_multiple_params/tutorial003_py310.py!}
```
////
@@ -157,7 +157,7 @@ Por exemplo:
//// tab | Python 3.10+
```Python hl_lines="26"
-{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
+{!> ../../docs_src/body_multiple_params/tutorial004_py310.py!}
```
////
@@ -165,12 +165,12 @@ Por exemplo:
//// tab | Python 3.8+
```Python hl_lines="27"
-{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
+{!> ../../docs_src/body_multiple_params/tutorial004.py!}
```
////
-/// info | "Informação"
+/// info | Informação
`Body` também possui todas as validações adicionais e metadados de parâmetros como em `Query`,`Path` e outras que você verá depois.
@@ -193,7 +193,7 @@ como em:
//// tab | Python 3.10+
```Python hl_lines="15"
-{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
+{!> ../../docs_src/body_multiple_params/tutorial005_py310.py!}
```
////
@@ -201,7 +201,7 @@ como em:
//// tab | Python 3.8+
```Python hl_lines="17"
-{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
+{!> ../../docs_src/body_multiple_params/tutorial005.py!}
```
////
diff --git a/docs/pt/docs/tutorial/body-nested-models.md b/docs/pt/docs/tutorial/body-nested-models.md
index 7d933b27f..bbe72a744 100644
--- a/docs/pt/docs/tutorial/body-nested-models.md
+++ b/docs/pt/docs/tutorial/body-nested-models.md
@@ -7,7 +7,7 @@ Com o **FastAPI**, você pode definir, validar, documentar e usar modelos profun
Você pode definir um atributo como um subtipo. Por exemplo, uma `list` do Python:
```Python hl_lines="14"
-{!../../../docs_src/body_nested_models/tutorial001.py!}
+{!../../docs_src/body_nested_models/tutorial001.py!}
```
Isso fará com que tags seja uma lista de itens mesmo sem declarar o tipo dos elementos desta lista.
@@ -21,7 +21,7 @@ Mas o Python tem uma maneira específica de declarar listas com tipos internos o
Primeiramente, importe `List` do módulo `typing` que já vem por padrão no Python:
```Python hl_lines="1"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
+{!../../docs_src/body_nested_models/tutorial002.py!}
```
### Declare a `List` com um parâmetro de tipo
@@ -45,7 +45,7 @@ Portanto, em nosso exemplo, podemos fazer com que `tags` sejam especificamente u
```Python hl_lines="14"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
+{!../../docs_src/body_nested_models/tutorial002.py!}
```
## Tipo "set"
@@ -59,7 +59,7 @@ Então podemos importar `Set` e declarar `tags` como um `set` de `str`s:
```Python hl_lines="1 14"
-{!../../../docs_src/body_nested_models/tutorial003.py!}
+{!../../docs_src/body_nested_models/tutorial003.py!}
```
Com isso, mesmo que você receba uma requisição contendo dados duplicados, ela será convertida em um conjunto de itens exclusivos.
@@ -83,7 +83,7 @@ Tudo isso, aninhado arbitrariamente.
Por exemplo, nós podemos definir um modelo `Image`:
```Python hl_lines="9-11"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
+{!../../docs_src/body_nested_models/tutorial004.py!}
```
### Use o sub-modelo como um tipo
@@ -91,7 +91,7 @@ Por exemplo, nós podemos definir um modelo `Image`:
E então podemos usa-lo como o tipo de um atributo:
```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
+{!../../docs_src/body_nested_models/tutorial004.py!}
```
Isso significa que o **FastAPI** vai esperar um corpo similar à:
@@ -126,7 +126,7 @@ Para ver todas as opções possíveis, cheque a documentação para osHTTP `PUT`.
+
+Você pode usar `jsonable_encoder` para converter os dados de entrada em dados que podem ser armazenados como JSON (por exemplo, com um banco de dados NoSQL). Por exemplo, convertendo `datetime` em `str`.
+
+//// tab | Python 3.10+
+
+```Python hl_lines="28-33"
+{!> ../../../docs_src/body_updates/tutorial001_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="30-35"
+{!> ../../../docs_src/body_updates/tutorial001_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="30-35"
+{!> ../../../docs_src/body_updates/tutorial001.py!}
+```
+
+////
+
+`PUT` é usado para receber dados que devem substituir os dados existentes.
+
+### Aviso sobre a substituição
+
+Isso significa que, se você quiser atualizar o item `bar` usando `PUT` com um corpo contendo:
+
+```Python
+{
+ "name": "Barz",
+ "price": 3,
+ "description": None,
+}
+```
+
+Como ele não inclui o atributo já armazenado `"tax": 20.2`, o modelo de entrada assumiria o valor padrão de `"tax": 10.5`.
+
+E os dados seriam salvos com esse "novo" `tax` de `10.5`.
+
+## Atualizações parciais com `PATCH`
+
+Você também pode usar a operação HTTP `PATCH` para *atualizar* parcialmente os dados.
+
+Isso significa que você pode enviar apenas os dados que deseja atualizar, deixando o restante intacto.
+
+/// note | Nota
+
+`PATCH` é menos comumente usado e conhecido do que `PUT`.
+
+E muitas equipes usam apenas `PUT`, mesmo para atualizações parciais.
+
+Você é **livre** para usá-los como preferir, **FastAPI** não impõe restrições.
+
+Mas este guia te dá uma ideia de como eles são destinados a serem usados.
+
+///
+
+### Usando o parâmetro `exclude_unset` do Pydantic
+
+Se você quiser receber atualizações parciais, é muito útil usar o parâmetro `exclude_unset` no método `.model_dump()` do modelo do Pydantic.
+
+Como `item.model_dump(exclude_unset=True)`.
+
+/// info | Informação
+
+No Pydantic v1, o método que era chamado `.dict()` e foi depreciado (mas ainda suportado) no Pydantic v2. Agora, deve-se usar o método `.model_dump()`.
+
+Os exemplos aqui usam `.dict()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_dump()` a partir do Pydantic v2.
+
+///
+
+Isso gera um `dict` com apenas os dados definidos ao criar o modelo `item`, excluindo os valores padrão.
+
+Então, você pode usar isso para gerar um `dict` com apenas os dados definidos (enviados na solicitação), omitindo valores padrão:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="32"
+{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="34"
+{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="34"
+{!> ../../../docs_src/body_updates/tutorial002.py!}
+```
+
+////
+
+### Usando o parâmetro `update` do Pydantic
+
+Agora, você pode criar uma cópia do modelo existente usando `.model_copy()`, e passar o parâmetro `update` com um `dict` contendo os dados para atualizar.
+
+/// info | Informação
+
+No Pydantic v1, o método era chamado `.copy()`, ele foi depreciado (mas ainda suportado) no Pydantic v2, e renomeado para `.model_copy()`.
+
+Os exemplos aqui usam `.copy()` para compatibilidade com o Pydantic v1, mas você deve usar `.model_copy()` com o Pydantic v2.
+
+///
+
+Como `stored_item_model.model_copy(update=update_data)`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="33"
+{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="35"
+{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="35"
+{!> ../../../docs_src/body_updates/tutorial002.py!}
+```
+
+////
+
+### Recapitulando as atualizações parciais
+
+Resumindo, para aplicar atualizações parciais você pode:
+
+* (Opcionalmente) usar `PATCH` em vez de `PUT`.
+* Recuperar os dados armazenados.
+* Colocar esses dados em um modelo do Pydantic.
+* Gerar um `dict` sem valores padrão a partir do modelo de entrada (usando `exclude_unset`).
+ * Dessa forma, você pode atualizar apenas os valores definidos pelo usuário, em vez de substituir os valores já armazenados com valores padrão em seu modelo.
+* Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`).
+* Converter o modelo copiado em algo que possa ser armazenado no seu banco de dados (por exemplo, usando o `jsonable_encoder`).
+ * Isso é comparável ao uso do método `.model_dump()`, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`.
+* Salvar os dados no seu banco de dados.
+* Retornar o modelo atualizado.
+
+//// tab | Python 3.10+
+
+```Python hl_lines="28-35"
+{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="30-37"
+{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="30-37"
+{!> ../../../docs_src/body_updates/tutorial002.py!}
+```
+
+////
+
+/// tip | Dica
+
+Você pode realmente usar essa mesma técnica com uma operação HTTP `PUT`.
+
+Mas o exemplo aqui usa `PATCH` porque foi criado para esses casos de uso.
+
+///
+
+/// note | Nota
+
+Observe que o modelo de entrada ainda é validado.
+
+Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, precisará ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`).
+
+Para distinguir os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/pt/docs/tutorial/body.md b/docs/pt/docs/tutorial/body.md
index f67687fb5..f3a1fda75 100644
--- a/docs/pt/docs/tutorial/body.md
+++ b/docs/pt/docs/tutorial/body.md
@@ -8,7 +8,7 @@ Sua API quase sempre irá enviar um corpo na **resposta**. Mas os clientes não
Para declarar um corpo da **requisição**, você utiliza os modelos do Pydantic com todos os seus poderes e benefícios.
-/// info | "Informação"
+/// info | Informação
Para enviar dados, você deve usar utilizar um dos métodos: `POST` (Mais comum), `PUT`, `DELETE` ou `PATCH`.
@@ -23,7 +23,7 @@ Como é desencorajado, a documentação interativa com Swagger UI não irá most
Primeiro, você precisa importar `BaseModel` do `pydantic`:
```Python hl_lines="4"
-{!../../../docs_src/body/tutorial001.py!}
+{!../../docs_src/body/tutorial001.py!}
```
## Crie seu modelo de dados
@@ -33,7 +33,7 @@ Então você declara seu modelo de dados como uma classe que herda `BaseModel`.
Utilize os tipos Python padrão para todos os atributos:
```Python hl_lines="7-11"
-{!../../../docs_src/body/tutorial001.py!}
+{!../../docs_src/body/tutorial001.py!}
```
Assim como quando declaramos parâmetros de consulta, quando um atributo do modelo possui um valor padrão, ele se torna opcional. Caso contrário, se torna obrigatório. Use `None` para torná-lo opcional.
@@ -63,7 +63,7 @@ Por exemplo, o modelo acima declara um JSON "`object`" (ou `dict` no Python) com
Para adicionar o corpo na *função de operação de rota*, declare-o da mesma maneira que você declarou parâmetros de rota e consulta:
```Python hl_lines="18"
-{!../../../docs_src/body/tutorial001.py!}
+{!../../docs_src/body/tutorial001.py!}
```
...E declare o tipo como o modelo que você criou, `Item`.
@@ -113,7 +113,7 @@ Mas você terá o mesmo suporte do editor no
-/// tip | "Dica"
+/// tip | Dica
Se você utiliza o PyCharm como editor, você pode utilizar o Plugin do Pydantic para o PyCharm .
@@ -132,7 +132,7 @@ Melhora o suporte do editor para seus modelos Pydantic com::
Dentro da função, você pode acessar todos os atributos do objeto do modelo diretamente:
```Python hl_lines="21"
-{!../../../docs_src/body/tutorial002.py!}
+{!../../docs_src/body/tutorial002.py!}
```
## Corpo da requisição + parâmetros de rota
@@ -142,7 +142,7 @@ Você pode declarar parâmetros de rota e corpo da requisição ao mesmo tempo.
O **FastAPI** irá reconhecer que os parâmetros da função que combinam com parâmetros de rota devem ser **retirados da rota**, e parâmetros da função que são declarados como modelos Pydantic sejam **retirados do corpo da requisição**.
```Python hl_lines="17-18"
-{!../../../docs_src/body/tutorial003.py!}
+{!../../docs_src/body/tutorial003.py!}
```
## Corpo da requisição + parâmetros de rota + parâmetros de consulta
@@ -152,7 +152,7 @@ Você também pode declarar parâmetros de **corpo**, **rota** e **consulta**, a
O **FastAPI** irá reconhecer cada um deles e retirar a informação do local correto.
```Python hl_lines="18"
-{!../../../docs_src/body/tutorial004.py!}
+{!../../docs_src/body/tutorial004.py!}
```
Os parâmetros da função serão reconhecidos conforme abaixo:
@@ -161,7 +161,7 @@ Os parâmetros da função serão reconhecidos conforme abaixo:
* Se o parâmetro é de um **tipo único** (como `int`, `float`, `str`, `bool`, etc) será interpretado como um parâmetro de **consulta**.
* Se o parâmetro é declarado como um **modelo Pydantic**, será interpretado como o **corpo** da requisição.
-/// note | "Observação"
+/// note | Observação
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
diff --git a/docs/pt/docs/tutorial/cookie-param-models.md b/docs/pt/docs/tutorial/cookie-param-models.md
new file mode 100644
index 000000000..671e0d74f
--- /dev/null
+++ b/docs/pt/docs/tutorial/cookie-param-models.md
@@ -0,0 +1,156 @@
+# Modelos de Parâmetros de Cookie
+
+Se você possui um grupo de **cookies** que estão relacionados, você pode criar um **modelo Pydantic** para declará-los. 🍪
+
+Isso lhe permitiria **reutilizar o modelo** em **diversos lugares** e também declarar validações e metadata para todos os parâmetros de uma vez. 😎
+
+/// note | Nota
+
+Isso é suportado desde a versão `0.115.0` do FastAPI. 🤓
+
+///
+
+/// tip | Dica
+
+Essa mesma técnica se aplica para `Query`, `Cookie`, e `Header`. 😎
+
+///
+
+## Cookies com Modelos Pydantic
+
+Declare o parâmetro de **cookie** que você precisa em um **modelo Pydantic**, e depois declare o parâmetro como um `Cookie`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="9-12 16"
+{!> ../../docs_src/cookie_param_models/tutorial001_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="9-12 16"
+{!> ../../docs_src/cookie_param_models/tutorial001_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="10-13 17"
+{!> ../../docs_src/cookie_param_models/tutorial001_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="7-10 14"
+{!> ../../docs_src/cookie_param_models/tutorial001_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="9-12 16"
+{!> ../../docs_src/cookie_param_models/tutorial001.py!}
+```
+
+////
+
+O **FastAPI** irá **extrair** os dados para **cada campo** dos **cookies** recebidos na requisição e lhe fornecer o modelo Pydantic que você definiu.
+
+## Verifique os Documentos
+
+Você pode ver os cookies definidos na IU dos documentos em `/docs`:
+
+
+
+
+---
+
+Se você usar o Pycharm, você pode:
+
+* Abrir o menu "Executar".
+* Selecionar a opção "Depurar...".
+* Então um menu de contexto aparece.
+* Selecionar o arquivo para depurar (neste caso, `main.py`).
+
+Em seguida, ele iniciará o servidor com seu código **FastAPI**, parará em seus pontos de interrupção, etc.
+
+Veja como pode parecer:
+
+
diff --git a/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md
index 420503b87..fcf71d08c 100644
--- a/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -9,7 +9,7 @@ No exemplo anterior, nós retornávamos um `dict` da nossa dependência ("injet
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@ No exemplo anterior, nós retornávamos um `dict` da nossa dependência ("injet
//// tab | Python 3.9+
```Python hl_lines="11"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@ No exemplo anterior, nós retornávamos um `dict` da nossa dependência ("injet
//// tab | Python 3.8+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="7"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="11"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -122,7 +122,7 @@ Então, podemos mudar o "injetável" na dependência `common_parameters` acima p
//// tab | Python 3.10+
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
```
////
@@ -130,7 +130,7 @@ Então, podemos mudar o "injetável" na dependência `common_parameters` acima p
//// tab | Python 3.9+
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
```
////
@@ -138,35 +138,35 @@ Então, podemos mudar o "injetável" na dependência `common_parameters` acima p
//// tab | Python 3.8+
```Python hl_lines="12-16"
-{!> ../../../docs_src/dependencies/tutorial002_an.py!}
+{!> ../../docs_src/dependencies/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="9-13"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -176,7 +176,7 @@ Observe o método `__init__` usado para criar uma instância da classe:
//// tab | Python 3.10+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
```
////
@@ -184,7 +184,7 @@ Observe o método `__init__` usado para criar uma instância da classe:
//// tab | Python 3.9+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
```
////
@@ -192,35 +192,35 @@ Observe o método `__init__` usado para criar uma instância da classe:
//// tab | Python 3.8+
```Python hl_lines="13"
-{!> ../../../docs_src/dependencies/tutorial002_an.py!}
+{!> ../../docs_src/dependencies/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -230,7 +230,7 @@ Utilize a versão com `Annotated` se possível.
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -238,7 +238,7 @@ Utilize a versão com `Annotated` se possível.
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -246,35 +246,35 @@ Utilize a versão com `Annotated` se possível.
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="6"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -296,7 +296,7 @@ Agora você pode declarar sua dependência utilizando essa classe.
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
```
////
@@ -304,7 +304,7 @@ Agora você pode declarar sua dependência utilizando essa classe.
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
```
////
@@ -312,35 +312,35 @@ Agora você pode declarar sua dependência utilizando essa classe.
//// tab | Python 3.8+
```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial002_an.py!}
+{!> ../../docs_src/dependencies/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -361,7 +361,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
@@ -397,7 +397,7 @@ commons: Annotated[CommonQueryParams, ...
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
@@ -423,7 +423,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
@@ -440,7 +440,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial003_an_py310.py!}
```
////
@@ -448,7 +448,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial003_an_py39.py!}
```
////
@@ -456,35 +456,35 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.8+
```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial003_an.py!}
+{!> ../../docs_src/dependencies/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
+{!> ../../docs_src/dependencies/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003.py!}
+{!> ../../docs_src/dependencies/tutorial003.py!}
```
////
@@ -507,7 +507,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
@@ -535,7 +535,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
@@ -559,7 +559,7 @@ commons: Annotated[CommonQueryParams, Depends()]
//// tab | Python 3.8 non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
@@ -578,7 +578,7 @@ O mesmo exemplo ficaria então dessa forma:
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial004_an_py310.py!}
```
////
@@ -586,7 +586,7 @@ O mesmo exemplo ficaria então dessa forma:
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial004_an_py39.py!}
```
////
@@ -594,42 +594,42 @@ O mesmo exemplo ficaria então dessa forma:
//// tab | Python 3.8+
```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial004_an.py!}
+{!> ../../docs_src/dependencies/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
+{!> ../../docs_src/dependencies/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004.py!}
+{!> ../../docs_src/dependencies/tutorial004.py!}
```
////
...e o **FastAPI** saberá o que fazer.
-/// tip | "Dica"
+/// tip | Dica
Se isso parece mais confuso do que útil, não utilize, você não *precisa* disso.
diff --git a/docs/pt/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/pt/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
index 4a7a29390..89c34855e 100644
--- a/docs/pt/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
+++ b/docs/pt/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -17,7 +17,7 @@ Ele deve ser uma lista de `Depends()`:
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -25,28 +25,28 @@ Ele deve ser uma lista de `Depends()`:
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
Essas dependências serão executadas/resolvidas da mesma forma que dependências comuns. Mas o valor delas (se existir algum) não será passado para a sua *função de operação de rota*.
-/// tip | "Dica"
+/// tip | Dica
Alguns editores de texto checam parâmetros de funções não utilizados, e os mostram como erros.
@@ -56,7 +56,7 @@ Isso também pode ser útil para evitar confundir novos desenvolvedores que ao v
///
-/// info | "Informação"
+/// info | Informação
Neste exemplo utilizamos cabeçalhos personalizados inventados `X-Keys` e `X-Token`.
@@ -75,7 +75,7 @@ Dependências podem declarar requisitos de requisições (como cabeçalhos) ou o
//// tab | Python 3.9+
```Python hl_lines="8 13"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -83,21 +83,21 @@ Dependências podem declarar requisitos de requisições (como cabeçalhos) ou o
//// tab | Python 3.8+
```Python hl_lines="7 12"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível
///
```Python hl_lines="6 11"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -109,7 +109,7 @@ Essas dependências podem levantar exceções, da mesma forma que dependências
//// tab | Python 3.9+
```Python hl_lines="10 15"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -117,21 +117,21 @@ Essas dependências podem levantar exceções, da mesma forma que dependências
//// tab | Python 3.8+
```Python hl_lines="9 14"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 non-Annotated
-/// tip | "Dica"
+/// tip | Dica
Utilize a versão com `Annotated` se possível
///
```Python hl_lines="8 13"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -145,7 +145,7 @@ Então, você pode reutilizar uma dependência comum (que retorna um valor) que
//// tab | Python 3.9+
```Python hl_lines="11 16"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -153,14 +153,14 @@ Então, você pode reutilizar uma dependência comum (que retorna um valor) que
//// tab | Python 3.8+
```Python hl_lines="10 15"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
//// tab | Python 3.8 non-Annotated
-/// tip | "Dica"
+/// tip | Dica
@@ -169,7 +169,7 @@ Então, você pode reutilizar uma dependência comum (que retorna um valor) que
Utilize a versão com `Annotated` se possível
```Python hl_lines="9 14"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
diff --git a/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md
index 16c2cf899..90c1e02e0 100644
--- a/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md
+++ b/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -4,13 +4,13 @@ O FastAPI possui suporte para dependências que realizam .
@@ -43,7 +43,7 @@ Mas se você tiver cabeçalhos personalizados desejando que um cliente em um nav
///
-/// note | "Detalhes técnicos"
+/// note | Detalhes técnicos
Você também pode usar `from starlette.requests import Request`.
@@ -60,7 +60,7 @@ E também depois que a `response` é gerada, antes de retorná-la.
Por exemplo, você pode adicionar um cabeçalho personalizado `X-Process-Time` contendo o tempo em segundos que levou para processar a solicitação e gerar uma resposta:
```Python hl_lines="10 12-13"
-{!../../../docs_src/middleware/tutorial001.py!}
+{!../../docs_src/middleware/tutorial001.py!}
```
## Outros middlewares
diff --git a/docs/pt/docs/tutorial/path-operation-configuration.md b/docs/pt/docs/tutorial/path-operation-configuration.md
index c57813780..5f3cc82fb 100644
--- a/docs/pt/docs/tutorial/path-operation-configuration.md
+++ b/docs/pt/docs/tutorial/path-operation-configuration.md
@@ -2,7 +2,7 @@
Existem vários parâmetros que você pode passar para o seu *decorador de operação de rota* para configurá-lo.
-/// warning | "Aviso"
+/// warning | Aviso
Observe que esses parâmetros são passados diretamente para o *decorador de operação de rota*, não para a sua *função de operação de rota*.
@@ -19,7 +19,7 @@ Mas se você não se lembrar o que cada código numérico significa, pode usar a
//// tab | Python 3.8 and above
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001.py!}
```
////
@@ -27,7 +27,7 @@ Mas se você não se lembrar o que cada código numérico significa, pode usar a
//// tab | Python 3.9 and above
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py39.py!}
```
////
@@ -35,14 +35,14 @@ Mas se você não se lembrar o que cada código numérico significa, pode usar a
//// tab | Python 3.10 and above
```Python hl_lines="1 15"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py310.py!}
```
////
Esse código de status será usado na resposta e será adicionado ao esquema OpenAPI.
-/// note | "Detalhes Técnicos"
+/// note | Detalhes Técnicos
Você também poderia usar `from starlette import status`.
@@ -57,7 +57,7 @@ Você pode adicionar tags para sua *operação de rota*, passe o parâmetro `tag
//// tab | Python 3.8 and above
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002.py!}
```
////
@@ -65,7 +65,7 @@ Você pode adicionar tags para sua *operação de rota*, passe o parâmetro `tag
//// tab | Python 3.9 and above
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py39.py!}
```
////
@@ -73,7 +73,7 @@ Você pode adicionar tags para sua *operação de rota*, passe o parâmetro `tag
//// tab | Python 3.10 and above
```Python hl_lines="15 20 25"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py310.py!}
```
////
@@ -91,7 +91,7 @@ Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
**FastAPI** suporta isso da mesma maneira que com strings simples:
```Python hl_lines="1 8-10 13 18"
-{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
+{!../../docs_src/path_operation_configuration/tutorial002b.py!}
```
## Resumo e descrição
@@ -101,7 +101,7 @@ Você pode adicionar um `summary` e uma `description`:
//// tab | Python 3.8 and above
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003.py!}
```
////
@@ -109,7 +109,7 @@ Você pode adicionar um `summary` e uma `description`:
//// tab | Python 3.9 and above
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py39.py!}
```
////
@@ -117,7 +117,7 @@ Você pode adicionar um `summary` e uma `description`:
//// tab | Python 3.10 and above
```Python hl_lines="18-19"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py310.py!}
```
////
@@ -131,7 +131,7 @@ Você pode escrever ../../../docs_src/path_operation_configuration/tutorial004.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004.py!}
```
////
@@ -139,7 +139,7 @@ Você pode escrever ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py39.py!}
```
////
@@ -147,7 +147,7 @@ Você pode escrever ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py310.py!}
```
////
@@ -164,7 +164,7 @@ Você pode especificar a descrição da resposta com o parâmetro `response_desc
//// tab | Python 3.8 and above
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005.py!}
```
////
@@ -172,7 +172,7 @@ Você pode especificar a descrição da resposta com o parâmetro `response_desc
//// tab | Python 3.9 and above
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py39.py!}
```
////
@@ -180,12 +180,12 @@ Você pode especificar a descrição da resposta com o parâmetro `response_desc
//// tab | Python 3.10 and above
```Python hl_lines="19"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py310.py!}
```
////
-/// info | "Informação"
+/// info | Informação
Note que `response_description` se refere especificamente à resposta, a `description` se refere à *operação de rota* em geral.
@@ -206,7 +206,7 @@ Então, se você não fornecer uma, o **FastAPI** irá gerar automaticamente uma
Se você precisar marcar uma *operação de rota* como descontinuada, mas sem removê-la, passe o parâmetro `deprecated`:
```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_configuration/tutorial006.py!}
```
Ela será claramente marcada como descontinuada nas documentações interativas:
diff --git a/docs/pt/docs/tutorial/path-params-numeric-validations.md b/docs/pt/docs/tutorial/path-params-numeric-validations.md
index 08ed03f75..3361f86c5 100644
--- a/docs/pt/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/pt/docs/tutorial/path-params-numeric-validations.md
@@ -9,7 +9,7 @@ Primeiro, importe `Path` de `fastapi`:
//// tab | Python 3.10+
```Python hl_lines="1"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
@@ -17,7 +17,7 @@ Primeiro, importe `Path` de `fastapi`:
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
@@ -31,7 +31,7 @@ Por exemplo para declarar um valor de metadado `title` para o parâmetro de rota
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
@@ -39,12 +39,12 @@ Por exemplo para declarar um valor de metadado `title` para o parâmetro de rota
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
-/// note | "Nota"
+/// note | Nota
Um parâmetro de rota é sempre obrigatório, como se fizesse parte da rota.
@@ -71,7 +71,7 @@ Isso não faz diferença para o **FastAPI**. Ele vai detectar os parâmetros pel
Então, você pode declarar sua função assim:
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
## Ordene os parâmetros de a acordo com sua necessidade, truques
@@ -83,7 +83,7 @@ Passe `*`, como o primeiro parâmetro da função.
O Python não vai fazer nada com esse `*`, mas ele vai saber que a partir dali os parâmetros seguintes deverão ser chamados argumentos nomeados (pares chave-valor), também conhecidos como kwargs. Mesmo que eles não possuam um valor padrão.
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
## Validações numéricas: maior que ou igual
@@ -93,7 +93,7 @@ Com `Query` e `Path` (e outras que você verá mais tarde) você pode declarar r
Aqui, com `ge=1`, `item_id` precisará ser um número inteiro maior que ("`g`reater than") ou igual ("`e`qual") a 1.
```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
## Validações numéricas: maior que e menor que ou igual
@@ -104,7 +104,7 @@ O mesmo se aplica para:
* `le`: menor que ou igual (`l`ess than or `e`qual)
```Python hl_lines="9"
-{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
## Validações numéricas: valores do tipo float, maior que e menor que
@@ -118,7 +118,7 @@ Assim, `0.5` seria um valor válido. Mas `0.0` ou `0` não seria.
E o mesmo para lt.
```Python hl_lines="11"
-{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
## Recapitulando
@@ -132,7 +132,7 @@ E você também pode declarar validações numéricas:
* `lt`: menor que (`l`ess `t`han)
* `le`: menor que ou igual (`l`ess than or `e`qual)
-/// info | "Informação"
+/// info | Informação
`Query`, `Path` e outras classes que você verá a frente são subclasses de uma classe comum `Param`.
@@ -140,7 +140,7 @@ Todas elas compartilham os mesmos parâmetros para validação adicional e metad
///
-/// note | "Detalhes Técnicos"
+/// note | Detalhes Técnicos
Quando você importa `Query`, `Path` e outras de `fastapi`, elas são na verdade funções.
diff --git a/docs/pt/docs/tutorial/path-params.md b/docs/pt/docs/tutorial/path-params.md
index fb872e4f5..64f8a0253 100644
--- a/docs/pt/docs/tutorial/path-params.md
+++ b/docs/pt/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
Você pode declarar os "parâmetros" ou "variáveis" com a mesma sintaxe utilizada pelo formato de strings do Python:
```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
O valor do parâmetro que foi passado à `item_id` será passado para a sua função como o argumento `item_id`.
@@ -19,12 +19,12 @@ Então, se você rodar este exemplo e for até http://127.0.0.1:8000/items/4.2
-/// check | "Verifique"
+/// check | Verifique
@@ -91,7 +91,7 @@ Quando você abrir o seu navegador em
-/// check | "Verifique"
+/// check | Verifique
@@ -130,7 +130,7 @@ E então você pode ter também uma rota `/users/{user_id}` para pegar dados sob
Porque as operações de rota são avaliadas em ordem, você precisa ter certeza que a rota para `/users/me` está sendo declarado antes da rota `/users/{user_id}`:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
+{!../../docs_src/path_params/tutorial003.py!}
```
Caso contrário, a rota para `/users/{user_id}` coincidiria também para `/users/me`, "pensando" que estaria recebendo o parâmetro `user_id` com o valor de `"me"`.
@@ -148,16 +148,16 @@ Por herdar de `str` a documentação da API vai ser capaz de saber que os valore
Assim, crie atributos de classe com valores fixos, que serão os valores válidos disponíveis.
```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// info | "informação"
+/// info | informação
Enumerations (ou enums) estão disponíveis no Python desde a versão 3.4.
///
-/// tip | "Dica"
+/// tip | Dica
@@ -170,7 +170,7 @@ Assim, crie atributos de classe com valores fixos, que serão os valores válido
Logo, crie um *parâmetro de rota* com anotações de tipo usando a classe enum que você criou (`ModelName`):
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### Revise a documentação
@@ -188,7 +188,7 @@ O valor do *parâmetro da rota* será um *membro de enumeration*.
Você pode comparar eles com o *membro de enumeration* no enum `ModelName` que você criou:
```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
#### Obtenha o *valor de enumerate*
@@ -196,10 +196,10 @@ Você pode comparar eles com o *membro de enumeration* no enum `ModelName` que v
Você pode ter o valor exato de enumerate (um `str` nesse caso) usando `model_name.value`, ou em geral, `your_enum_member.value`:
```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// tip | "Dica"
+/// tip | Dica
@@ -214,7 +214,7 @@ Você pode retornar *membros de enum* da sua *rota de operação*, em um corpo J
Eles serão convertidos para o seus valores correspondentes (strings nesse caso) antes de serem retornados ao cliente:
```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
No seu cliente você vai obter uma resposta JSON como:
@@ -255,10 +255,10 @@ Nesse caso, o nome do parâmetro é `file_path`, e a última parte, `:path`, diz
Então, você poderia usar ele com:
```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
+{!../../docs_src/path_params/tutorial004.py!}
```
-/// tip | "Dica"
+/// tip | Dica
diff --git a/docs/pt/docs/tutorial/query-param-models.md b/docs/pt/docs/tutorial/query-param-models.md
new file mode 100644
index 000000000..854183fb4
--- /dev/null
+++ b/docs/pt/docs/tutorial/query-param-models.md
@@ -0,0 +1,197 @@
+# Modelos de Parâmetros de Consulta
+
+Se você possui um grupo de **parâmetros de consultas** que são relacionados, você pode criar um **modelo Pydantic** para declará-los.
+
+Isso permitiria que você **reutilizasse o modelo** em **diversos lugares**, e também declarasse validações e metadados de todos os parâmetros de uma única vez. 😎
+
+/// note | Nota
+
+Isso é suportado desde o FastAPI versão `0.115.0`. 🤓
+
+///
+
+## Parâmetros de Consulta com um Modelo Pydantic
+
+Declare os **parâmetros de consulta** que você precisa em um **modelo Pydantic**, e então declare o parâmetro como `Query`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="9-13 17"
+{!> ../../docs_src/query_param_models/tutorial001_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="8-12 16"
+{!> ../../docs_src/query_param_models/tutorial001_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="10-14 18"
+{!> ../../docs_src/query_param_models/tutorial001_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="9-13 17"
+{!> ../../docs_src/query_param_models/tutorial001_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="8-12 16"
+{!> ../../docs_src/query_param_models/tutorial001_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="9-13 17"
+{!> ../../docs_src/query_param_models/tutorial001_py310.py!}
+```
+
+////
+
+O **FastAPI** **extrairá** os dados para **cada campo** dos **parâmetros de consulta** presentes na requisição, e fornecerá o modelo Pydantic que você definiu.
+
+
+## Verifique os Documentos
+
+Você pode ver os parâmetros de consulta nos documentos de IU em `/docs`:
+
+
+POST.
+
+///
+
+/// warning | Aviso
+
+Você pode declarar múltiplos parâmetros `File` e `Form` em uma *operação de rota*, mas você não pode declarar campos `Body` que você espera receber como JSON, pois a requisição terá o corpo codificado usando `multipart/form-data` ao invés de `application/json`.
+
+Isso não é uma limitação do **FastAPI**, é parte do protocolo HTTP.
+
+///
+
+## Upload de Arquivo Opcional
+
+Você pode tornar um arquivo opcional usando anotações de tipo padrão e definindo um valor padrão de `None`:
+
+{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
+
+## `UploadFile` com Metadados Adicionais
+
+Você também pode usar `File()` com `UploadFile`, por exemplo, para definir metadados adicionais:
+
+{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
+
+## Uploads de Múltiplos Arquivos
+
+É possível realizar o upload de vários arquivos ao mesmo tempo.
+
+Eles serão associados ao mesmo "campo de formulário" enviado usando "dados de formulário".
+
+Para usar isso, declare uma lista de `bytes` ou `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
+
+Você receberá, tal como declarado, uma `list` de `bytes` ou `UploadFile`.
+
+/// note | Detalhes Técnicos
+
+Você pode também pode usar `from starlette.responses import HTMLResponse`.
+
+**FastAPI** providencia o mesmo `starlette.responses` que `fastapi.responses` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
+
+///
+
+### Uploads de Múltiplos Arquivos com Metadados Adicionais
+
+Da mesma forma de antes, você pode usar `File()` para definir parâmetros adicionais, mesmo para `UploadFile`:
+
+{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
+
+## Recapitulando
+
+Utilize `File`, `bytes` e `UploadFile` para declarar arquivos a serem enviados na requisição, enviados como dados de formulário.
diff --git a/docs/pt/docs/tutorial/request-form-models.md b/docs/pt/docs/tutorial/request-form-models.md
new file mode 100644
index 000000000..7128a0ae2
--- /dev/null
+++ b/docs/pt/docs/tutorial/request-form-models.md
@@ -0,0 +1,134 @@
+# Modelos de Formulários
+
+Você pode utilizar **Modelos Pydantic** para declarar **campos de formulários** no FastAPI.
+
+/// info | Informação
+
+Para utilizar formulários, instale primeiramente o `python-multipart`.
+
+Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo, e então instalar. Por exemplo:
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+/// note | Nota
+
+Isto é suportado desde a versão `0.113.0` do FastAPI. 🤓
+
+///
+
+## Modelos Pydantic para Formulários
+
+Você precisa apenas declarar um **modelo Pydantic** com os campos que deseja receber como **campos de formulários**, e então declarar o parâmetro como um `Form`:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="9-11 15"
+{!> ../../docs_src/request_form_models/tutorial001_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="8-10 14"
+{!> ../../docs_src/request_form_models/tutorial001_an.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira utilizar a versão `Annotated` se possível.
+
+///
+
+```Python hl_lines="7-9 13"
+{!> ../../docs_src/request_form_models/tutorial001.py!}
+```
+
+////
+
+O **FastAPI** irá **extrair** as informações para **cada campo** dos **dados do formulário** na requisição e dar para você o modelo Pydantic que você definiu.
+
+## Confira os Documentos
+
+Você pode verificar na UI de documentação em `/docs`:
+
+
+
-/// note | "Nota"
+/// note | Nota
Alguns códigos de resposta (consulte a próxima seção) indicam que a resposta não possui um corpo.
@@ -43,7 +43,7 @@ O FastAPI sabe disso e produzirá documentos OpenAPI informando que não há cor
## Sobre os códigos de status HTTP
-/// note | "Nota"
+/// note | Nota
Se você já sabe o que são códigos de status HTTP, pule para a próxima seção.
@@ -67,7 +67,7 @@ Resumidamente:
* Para erros genéricos do cliente, você pode usar apenas `400`.
* `500` e acima são para erros do servidor. Você quase nunca os usa diretamente. Quando algo der errado em alguma parte do código do seu aplicativo ou servidor, ele retornará automaticamente um desses códigos de status.
-/// tip | "Dica"
+/// tip | Dica
Para saber mais sobre cada código de status e qual código serve para quê, verifique o MDN documentação sobre códigos de status HTTP.
@@ -78,7 +78,7 @@ Para saber mais sobre cada código de status e qual código serve para quê, ver
Vamos ver o exemplo anterior novamente:
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
`201` é o código de status para "Criado".
@@ -88,14 +88,14 @@ Mas você não precisa memorizar o que cada um desses códigos significa.
Você pode usar as variáveis de conveniência de `fastapi.status`.
```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
+{!../../docs_src/response_status_code/tutorial002.py!}
```
Eles são apenas uma conveniência, eles possuem o mesmo número, mas dessa forma você pode usar o autocomplete do editor para encontrá-los:
-/// note | "Detalhes técnicos"
+/// note | Detalhes técnicos
Você também pode usar `from starlette import status`.
diff --git a/docs/pt/docs/tutorial/schema-extra-example.md b/docs/pt/docs/tutorial/schema-extra-example.md
index a291db045..dd95d4c7d 100644
--- a/docs/pt/docs/tutorial/schema-extra-example.md
+++ b/docs/pt/docs/tutorial/schema-extra-example.md
@@ -9,12 +9,12 @@ Aqui estão várias formas de se fazer isso.
Você pode declarar um `example` para um modelo Pydantic usando `Config` e `schema_extra`, conforme descrito em Documentação do Pydantic: Schema customization:
```Python hl_lines="15-23"
-{!../../../docs_src/schema_extra_example/tutorial001.py!}
+{!../../docs_src/schema_extra_example/tutorial001.py!}
```
Essas informações extras serão adicionadas como se encontram no **JSON Schema** de resposta desse modelo e serão usadas na documentação da API.
-/// tip | "Dica"
+/// tip | Dica
Você pode usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras de forma personalizada.
@@ -29,10 +29,10 @@ Ao usar `Field ()` com modelos Pydantic, você também pode declarar informaçõ
Você pode usar isso para adicionar um `example` para cada campo:
```Python hl_lines="4 10-13"
-{!../../../docs_src/schema_extra_example/tutorial002.py!}
+{!../../docs_src/schema_extra_example/tutorial002.py!}
```
-/// warning | "Atenção"
+/// warning | Atenção
Lembre-se de que esses argumentos extras passados não adicionarão nenhuma validação, apenas informações extras, para fins de documentação.
@@ -57,7 +57,7 @@ você também pode declarar um dado `example` ou um grupo de `examples` com info
Aqui nós passamos um `example` dos dados esperados por `Body()`:
```Python hl_lines="21-26"
-{!../../../docs_src/schema_extra_example/tutorial003.py!}
+{!../../docs_src/schema_extra_example/tutorial003.py!}
```
### Exemplo na UI da documentação
@@ -80,7 +80,7 @@ Cada `dict` de exemplo específico em `examples` pode conter:
* `externalValue`: alternativa ao `value`, uma URL apontando para o exemplo. Embora isso possa não ser suportado por tantas ferramentas quanto `value`.
```Python hl_lines="22-48"
-{!../../../docs_src/schema_extra_example/tutorial004.py!}
+{!../../docs_src/schema_extra_example/tutorial004.py!}
```
### Exemplos na UI da documentação
@@ -91,7 +91,7 @@ Com `examples` adicionado a `Body()`, os `/docs` vão ficar assim:
## Detalhes técnicos
-/// warning | "Atenção"
+/// warning | Atenção
Esses são detalhes muito técnicos sobre os padrões **JSON Schema** e **OpenAPI**.
diff --git a/docs/pt/docs/tutorial/security/first-steps.md b/docs/pt/docs/tutorial/security/first-steps.md
index 007fefcb9..02871c90a 100644
--- a/docs/pt/docs/tutorial/security/first-steps.md
+++ b/docs/pt/docs/tutorial/security/first-steps.md
@@ -20,12 +20,12 @@ Vamos primeiro usar o código e ver como funciona, e depois voltaremos para ente
Copie o exemplo em um arquivo `main.py`:
```Python
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
## Execute-o
-/// info | "informação"
+/// info | informação
@@ -57,7 +57,7 @@ Você verá algo deste tipo:
-/// check | "Botão de Autorizar!"
+/// check | Botão de Autorizar!
@@ -71,7 +71,7 @@ E se você clicar, você terá um pequeno formulário de autorização para digi
-/// note | "Nota"
+/// note | Nota
@@ -119,7 +119,7 @@ Então, vamos rever de um ponto de vista simplificado:
Neste exemplo, nós vamos usar o **OAuth2** com o fluxo de **Senha**, usando um token **Bearer**. Fazemos isso usando a classe `OAuth2PasswordBearer`.
-/// info | "informação"
+/// info | informação
@@ -136,10 +136,10 @@ Neste exemplo, nós vamos usar o **OAuth2** com o fluxo de **Senha**, usando um
Quando nós criamos uma instância da classe `OAuth2PasswordBearer`, nós passamos pelo parâmetro `tokenUrl` Esse parâmetro contém a URL que o client (o frontend rodando no browser do usuário) vai usar para mandar o `username` e `senha` para obter um token.
```Python hl_lines="6"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
-/// tip | "Dica"
+/// tip | Dica
@@ -155,7 +155,7 @@ Esse parâmetro não cria um endpoint / *path operation*, mas declara que a URL
Em breve também criaremos o atual path operation.
-/// info | "informação"
+/// info | informação
@@ -180,14 +180,14 @@ Então, pode ser usado com `Depends`.
Agora você pode passar aquele `oauth2_scheme` em uma dependência com `Depends`.
```Python hl_lines="10"
-{!../../../docs_src/security/tutorial001.py!}
+{!../../docs_src/security/tutorial001.py!}
```
Esse dependência vai fornecer uma `str` que é atribuído ao parâmetro `token da *função do path operation*
A **FastAPI** saberá que pode usar essa dependência para definir um "esquema de segurança" no esquema da OpenAPI (e na documentação da API automática).
-/// info | "Detalhes técnicos"
+/// info | Detalhes técnicos
diff --git a/docs/pt/docs/tutorial/security/index.md b/docs/pt/docs/tutorial/security/index.md
index 2f23aa47e..b4440ec04 100644
--- a/docs/pt/docs/tutorial/security/index.md
+++ b/docs/pt/docs/tutorial/security/index.md
@@ -32,7 +32,7 @@ Não é muito popular ou usado nos dias atuais.
OAuth2 não especifica como criptografar a comunicação, ele espera que você tenha sua aplicação em um servidor HTTPS.
-/// tip | "Dica"
+/// tip | Dica
Na seção sobre **deployment** você irá ver como configurar HTTPS de modo gratuito, usando Traefik e Let’s Encrypt.
@@ -89,7 +89,7 @@ OpenAPI define os seguintes esquemas de segurança:
* Essa descoberta automática é o que é definido na especificação OpenID Connect.
-/// tip | "Dica"
+/// 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.
diff --git a/docs/pt/docs/tutorial/security/simple-oauth2.md b/docs/pt/docs/tutorial/security/simple-oauth2.md
new file mode 100644
index 000000000..4e55f8c25
--- /dev/null
+++ b/docs/pt/docs/tutorial/security/simple-oauth2.md
@@ -0,0 +1,539 @@
+# Simples OAuth2 com senha e Bearer
+
+Agora vamos construir a partir do capítulo anterior e adicionar as partes que faltam para ter um fluxo de segurança completo.
+
+## Pegue o `username` (nome de usuário) e `password` (senha)
+
+É utilizado o utils de segurança da **FastAPI** para obter o `username` e a `password`.
+
+OAuth2 especifica que ao usar o "password flow" (fluxo de senha), que estamos usando, o cliente/usuário deve enviar os campos `username` e `password` como dados do formulário.
+
+E a especificação diz que os campos devem ser nomeados assim. Portanto, `user-name` ou `email` não funcionariam.
+
+Mas não se preocupe, você pode mostrá-lo como quiser aos usuários finais no frontend.
+
+E seus modelos de banco de dados podem usar qualquer outro nome que você desejar.
+
+Mas para a *operação de rota* de login, precisamos usar esses nomes para serem compatíveis com a especificação (e poder, por exemplo, usar o sistema integrado de documentação da API).
+
+A especificação também afirma que o `username` e a `password` devem ser enviados como dados de formulário (portanto, não há JSON aqui).
+
+### `scope`
+
+A especificação também diz que o cliente pode enviar outro campo de formulário "`scope`" (Escopo).
+
+O nome do campo do formulário é `scope` (no singular), mas na verdade é uma longa string com "escopos" separados por espaços.
+
+Cada “scope” é apenas uma string (sem espaços).
+
+Normalmente são usados para declarar permissões de segurança específicas, por exemplo:
+
+* `users:read` ou `users:write` são exemplos comuns.
+* `instagram_basic` é usado pelo Facebook e Instagram.
+* `https://www.googleapis.com/auth/drive` é usado pelo Google.
+
+/// info | Informação
+
+No OAuth2, um "scope" é apenas uma string que declara uma permissão específica necessária.
+
+Não importa se tem outros caracteres como `:` ou se é uma URL.
+
+Esses detalhes são específicos da implementação.
+
+Para OAuth2 são apenas strings.
+
+///
+
+## Código para conseguir o `username` e a `password`
+
+Agora vamos usar os utilitários fornecidos pelo **FastAPI** para lidar com isso.
+
+### `OAuth2PasswordRequestForm`
+
+Primeiro, importe `OAuth2PasswordRequestForm` e use-o como uma dependência com `Depends` na *operação de rota* para `/token`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="4 78"
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="4 78"
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="4 79"
+{!> ../../docs_src/security/tutorial003_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="2 74"
+{!> ../../docs_src/security/tutorial003_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="4 76"
+{!> ../../docs_src/security/tutorial003.py!}
+```
+
+////
+
+`OAuth2PasswordRequestForm` é uma dependência de classe que declara um corpo de formulário com:
+
+* O `username`.
+* A `password`.
+* Um campo `scope` opcional como uma string grande, composta de strings separadas por espaços.
+* Um `grant_type` (tipo de concessão) opcional.
+
+/// tip | Dica
+
+A especificação OAuth2 na verdade *requer* um campo `grant_type` com um valor fixo de `password`, mas `OAuth2PasswordRequestForm` não o impõe.
+
+Se você precisar aplicá-lo, use `OAuth2PasswordRequestFormStrict` em vez de `OAuth2PasswordRequestForm`.
+
+///
+
+* Um `client_id` opcional (não precisamos dele em nosso exemplo).
+* Um `client_secret` opcional (não precisamos dele em nosso exemplo).
+
+/// info | Informação
+
+O `OAuth2PasswordRequestForm` não é uma classe especial para **FastAPI** como é `OAuth2PasswordBearer`.
+
+`OAuth2PasswordBearer` faz com que **FastAPI** saiba que é um esquema de segurança. Portanto, é adicionado dessa forma ao OpenAPI.
+
+Mas `OAuth2PasswordRequestForm` é apenas uma dependência de classe que você mesmo poderia ter escrito ou poderia ter declarado os parâmetros do `Form` (formulário) diretamente.
+
+Mas como é um caso de uso comum, ele é fornecido diretamente pelo **FastAPI**, apenas para facilitar.
+
+///
+
+### Use os dados do formulário
+
+/// tip | Dica
+
+A instância da classe de dependência `OAuth2PasswordRequestForm` não terá um atributo `scope` com a string longa separada por espaços, em vez disso, terá um atributo `scopes` com a lista real de strings para cada escopo enviado.
+
+Não estamos usando `scopes` neste exemplo, mas a funcionalidade está disponível se você precisar.
+
+///
+
+Agora, obtenha os dados do usuário do banco de dados (falso), usando o `username` do campo do formulário.
+
+Se não existir tal usuário, retornaremos um erro dizendo "Incorrect username or password" (Nome de usuário ou senha incorretos).
+
+Para o erro, usamos a exceção `HTTPException`:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="3 79-81"
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="3 79-81"
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="3 80-82"
+{!> ../../docs_src/security/tutorial003_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="1 75-77"
+{!> ../../docs_src/security/tutorial003_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="3 77-79"
+{!> ../../docs_src/security/tutorial003.py!}
+```
+
+////
+
+### Confira a password (senha)
+
+Neste ponto temos os dados do usuário do nosso banco de dados, mas não verificamos a senha.
+
+Vamos colocar esses dados primeiro no modelo `UserInDB` do Pydantic.
+
+Você nunca deve salvar senhas em texto simples, portanto, usaremos o sistema de hashing de senhas (falsas).
+
+Se as senhas não corresponderem, retornaremos o mesmo erro.
+
+#### Hashing de senha
+
+"Hashing" significa: converter algum conteúdo (uma senha neste caso) em uma sequência de bytes (apenas uma string) que parece algo sem sentido.
+
+Sempre que você passa exatamente o mesmo conteúdo (exatamente a mesma senha), você obtém exatamente a mesma sequência aleatória de caracteres.
+
+Mas você não pode converter a sequência aleatória de caracteres de volta para a senha.
+
+##### Porque usar hashing de senha
+
+Se o seu banco de dados for roubado, o ladrão não terá as senhas em texto simples dos seus usuários, apenas os hashes.
+
+Assim, o ladrão não poderá tentar usar essas mesmas senhas em outro sistema (como muitos usuários usam a mesma senha em todos os lugares, isso seria perigoso).
+
+//// tab | Python 3.10+
+
+```Python hl_lines="82-85"
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="82-85"
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="83-86"
+{!> ../../docs_src/security/tutorial003_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="78-81"
+{!> ../../docs_src/security/tutorial003_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="80-83"
+{!> ../../docs_src/security/tutorial003.py!}
+```
+
+////
+
+#### Sobre `**user_dict`
+
+`UserInDB(**user_dict)` significa:
+
+*Passe as keys (chaves) e values (valores) de `user_dict` diretamente como argumentos de valor-chave, equivalente a:*
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+ disabled = user_dict["disabled"],
+ hashed_password = user_dict["hashed_password"],
+)
+```
+
+/// info | Informação
+
+Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Extra Models**](../extra-models.md#about-user_indict){.internal-link target=_blank}.
+
+///
+
+## Retorne o token
+
+A resposta do endpoint `token` deve ser um objeto JSON.
+
+Deve ter um `token_type`. No nosso caso, como estamos usando tokens "Bearer", o tipo de token deve ser "`bearer`".
+
+E deve ter um `access_token`, com uma string contendo nosso token de acesso.
+
+Para este exemplo simples, seremos completamente inseguros e retornaremos o mesmo `username` do token.
+
+/// tip | Dica
+
+No próximo capítulo, você verá uma implementação realmente segura, com hash de senha e tokens JWT.
+
+Mas, por enquanto, vamos nos concentrar nos detalhes específicos de que precisamos.
+
+///
+
+//// tab | Python 3.10+
+
+```Python hl_lines="87"
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="87"
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="88"
+{!> ../../docs_src/security/tutorial003_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="83"
+{!> ../../docs_src/security/tutorial003_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="85"
+{!> ../../docs_src/security/tutorial003.py!}
+```
+
+////
+
+/// tip | Dica
+
+Pela especificação, você deve retornar um JSON com um `access_token` e um `token_type`, o mesmo que neste exemplo.
+
+Isso é algo que você mesmo deve fazer em seu código e certifique-se de usar essas chaves JSON.
+
+É quase a única coisa que você deve se lembrar de fazer corretamente, para estar em conformidade com as especificações.
+
+De resto, **FastAPI** cuida disso para você.
+
+///
+
+## Atualize as dependências
+
+Agora vamos atualizar nossas dependências.
+
+Queremos obter o `user_user` *somente* se este usuário estiver ativo.
+
+Portanto, criamos uma dependência adicional `get_current_active_user` que por sua vez usa `get_current_user` como dependência.
+
+Ambas as dependências retornarão apenas um erro HTTP se o usuário não existir ou se estiver inativo.
+
+Portanto, em nosso endpoint, só obteremos um usuário se o usuário existir, tiver sido autenticado corretamente e estiver ativo:
+
+//// tab | Python 3.10+
+
+```Python hl_lines="58-66 69-74 94"
+{!> ../../docs_src/security/tutorial003_an_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="58-66 69-74 94"
+{!> ../../docs_src/security/tutorial003_an_py39.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="59-67 70-75 95"
+{!> ../../docs_src/security/tutorial003_an.py!}
+```
+
+////
+
+//// tab | Python 3.10+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="56-64 67-70 88"
+{!> ../../docs_src/security/tutorial003_py310.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Dica
+
+Prefira usar a versão `Annotated`, se possível.
+
+///
+
+```Python hl_lines="58-66 69-72 90"
+{!> ../../docs_src/security/tutorial003.py!}
+```
+
+////
+
+/// info | Informação
+
+O cabeçalho adicional `WWW-Authenticate` com valor `Bearer` que estamos retornando aqui também faz parte da especificação.
+
+Qualquer código de status HTTP (erro) 401 "UNAUTHORIZED" também deve retornar um cabeçalho `WWW-Authenticate`.
+
+No caso de tokens ao portador (nosso caso), o valor desse cabeçalho deve ser `Bearer`.
+
+Na verdade, você pode pular esse cabeçalho extra e ainda funcionaria.
+
+Mas é fornecido aqui para estar em conformidade com as especificações.
+
+Além disso, pode haver ferramentas que esperam e usam isso (agora ou no futuro) e que podem ser úteis para você ou seus usuários, agora ou no futuro.
+
+Esse é o benefício dos padrões...
+
+///
+
+## Veja em ação
+
+Abra o docs interativo: http://127.0.0.1:8000/docs.
+
+### Autenticação
+
+Clique no botão "Authorize".
+
+Use as credenciais:
+
+User: `johndoe`
+
+Password: `secret`
+
+
+
+Após autenticar no sistema, você verá assim:
+
+
+
+### Obtenha seus próprios dados de usuário
+
+Agora use a operação `GET` com o caminho `/users/me`.
+
+Você obterá os dados do seu usuário, como:
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false,
+ "hashed_password": "fakehashedsecret"
+}
+```
+
+
+
+Se você clicar no ícone de cadeado, sair e tentar a mesma operação novamente, receberá um erro HTTP 401 de:
+
+```JSON
+{
+ "detail": "Not authenticated"
+}
+```
+
+### Usuário inativo
+
+Agora tente com um usuário inativo, autentique-se com:
+
+User: `alice`
+
+Password: `secret2`
+
+E tente usar a operação `GET` com o caminho `/users/me`.
+
+Você receberá um erro "Usuário inativo", como:
+
+```JSON
+{
+ "detail": "Inactive user"
+}
+```
+
+## Recaptulando
+
+Agora você tem as ferramentas para implementar um sistema de segurança completo baseado em `username` e `password` para sua API.
+
+Usando essas ferramentas, você pode tornar o sistema de segurança compatível com qualquer banco de dados e com qualquer usuário ou modelo de dados.
+
+O único detalhe que falta é que ainda não é realmente "seguro".
+
+No próximo capítulo você verá como usar uma biblioteca de hashing de senha segura e tokens JWT.
diff --git a/docs/pt/docs/tutorial/sql-databases.md b/docs/pt/docs/tutorial/sql-databases.md
new file mode 100644
index 000000000..3d76a532c
--- /dev/null
+++ b/docs/pt/docs/tutorial/sql-databases.md
@@ -0,0 +1,359 @@
+# Bancos de Dados SQL (Relacionais)
+
+**FastAPI** não exige que você use um banco de dados SQL (relacional). Mas você pode usar **qualquer banco de dados** que quiser.
+
+Aqui veremos um exemplo usando SQLModel.
+
+**SQLModel** é construído sobre SQLAlchemy e Pydantic. Ele foi criado pelo mesmo autor do **FastAPI** para ser o par perfeito para aplicações **FastAPI** que precisam usar **bancos de dados SQL**.
+
+/// tip | Dica
+
+Você pode usar qualquer outra biblioteca de banco de dados SQL ou NoSQL que quiser (em alguns casos chamadas de "ORMs"), o FastAPI não obriga você a usar nada. 😎
+
+///
+
+Como o SQLModel é baseado no SQLAlchemy, você pode facilmente usar **qualquer banco de dados suportado** pelo SQLAlchemy (o que também os torna suportados pelo SQLModel), como:
+
+* PostgreSQL
+* MySQL
+* SQLite
+* Oracle
+* Microsoft SQL Server, etc.
+
+Neste exemplo, usaremos **SQLite**, porque ele usa um único arquivo e o Python tem suporte integrado. Assim, você pode copiar este exemplo e executá-lo como está.
+
+Mais tarde, para sua aplicação em produção, você pode querer usar um servidor de banco de dados como o **PostgreSQL**.
+
+/// tip | Dica
+
+Existe um gerador de projetos oficial com **FastAPI** e **PostgreSQL** incluindo um frontend e mais ferramentas: https://github.com/fastapi/full-stack-fastapi-template
+
+///
+
+Este é um tutorial muito simples e curto, se você quiser aprender sobre bancos de dados em geral, sobre SQL ou recursos mais avançados, acesse a documentação do SQLModel.
+
+## Instalar o `SQLModel`
+
+Primeiro, certifique-se de criar seu [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e, em seguida, instalar o `sqlmodel`:
+
+
+
+
-/// tip | "Подсказка"
+/// tip | Подсказка
Если вы используете PyCharm в качестве редактора, то вам стоит попробовать плагин Pydantic PyCharm Plugin.
@@ -132,7 +132,7 @@
Внутри функции вам доступны все атрибуты объекта модели напрямую:
```Python hl_lines="21"
-{!../../../docs_src/body/tutorial002.py!}
+{!../../docs_src/body/tutorial002.py!}
```
## Тело запроса + параметры пути
@@ -142,7 +142,7 @@
**FastAPI** распознает, какие параметры функции соответствуют параметрам пути и должны быть **получены из пути**, а какие параметры функции, объявленные как модели Pydantic, должны быть **получены из тела запроса**.
```Python hl_lines="17-18"
-{!../../../docs_src/body/tutorial003.py!}
+{!../../docs_src/body/tutorial003.py!}
```
## Тело запроса + параметры пути + параметры запроса
@@ -152,7 +152,7 @@
**FastAPI** распознает каждый из них и возьмет данные из правильного источника.
```Python hl_lines="18"
-{!../../../docs_src/body/tutorial004.py!}
+{!../../docs_src/body/tutorial004.py!}
```
Параметры функции распознаются следующим образом:
@@ -161,7 +161,7 @@
* Если аннотация типа параметра содержит **примитивный тип** (`int`, `float`, `str`, `bool` и т.п.), он будет интерпретирован как параметр **запроса**.
* Если аннотация типа параметра представляет собой **модель Pydantic**, он будет интерпретирован как параметр **тела запроса**.
-/// note | "Заметка"
+/// note | Заметка
FastAPI понимает, что значение параметра `q` не является обязательным, потому что имеет значение по умолчанию `= None`.
diff --git a/docs/ru/docs/tutorial/cookie-params.md b/docs/ru/docs/tutorial/cookie-params.md
index e88b9d7ee..88533f7f8 100644
--- a/docs/ru/docs/tutorial/cookie-params.md
+++ b/docs/ru/docs/tutorial/cookie-params.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="1"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
@@ -31,7 +31,7 @@
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
@@ -39,12 +39,12 @@
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
-/// note | "Технические детали"
+/// note | Технические детали
`Cookie` - это класс, родственный `Path` и `Query`. Он также наследуется от общего класса `Param`.
@@ -52,7 +52,7 @@
///
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Для объявления cookies, вам нужно использовать `Cookie`, иначе параметры будут интерпретированы как параметры запроса.
diff --git a/docs/ru/docs/tutorial/cors.md b/docs/ru/docs/tutorial/cors.md
index 852833208..622cd5a98 100644
--- a/docs/ru/docs/tutorial/cors.md
+++ b/docs/ru/docs/tutorial/cors.md
@@ -47,7 +47,7 @@
* Отдельных HTTP-заголовков или всех вместе, используя `"*"`.
```Python hl_lines="2 6-11 13-19"
-{!../../../docs_src/cors/tutorial001.py!}
+{!../../docs_src/cors/tutorial001.py!}
```
`CORSMiddleware` использует для параметров "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте.
@@ -78,7 +78,7 @@
Для получения более подробной информации о CORS, обратитесь к Документации CORS от Mozilla.
-/// note | "Технические детали"
+/// note | Технические детали
Вы также можете использовать `from starlette.middleware.cors import CORSMiddleware`.
diff --git a/docs/ru/docs/tutorial/debugging.md b/docs/ru/docs/tutorial/debugging.md
index 685fb7356..0feeaa20c 100644
--- a/docs/ru/docs/tutorial/debugging.md
+++ b/docs/ru/docs/tutorial/debugging.md
@@ -7,7 +7,7 @@
В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую:
```Python hl_lines="1 15"
-{!../../../docs_src/debugging/tutorial001.py!}
+{!../../docs_src/debugging/tutorial001.py!}
```
### Описание `__name__ == "__main__"`
@@ -74,7 +74,7 @@ from myapp import app
не будет выполнена.
-/// info | "Информация"
+/// info | Информация
Для получения дополнительной информации, ознакомьтесь с официальной документацией Python.
diff --git a/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
index d0471baca..486ff9ea9 100644
--- a/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="11"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@
//// tab | Python 3.6+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="11"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -120,7 +120,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
```
////
@@ -128,7 +128,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.9+
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
```
////
@@ -136,35 +136,35 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="12-16"
-{!> ../../../docs_src/dependencies/tutorial002_an.py!}
+{!> ../../docs_src/dependencies/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9-13"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -174,7 +174,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
```
////
@@ -182,7 +182,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.9+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
```
////
@@ -190,35 +190,35 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="13"
-{!> ../../../docs_src/dependencies/tutorial002_an.py!}
+{!> ../../docs_src/dependencies/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -228,7 +228,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -236,7 +236,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -244,35 +244,35 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="6"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -294,7 +294,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
```
////
@@ -302,7 +302,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
```
////
@@ -310,35 +310,35 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial002_an.py!}
+{!> ../../docs_src/dependencies/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -351,7 +351,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
@@ -395,7 +395,7 @@ commons: Annotated[CommonQueryParams, ...
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
@@ -421,7 +421,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
@@ -438,7 +438,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial003_an_py310.py!}
```
////
@@ -446,7 +446,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial003_an_py39.py!}
```
////
@@ -454,35 +454,35 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.6+
```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial003_an.py!}
+{!> ../../docs_src/dependencies/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
+{!> ../../docs_src/dependencies/tutorial003_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003.py!}
+{!> ../../docs_src/dependencies/tutorial003.py!}
```
////
@@ -497,7 +497,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
@@ -532,7 +532,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
@@ -556,7 +556,7 @@ commons: Annotated[CommonQueryParams, Depends()]
//// tab | Python 3.6 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
@@ -575,7 +575,7 @@ commons: CommonQueryParams = Depends()
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial004_an_py310.py!}
```
////
@@ -583,7 +583,7 @@ commons: CommonQueryParams = Depends()
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial004_an_py39.py!}
```
////
@@ -591,42 +591,42 @@ commons: CommonQueryParams = Depends()
//// tab | Python 3.6+
```Python hl_lines="20"
-{!> ../../../docs_src/dependencies/tutorial004_an.py!}
+{!> ../../docs_src/dependencies/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
+{!> ../../docs_src/dependencies/tutorial004_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004.py!}
+{!> ../../docs_src/dependencies/tutorial004.py!}
```
////
...и **FastAPI** будет знать, что делать.
-/// tip | "Подсказка"
+/// tip | Подсказка
Если это покажется вам более запутанным, чем полезным, не обращайте внимания, это вам не *нужно*.
diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
index 11df4b474..305ce46cb 100644
--- a/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
+++ b/docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -25,7 +25,7 @@
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
@@ -39,7 +39,7 @@
///
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -75,7 +75,7 @@
//// tab | Python 3.9+
```Python hl_lines="8 13"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -83,7 +83,7 @@
//// tab | Python 3.8+
```Python hl_lines="7 12"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
@@ -97,7 +97,7 @@
///
```Python hl_lines="6 11"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -109,7 +109,7 @@
//// tab | Python 3.9+
```Python hl_lines="10 15"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -117,7 +117,7 @@
//// tab | Python 3.8+
```Python hl_lines="9 14"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
@@ -131,7 +131,7 @@
///
```Python hl_lines="8 13"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
@@ -145,7 +145,7 @@
//// tab | Python 3.9+
```Python hl_lines="11 16"
-{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
```
////
@@ -153,7 +153,7 @@
//// tab | Python 3.8+
```Python hl_lines="10 15"
-{!> ../../../docs_src/dependencies/tutorial006_an.py!}
+{!> ../../docs_src/dependencies/tutorial006_an.py!}
```
////
@@ -167,7 +167,7 @@
///
```Python hl_lines="9 14"
-{!> ../../../docs_src/dependencies/tutorial006.py!}
+{!> ../../docs_src/dependencies/tutorial006.py!}
```
////
diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
index ece7ef8e3..83f8ec0d2 100644
--- a/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
+++ b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -4,13 +4,13 @@ FastAPI поддерживает зависимости, которые выпо
Для этого используйте `yield` вместо `return`, а дополнительный код напишите после него.
-/// tip | "Подсказка"
+/// tip | Подсказка
Обязательно используйте `yield` один-единственный раз.
///
-/// note | "Технические детали"
+/// note | Технические детали
Любая функция, с которой может работать:
@@ -30,22 +30,22 @@ FastAPI поддерживает зависимости, которые выпо
Перед созданием ответа будет выполнен только код до и включая `yield`.
```Python hl_lines="2-4"
-{!../../../docs_src/dependencies/tutorial007.py!}
+{!../../docs_src/dependencies/tutorial007.py!}
```
Полученное значение и есть то, что будет внедрено в функцию операции пути и другие зависимости:
```Python hl_lines="4"
-{!../../../docs_src/dependencies/tutorial007.py!}
+{!../../docs_src/dependencies/tutorial007.py!}
```
Код, следующий за оператором `yield`, выполняется после доставки ответа:
```Python hl_lines="5-6"
-{!../../../docs_src/dependencies/tutorial007.py!}
+{!../../docs_src/dependencies/tutorial007.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Можно использовать как `async` так и обычные функции.
@@ -64,7 +64,7 @@ FastAPI поддерживает зависимости, которые выпо
Таким же образом можно использовать `finally`, чтобы убедиться, что обязательные шаги при выходе выполнены, независимо от того, было ли исключение или нет.
```Python hl_lines="3 5"
-{!../../../docs_src/dependencies/tutorial007.py!}
+{!../../docs_src/dependencies/tutorial007.py!}
```
## Подзависимости с `yield`
@@ -78,7 +78,7 @@ FastAPI поддерживает зависимости, которые выпо
//// tab | Python 3.9+
```Python hl_lines="6 14 22"
-{!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial008_an_py39.py!}
```
////
@@ -86,21 +86,21 @@ FastAPI поддерживает зависимости, которые выпо
//// tab | Python 3.6+
```Python hl_lines="5 13 21"
-{!> ../../../docs_src/dependencies/tutorial008_an.py!}
+{!> ../../docs_src/dependencies/tutorial008_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="4 12 20"
-{!> ../../../docs_src/dependencies/tutorial008.py!}
+{!> ../../docs_src/dependencies/tutorial008.py!}
```
////
@@ -114,7 +114,7 @@ FastAPI поддерживает зависимости, которые выпо
//// tab | Python 3.9+
```Python hl_lines="18-19 26-27"
-{!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial008_an_py39.py!}
```
////
@@ -122,21 +122,21 @@ FastAPI поддерживает зависимости, которые выпо
//// tab | Python 3.6+
```Python hl_lines="17-18 25-26"
-{!> ../../../docs_src/dependencies/tutorial008_an.py!}
+{!> ../../docs_src/dependencies/tutorial008_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="16-17 24-25"
-{!> ../../../docs_src/dependencies/tutorial008.py!}
+{!> ../../docs_src/dependencies/tutorial008.py!}
```
////
@@ -149,7 +149,7 @@ FastAPI поддерживает зависимости, которые выпо
**FastAPI** проследит за тем, чтобы все выполнялось в правильном порядке.
-/// note | "Технические детали"
+/// note | Технические детали
Это работает благодаря Контекстным менеджерам в Python.
@@ -177,7 +177,7 @@ FastAPI поддерживает зависимости, которые выпо
Если у вас есть пользовательские исключения, которые вы хотите обрабатывать *до* возврата ответа и, возможно, модифицировать ответ, даже вызывая `HTTPException`, создайте [Cобственный обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
-/// tip | "Подсказка"
+/// tip | Подсказка
Вы все еще можете вызывать исключения, включая `HTTPException`, *до* `yield`. Но не после.
@@ -225,7 +225,7 @@ participant tasks as Background tasks
end
```
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Клиенту будет отправлен только **один ответ**. Это может быть один из ответов об ошибке или это будет ответ от *операции пути*.
@@ -233,7 +233,7 @@ participant tasks as Background tasks
///
-/// tip | "Подсказка"
+/// tip | Подсказка
На этой диаграмме показано "HttpException", но вы также можете вызвать любое другое исключение, для которого вы создаете [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
@@ -243,7 +243,7 @@ participant tasks as Background tasks
## Зависимости с `yield`, `HTTPException` и фоновыми задачами
-/// warning | "Внимание"
+/// warning | Внимание
Скорее всего, вам не нужны эти технические подробности, вы можете пропустить этот раздел и продолжить ниже.
@@ -257,7 +257,7 @@ participant tasks as Background tasks
Тем не менее, поскольку это означало бы ожидание ответа в сети, а также ненужное удержание ресурса в зависимости от доходности (например, соединение с базой данных), это было изменено в FastAPI 0.106.0.
-/// tip | "Подсказка"
+/// tip | Подсказка
Кроме того, фоновая задача обычно представляет собой независимый набор логики, который должен обрабатываться отдельно, со своими собственными ресурсами (например, собственным подключением к базе данных).
Таким образом, вы, вероятно, получите более чистый код.
@@ -290,7 +290,7 @@ with open("./somefile.txt") as f:
### Использование менеджеров контекста в зависимостях с помощью `yield`
-/// warning | "Внимание"
+/// warning | Внимание
Это более или менее "продвинутая" идея.
@@ -304,10 +304,10 @@ with open("./somefile.txt") as f:
`with` или `async with` внутри функции зависимости:
```Python hl_lines="1-9 13"
-{!../../../docs_src/dependencies/tutorial010.py!}
+{!../../docs_src/dependencies/tutorial010.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Другой способ создания контекстного менеджера - с помощью:
diff --git a/docs/ru/docs/tutorial/dependencies/global-dependencies.md b/docs/ru/docs/tutorial/dependencies/global-dependencies.md
index 9e03e3723..a4dfeb8ac 100644
--- a/docs/ru/docs/tutorial/dependencies/global-dependencies.md
+++ b/docs/ru/docs/tutorial/dependencies/global-dependencies.md
@@ -9,7 +9,7 @@
//// tab | Python 3.9+
```Python hl_lines="16"
-{!> ../../../docs_src/dependencies/tutorial012_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial012_an_py39.py!}
```
////
@@ -17,21 +17,21 @@
//// tab | Python 3.8+
```Python hl_lines="16"
-{!> ../../../docs_src/dependencies/tutorial012_an.py!}
+{!> ../../docs_src/dependencies/tutorial012_an.py!}
```
////
//// tab | Python 3.8 non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать 'Annotated' версию, если это возможно.
///
```Python hl_lines="15"
-{!> ../../../docs_src/dependencies/tutorial012.py!}
+{!> ../../docs_src/dependencies/tutorial012.py!}
```
////
diff --git a/docs/ru/docs/tutorial/dependencies/index.md b/docs/ru/docs/tutorial/dependencies/index.md
index b244b3fdc..b6cf7c780 100644
--- a/docs/ru/docs/tutorial/dependencies/index.md
+++ b/docs/ru/docs/tutorial/dependencies/index.md
@@ -32,7 +32,7 @@
//// tab | Python 3.10+
```Python hl_lines="8-9"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -40,7 +40,7 @@
//// tab | Python 3.9+
```Python hl_lines="8-11"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -48,35 +48,35 @@
//// tab | Python 3.8+
```Python hl_lines="9-12"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
///
```Python hl_lines="6-7"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
///
```Python hl_lines="8-11"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -99,7 +99,7 @@
И в конце она возвращает `dict`, содержащий эти значения.
-/// info | "Информация"
+/// info | Информация
**FastAPI** добавил поддержку для `Annotated` (и начал её рекомендовать) в версии 0.95.0.
@@ -114,7 +114,7 @@
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -122,7 +122,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -130,35 +130,35 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
///
```Python hl_lines="1"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
///
```Python hl_lines="3"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -170,7 +170,7 @@
//// tab | Python 3.10+
```Python hl_lines="13 18"
-{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
```
////
@@ -178,7 +178,7 @@
//// tab | Python 3.9+
```Python hl_lines="15 20"
-{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
```
////
@@ -186,35 +186,35 @@
//// tab | Python 3.8+
```Python hl_lines="16 21"
-{!> ../../../docs_src/dependencies/tutorial001_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
///
```Python hl_lines="11 16"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
///
```Python hl_lines="15 20"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -225,7 +225,7 @@
И потом функция берёт параметры так же, как *функция обработки пути*.
-/// tip | "Подсказка"
+/// tip | Подсказка
В следующей главе вы увидите, какие другие вещи, помимо функций, можно использовать в качестве зависимостей.
@@ -250,7 +250,7 @@ common_parameters --> read_users
Таким образом, вы пишете общий код один раз, и **FastAPI** позаботится о его вызове для ваших *операций с путями*.
-/// check | "Проверка"
+/// check | Проверка
Обратите внимание, что вы не создаёте специальный класс и не передаёте его куда-то в **FastAPI** для регистрации, или что-то в этом роде.
@@ -273,7 +273,7 @@ commons: Annotated[dict, Depends(common_parameters)]
//// tab | Python 3.10+
```Python hl_lines="12 16 21"
-{!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_02_an_py310.py!}
```
////
@@ -281,7 +281,7 @@ commons: Annotated[dict, Depends(common_parameters)]
//// tab | Python 3.9+
```Python hl_lines="14 18 23"
-{!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial001_02_an_py39.py!}
```
////
@@ -289,12 +289,12 @@ commons: Annotated[dict, Depends(common_parameters)]
//// tab | Python 3.8+
```Python hl_lines="15 19 24"
-{!> ../../../docs_src/dependencies/tutorial001_02_an.py!}
+{!> ../../docs_src/dependencies/tutorial001_02_an.py!}
```
////
-/// tip | "Подсказка"
+/// tip | Подсказка
Это стандартный синтаксис python и называется "type alias", это не особенность **FastAPI**.
@@ -316,7 +316,7 @@ commons: Annotated[dict, Depends(common_parameters)]
Это всё не важно. **FastAPI** знает, что нужно сделать. 😎
-/// note | "Информация"
+/// note | Информация
Если вам эта тема не знакома, прочтите [Async: *"In a hurry?"*](../../async.md){.internal-link target=_blank} раздел о `async` и `await` в документации.
diff --git a/docs/ru/docs/tutorial/dependencies/sub-dependencies.md b/docs/ru/docs/tutorial/dependencies/sub-dependencies.md
index 332470396..0e8cb20e7 100644
--- a/docs/ru/docs/tutorial/dependencies/sub-dependencies.md
+++ b/docs/ru/docs/tutorial/dependencies/sub-dependencies.md
@@ -13,7 +13,7 @@
//// tab | Python 3.10+
```Python hl_lines="8-9"
-{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial005_an_py310.py!}
```
////
@@ -21,7 +21,7 @@
//// tab | Python 3.9+
```Python hl_lines="8-9"
-{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial005_an_py39.py!}
```
////
@@ -29,35 +29,35 @@
//// tab | Python 3.6+
```Python hl_lines="9-10"
-{!> ../../../docs_src/dependencies/tutorial005_an.py!}
+{!> ../../docs_src/dependencies/tutorial005_an.py!}
```
////
//// tab | Python 3.10 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="6-7"
-{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
+{!> ../../docs_src/dependencies/tutorial005_py310.py!}
```
////
//// tab | Python 3.6 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="8-9"
-{!> ../../../docs_src/dependencies/tutorial005.py!}
+{!> ../../docs_src/dependencies/tutorial005.py!}
```
////
@@ -73,7 +73,7 @@
//// tab | Python 3.10+
```Python hl_lines="13"
-{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial005_an_py310.py!}
```
////
@@ -81,7 +81,7 @@
//// tab | Python 3.9+
```Python hl_lines="13"
-{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial005_an_py39.py!}
```
////
@@ -89,35 +89,35 @@
//// tab | Python 3.6+
```Python hl_lines="14"
-{!> ../../../docs_src/dependencies/tutorial005_an.py!}
+{!> ../../docs_src/dependencies/tutorial005_an.py!}
```
////
//// tab | Python 3.10 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="11"
-{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
+{!> ../../docs_src/dependencies/tutorial005_py310.py!}
```
////
//// tab | Python 3.6 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="13"
-{!> ../../../docs_src/dependencies/tutorial005.py!}
+{!> ../../docs_src/dependencies/tutorial005.py!}
```
////
@@ -136,7 +136,7 @@
//// tab | Python 3.10+
```Python hl_lines="23"
-{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
+{!> ../../docs_src/dependencies/tutorial005_an_py310.py!}
```
////
@@ -144,7 +144,7 @@
//// tab | Python 3.9+
```Python hl_lines="23"
-{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial005_an_py39.py!}
```
////
@@ -152,40 +152,40 @@
//// tab | Python 3.6+
```Python hl_lines="24"
-{!> ../../../docs_src/dependencies/tutorial005_an.py!}
+{!> ../../docs_src/dependencies/tutorial005_an.py!}
```
////
//// tab | Python 3.10 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
+{!> ../../docs_src/dependencies/tutorial005_py310.py!}
```
////
//// tab | Python 3.6 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="22"
-{!> ../../../docs_src/dependencies/tutorial005.py!}
+{!> ../../docs_src/dependencies/tutorial005.py!}
```
////
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Обратите внимание, что мы объявляем только одну зависимость в *функции операции пути* - `query_or_cookie_extractor`.
@@ -223,7 +223,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
@@ -244,7 +244,7 @@ async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False
Но, тем не менее, эта система очень мощная и позволяет вам объявлять вложенные графы (деревья) зависимостей сколь угодно глубоко.
-/// tip | "Подсказка"
+/// tip | Подсказка
Все это может показаться не столь полезным на этих простых примерах.
diff --git a/docs/ru/docs/tutorial/encoder.md b/docs/ru/docs/tutorial/encoder.md
index 02c3587f3..523644ac8 100644
--- a/docs/ru/docs/tutorial/encoder.md
+++ b/docs/ru/docs/tutorial/encoder.md
@@ -23,7 +23,7 @@
//// tab | Python 3.10+
```Python hl_lines="4 21"
-{!> ../../../docs_src/encoder/tutorial001_py310.py!}
+{!> ../../docs_src/encoder/tutorial001_py310.py!}
```
////
@@ -31,7 +31,7 @@
//// tab | Python 3.6+
```Python hl_lines="5 22"
-{!> ../../../docs_src/encoder/tutorial001.py!}
+{!> ../../docs_src/encoder/tutorial001.py!}
```
////
@@ -42,7 +42,7 @@
Функция не возвращает большой `str`, содержащий данные в формате JSON (в виде строки). Она возвращает стандартную структуру данных Python (например, `dict`) со значениями и подзначениями, которые совместимы с JSON.
-/// note | "Технические детали"
+/// note | Технические детали
`jsonable_encoder` фактически используется **FastAPI** внутри системы для преобразования данных. Однако он полезен и во многих других сценариях.
diff --git a/docs/ru/docs/tutorial/extra-data-types.md b/docs/ru/docs/tutorial/extra-data-types.md
index 2650bb0af..82cb0ff7a 100644
--- a/docs/ru/docs/tutorial/extra-data-types.md
+++ b/docs/ru/docs/tutorial/extra-data-types.md
@@ -58,7 +58,7 @@
//// tab | Python 3.8 и выше
```Python hl_lines="1 3 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001.py!}
+{!> ../../docs_src/extra_data_types/tutorial001.py!}
```
////
@@ -66,7 +66,7 @@
//// tab | Python 3.10 и выше
```Python hl_lines="1 2 11-15"
-{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
```
////
@@ -76,7 +76,7 @@
//// tab | Python 3.8 и выше
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001.py!}
+{!> ../../docs_src/extra_data_types/tutorial001.py!}
```
////
@@ -84,7 +84,7 @@
//// tab | Python 3.10 и выше
```Python hl_lines="17-18"
-{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
```
////
diff --git a/docs/ru/docs/tutorial/extra-models.md b/docs/ru/docs/tutorial/extra-models.md
index 2aac76aa3..241f70779 100644
--- a/docs/ru/docs/tutorial/extra-models.md
+++ b/docs/ru/docs/tutorial/extra-models.md
@@ -8,7 +8,7 @@
* **Модель для вывода** не должна содержать пароль.
* **Модель для базы данных**, возможно, должна содержать хэшированный пароль.
-/// danger | "Внимание"
+/// danger | Внимание
Никогда не храните пароли пользователей в чистом виде. Всегда храните "безопасный хэш", который вы затем сможете проверить.
@@ -23,7 +23,7 @@
//// tab | Python 3.10+
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
-{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
+{!> ../../docs_src/extra_models/tutorial001_py310.py!}
```
////
@@ -31,7 +31,7 @@
//// tab | Python 3.8+
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
-{!> ../../../docs_src/extra_models/tutorial001.py!}
+{!> ../../docs_src/extra_models/tutorial001.py!}
```
////
@@ -146,7 +146,7 @@ UserInDB(
)
```
-/// warning | "Предупреждение"
+/// warning | Предупреждение
Цель использованных в примере вспомогательных функций - не более чем демонстрация возможных операций с данными, но, конечно, они не обеспечивают настоящую безопасность.
@@ -171,7 +171,7 @@ UserInDB(
//// tab | Python 3.10+
```Python hl_lines="7 13-14 17-18 21-22"
-{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
+{!> ../../docs_src/extra_models/tutorial002_py310.py!}
```
////
@@ -179,7 +179,7 @@ UserInDB(
//// tab | Python 3.8+
```Python hl_lines="9 15-16 19-20 23-24"
-{!> ../../../docs_src/extra_models/tutorial002.py!}
+{!> ../../docs_src/extra_models/tutorial002.py!}
```
////
@@ -192,7 +192,7 @@ UserInDB(
Для этого используйте стандартные аннотации типов в Python `typing.Union`:
-/// note | "Примечание"
+/// note | Примечание
При объявлении `Union`, сначала указывайте наиболее детальные типы, затем менее детальные. В примере ниже более детальный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
@@ -201,7 +201,7 @@ UserInDB(
//// tab | Python 3.10+
```Python hl_lines="1 14-15 18-20 33"
-{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
+{!> ../../docs_src/extra_models/tutorial003_py310.py!}
```
////
@@ -209,7 +209,7 @@ UserInDB(
//// tab | Python 3.8+
```Python hl_lines="1 14-15 18-20 33"
-{!> ../../../docs_src/extra_models/tutorial003.py!}
+{!> ../../docs_src/extra_models/tutorial003.py!}
```
////
@@ -237,7 +237,7 @@ some_variable: PlaneItem | CarItem
//// tab | Python 3.9+
```Python hl_lines="18"
-{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
+{!> ../../docs_src/extra_models/tutorial004_py39.py!}
```
////
@@ -245,7 +245,7 @@ some_variable: PlaneItem | CarItem
//// tab | Python 3.8+
```Python hl_lines="1 20"
-{!> ../../../docs_src/extra_models/tutorial004.py!}
+{!> ../../docs_src/extra_models/tutorial004.py!}
```
////
@@ -261,7 +261,7 @@ some_variable: PlaneItem | CarItem
//// tab | Python 3.9+
```Python hl_lines="6"
-{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
+{!> ../../docs_src/extra_models/tutorial005_py39.py!}
```
////
@@ -269,7 +269,7 @@ some_variable: PlaneItem | CarItem
//// tab | Python 3.8+
```Python hl_lines="1 8"
-{!> ../../../docs_src/extra_models/tutorial005.py!}
+{!> ../../docs_src/extra_models/tutorial005.py!}
```
////
diff --git a/docs/ru/docs/tutorial/first-steps.md b/docs/ru/docs/tutorial/first-steps.md
index e60d58823..309f26c4f 100644
--- a/docs/ru/docs/tutorial/first-steps.md
+++ b/docs/ru/docs/tutorial/first-steps.md
@@ -3,7 +3,7 @@
Самый простой FastAPI файл может выглядеть так:
```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Скопируйте в файл `main.py`.
@@ -24,7 +24,7 @@ $ uvicorn main:app --reload
-/// note | "Технические детали"
+/// note | Технические детали
Команда `uvicorn main:app` обращается к:
@@ -134,12 +134,12 @@ OpenAPI описывает схему API. Эта схема содержит о
### Шаг 1: импортируйте `FastAPI`
```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` это класс в Python, который предоставляет всю функциональность для API.
-/// note | "Технические детали"
+/// note | Технические детали
`FastAPI` это класс, который наследуется непосредственно от `Starlette`.
@@ -150,7 +150,7 @@ OpenAPI описывает схему API. Эта схема содержит о
### Шаг 2: создайте экземпляр `FastAPI`
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Переменная `app` является экземпляром класса `FastAPI`.
@@ -172,7 +172,7 @@ $ uvicorn main:app --reload
Если создать такое приложение:
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial002.py!}
+{!../../docs_src/first_steps/tutorial002.py!}
```
И поместить его в `main.py`, тогда вызов `uvicorn` будет таким:
@@ -205,7 +205,7 @@ https://example.com/items/foo
/items/foo
```
-/// info | "Дополнительная иформация"
+/// info | Дополнительная иформация
Термин "path" также часто называется "endpoint" или "route".
@@ -251,7 +251,7 @@ https://example.com/items/foo
#### Определите *декоратор операции пути (path operation decorator)*
```Python hl_lines="6"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Декоратор `@app.get("/")` указывает **FastAPI**, что функция, прямо под ним, отвечает за обработку запросов, поступающих по адресу:
@@ -259,7 +259,7 @@ https://example.com/items/foo
* путь `/`
* использующих get операцию
-/// info | "`@decorator` Дополнительная информация"
+/// info | `@decorator` Дополнительная информация
Синтаксис `@something` в Python называется "декоратор".
@@ -286,7 +286,7 @@ https://example.com/items/foo
* `@app.patch()`
* `@app.trace()`
-/// tip | "Подсказка"
+/// tip | Подсказка
Вы можете использовать каждую операцию (HTTP-метод) по своему усмотрению.
@@ -307,7 +307,7 @@ https://example.com/items/foo
* **функция**: функция ниже "декоратора" (ниже `@app.get("/")`).
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Это обычная Python функция.
@@ -321,10 +321,10 @@ https://example.com/items/foo
Вы также можете определить ее как обычную функцию вместо `async def`:
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
+{!../../docs_src/first_steps/tutorial003.py!}
```
-/// note | "Технические детали"
+/// note | Технические детали
Если не знаете в чём разница, посмотрите [Конкурентность: *"Нет времени?"*](../async.md#_1){.internal-link target=_blank}.
@@ -333,7 +333,7 @@ https://example.com/items/foo
### Шаг 5: верните результат
```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д.
diff --git a/docs/ru/docs/tutorial/handling-errors.md b/docs/ru/docs/tutorial/handling-errors.md
index 028f3e0d2..a06644376 100644
--- a/docs/ru/docs/tutorial/handling-errors.md
+++ b/docs/ru/docs/tutorial/handling-errors.md
@@ -26,7 +26,7 @@
### Импортируйте `HTTPException`
```Python hl_lines="1"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### Вызовите `HTTPException` в своем коде
@@ -42,7 +42,7 @@
В данном примере, когда клиент запрашивает элемент по несуществующему ID, возникает исключение со статус-кодом `404`:
```Python hl_lines="11"
-{!../../../docs_src/handling_errors/tutorial001.py!}
+{!../../docs_src/handling_errors/tutorial001.py!}
```
### Возвращаемый ответ
@@ -63,7 +63,7 @@
}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
При вызове `HTTPException` в качестве параметра `detail` можно передавать любое значение, которое может быть преобразовано в JSON, а не только `str`.
@@ -82,7 +82,7 @@
Но в случае, если это необходимо для продвинутого сценария, можно добавить пользовательские заголовки:
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial002.py!}
+{!../../docs_src/handling_errors/tutorial002.py!}
```
## Установка пользовательских обработчиков исключений
@@ -96,7 +96,7 @@
Можно добавить собственный обработчик исключений с помощью `@app.exception_handler()`:
```Python hl_lines="5-7 13-18 24"
-{!../../../docs_src/handling_errors/tutorial003.py!}
+{!../../docs_src/handling_errors/tutorial003.py!}
```
Здесь, если запросить `/unicorns/yolo`, то *операция пути* вызовет `UnicornException`.
@@ -109,7 +109,7 @@
{"message": "Oops! yolo did something. There goes a rainbow..."}
```
-/// note | "Технические детали"
+/// note | Технические детали
Также можно использовать `from starlette.requests import Request` и `from starlette.responses import JSONResponse`.
@@ -136,7 +136,7 @@
Обработчик исключения получит объект `Request` и исключение.
```Python hl_lines="2 14-16"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
Теперь, если перейти к `/items/foo`, то вместо стандартной JSON-ошибки с:
@@ -166,7 +166,7 @@ path -> item_id
#### `RequestValidationError` или `ValidationError`
-/// warning | "Внимание"
+/// warning | Внимание
Это технические детали, которые можно пропустить, если они не важны для вас сейчас.
@@ -189,10 +189,10 @@ path -> item_id
Например, для этих ошибок можно вернуть обычный текстовый ответ вместо JSON:
```Python hl_lines="3-4 9-11 22"
-{!../../../docs_src/handling_errors/tutorial004.py!}
+{!../../docs_src/handling_errors/tutorial004.py!}
```
-/// note | "Технические детали"
+/// note | Технические детали
Можно также использовать `from starlette.responses import PlainTextResponse`.
@@ -207,7 +207,7 @@ path -> item_id
Вы можете использовать его при разработке приложения для регистрации тела и его отладки, возврата пользователю и т.д.
```Python hl_lines="14"
-{!../../../docs_src/handling_errors/tutorial005.py!}
+{!../../docs_src/handling_errors/tutorial005.py!}
```
Теперь попробуйте отправить недействительный элемент, например:
@@ -267,7 +267,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
Если вы хотите использовать исключение вместе с теми же обработчиками исключений по умолчанию из **FastAPI**, вы можете импортировать и повторно использовать обработчики исключений по умолчанию из `fastapi.exception_handlers`:
```Python hl_lines="2-5 15 21"
-{!../../../docs_src/handling_errors/tutorial006.py!}
+{!../../docs_src/handling_errors/tutorial006.py!}
```
В этом примере вы просто `выводите в терминал` ошибку с очень выразительным сообщением, но идея вам понятна. Вы можете использовать исключение, а затем просто повторно использовать стандартные обработчики исключений.
diff --git a/docs/ru/docs/tutorial/header-params.md b/docs/ru/docs/tutorial/header-params.md
index 3b5e38328..904709b04 100644
--- a/docs/ru/docs/tutorial/header-params.md
+++ b/docs/ru/docs/tutorial/header-params.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001_an.py!}
+{!> ../../docs_src/header_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="1"
-{!> ../../../docs_src/header_params/tutorial001_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="3"
-{!> ../../../docs_src/header_params/tutorial001.py!}
+{!> ../../docs_src/header_params/tutorial001.py!}
```
////
@@ -67,7 +67,7 @@
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py310.py!}
```
////
@@ -75,7 +75,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial001_an_py39.py!}
```
////
@@ -83,40 +83,40 @@
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial001_an.py!}
+{!> ../../docs_src/header_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/header_params/tutorial001_py310.py!}
+{!> ../../docs_src/header_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial001.py!}
+{!> ../../docs_src/header_params/tutorial001.py!}
```
////
-/// note | "Технические детали"
+/// note | Технические детали
`Header` - это "родственный" класс `Path`, `Query` и `Cookie`. Он также наследуется от того же общего класса `Param`.
@@ -124,7 +124,7 @@
///
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Чтобы объявить заголовки, важно использовать `Header`, иначе параметры интерпретируются как query-параметры.
@@ -149,7 +149,7 @@
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial002_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial002_an_py310.py!}
```
////
@@ -157,7 +157,7 @@
//// tab | Python 3.9+
```Python hl_lines="11"
-{!> ../../../docs_src/header_params/tutorial002_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial002_an_py39.py!}
```
////
@@ -165,40 +165,40 @@
//// tab | Python 3.8+
```Python hl_lines="12"
-{!> ../../../docs_src/header_params/tutorial002_an.py!}
+{!> ../../docs_src/header_params/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="8"
-{!> ../../../docs_src/header_params/tutorial002_py310.py!}
+{!> ../../docs_src/header_params/tutorial002_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial002.py!}
+{!> ../../docs_src/header_params/tutorial002.py!}
```
////
-/// warning | "Внимание"
+/// warning | Внимание
Прежде чем установить для `convert_underscores` значение `False`, имейте в виду, что некоторые HTTP-прокси и серверы запрещают использование заголовков с подчеркиванием.
@@ -217,7 +217,7 @@
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_an_py310.py!}
+{!> ../../docs_src/header_params/tutorial003_an_py310.py!}
```
////
@@ -225,7 +225,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_an_py39.py!}
+{!> ../../docs_src/header_params/tutorial003_an_py39.py!}
```
////
@@ -233,49 +233,49 @@
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/header_params/tutorial003_an.py!}
+{!> ../../docs_src/header_params/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/header_params/tutorial003_py310.py!}
+{!> ../../docs_src/header_params/tutorial003_py310.py!}
```
////
//// tab | Python 3.9+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003_py39.py!}
+{!> ../../docs_src/header_params/tutorial003_py39.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/header_params/tutorial003.py!}
+{!> ../../docs_src/header_params/tutorial003.py!}
```
////
diff --git a/docs/ru/docs/tutorial/index.md b/docs/ru/docs/tutorial/index.md
index 4cf45c0ed..ddca2fbb1 100644
--- a/docs/ru/docs/tutorial/index.md
+++ b/docs/ru/docs/tutorial/index.md
@@ -52,7 +52,7 @@ $ pip install "fastapi[all]"
...это также включает `uvicorn`, который вы можете использовать в качестве сервера, который запускает ваш код.
-/// note | "Технические детали"
+/// note | Технические детали
Вы также можете установить его по частям.
diff --git a/docs/ru/docs/tutorial/metadata.md b/docs/ru/docs/tutorial/metadata.md
index 9799fe538..ae739a043 100644
--- a/docs/ru/docs/tutorial/metadata.md
+++ b/docs/ru/docs/tutorial/metadata.md
@@ -18,10 +18,10 @@
Вы можете задать их следующим образом:
```Python hl_lines="3-16 19-31"
-{!../../../docs_src/metadata/tutorial001.py!}
+{!../../docs_src/metadata/tutorial001.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Вы можете использовать Markdown в поле `description`, и оно будет отображено в выводе.
@@ -52,12 +52,12 @@
Создайте метаданные для ваших тегов и передайте их в параметре `openapi_tags`:
```Python hl_lines="3-16 18"
-{!../../../docs_src/metadata/tutorial004.py!}
+{!../../docs_src/metadata/tutorial004.py!}
```
Помните, что вы можете использовать Markdown внутри описания, к примеру "login" будет отображен жирным шрифтом (**login**) и "fancy" будет отображаться курсивом (_fancy_).
-/// tip | "Подсказка"
+/// tip | Подсказка
Вам необязательно добавлять метаданные для всех используемых тегов
@@ -67,10 +67,10 @@
Используйте параметр `tags` с вашими *операциями пути* (и `APIRouter`ами), чтобы присвоить им различные теги:
```Python hl_lines="21 26"
-{!../../../docs_src/metadata/tutorial004.py!}
+{!../../docs_src/metadata/tutorial004.py!}
```
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Узнайте больше о тегах в [Конфигурации операции пути](path-operation-configuration.md#_3){.internal-link target=_blank}.
@@ -97,7 +97,7 @@
К примеру, чтобы задать её отображение по адресу `/api/v1/openapi.json`:
```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial002.py!}
+{!../../docs_src/metadata/tutorial002.py!}
```
Если вы хотите отключить схему OpenAPI полностью, вы можете задать `openapi_url=None`, это также отключит пользовательские интерфейсы документации, которые его использует.
@@ -116,5 +116,5 @@
К примеру, чтобы задать отображение Swagger UI по адресу `/documentation` и отключить ReDoc:
```Python hl_lines="3"
-{!../../../docs_src/metadata/tutorial003.py!}
+{!../../docs_src/metadata/tutorial003.py!}
```
diff --git a/docs/ru/docs/tutorial/path-operation-configuration.md b/docs/ru/docs/tutorial/path-operation-configuration.md
index 26b1726ad..ac12b7084 100644
--- a/docs/ru/docs/tutorial/path-operation-configuration.md
+++ b/docs/ru/docs/tutorial/path-operation-configuration.md
@@ -2,7 +2,7 @@
Существует несколько параметров, которые вы можете передать вашему *декоратору операций пути* для его настройки.
-/// warning | "Внимание"
+/// warning | Внимание
Помните, что эти параметры передаются непосредственно *декоратору операций пути*, а не вашей *функции-обработчику операций пути*.
@@ -19,7 +19,7 @@
//// tab | Python 3.10+
```Python hl_lines="1 15"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py310.py!}
```
////
@@ -27,7 +27,7 @@
//// tab | Python 3.9+
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001_py39.py!}
```
////
@@ -35,14 +35,14 @@
//// tab | Python 3.8+
```Python hl_lines="3 17"
-{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial001.py!}
```
////
Этот код состояния будет использован в ответе и будет добавлен в схему OpenAPI.
-/// note | "Технические детали"
+/// note | Технические детали
Вы также можете использовать `from starlette import status`.
@@ -57,7 +57,7 @@
//// tab | Python 3.10+
```Python hl_lines="15 20 25"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py310.py!}
```
////
@@ -65,7 +65,7 @@
//// tab | Python 3.9+
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002_py39.py!}
```
////
@@ -73,7 +73,7 @@
//// tab | Python 3.8+
```Python hl_lines="17 22 27"
-{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial002.py!}
```
////
@@ -91,7 +91,7 @@
**FastAPI** поддерживает это так же, как и в случае с обычными строками:
```Python hl_lines="1 8-10 13 18"
-{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
+{!../../docs_src/path_operation_configuration/tutorial002b.py!}
```
## Краткое и развёрнутое содержание
@@ -101,7 +101,7 @@
//// tab | Python 3.10+
```Python hl_lines="18-19"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py310.py!}
```
////
@@ -109,7 +109,7 @@
//// tab | Python 3.9+
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003_py39.py!}
```
////
@@ -117,7 +117,7 @@
//// tab | Python 3.8+
```Python hl_lines="20-21"
-{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial003.py!}
```
////
@@ -131,7 +131,7 @@
//// tab | Python 3.10+
```Python hl_lines="17-25"
-{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py310.py!}
```
////
@@ -139,7 +139,7 @@
//// tab | Python 3.9+
```Python hl_lines="19-27"
-{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004_py39.py!}
```
////
@@ -147,7 +147,7 @@
//// tab | Python 3.8+
```Python hl_lines="19-27"
-{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial004.py!}
```
////
@@ -163,7 +163,7 @@
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py310.py!}
```
////
@@ -171,7 +171,7 @@
//// tab | Python 3.9+
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005_py39.py!}
```
////
@@ -179,18 +179,18 @@
//// tab | Python 3.8+
```Python hl_lines="21"
-{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
+{!> ../../docs_src/path_operation_configuration/tutorial005.py!}
```
////
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Помните, что `response_description` относится конкретно к ответу, а `description` относится к *операции пути* в целом.
///
-/// check | "Технические детали"
+/// check | Технические детали
OpenAPI указывает, что каждой *операции пути* необходимо описание ответа.
@@ -205,7 +205,7 @@ OpenAPI указывает, что каждой *операции пути* не
Если вам необходимо пометить *операцию пути* как устаревшую, при этом не удаляя её, передайте параметр `deprecated`:
```Python hl_lines="16"
-{!../../../docs_src/path_operation_configuration/tutorial006.py!}
+{!../../docs_src/path_operation_configuration/tutorial006.py!}
```
Он будет четко помечен как устаревший в интерактивной документации:
diff --git a/docs/ru/docs/tutorial/path-params-numeric-validations.md b/docs/ru/docs/tutorial/path-params-numeric-validations.md
index ced12c826..ed19576a2 100644
--- a/docs/ru/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/ru/docs/tutorial/path-params-numeric-validations.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="1 3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="1 3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
////
@@ -25,40 +25,40 @@
//// tab | Python 3.8+
```Python hl_lines="3-4"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="1"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="3"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
-/// info | "Информация"
+/// info | Информация
Поддержка `Annotated` была добавлена в FastAPI начиная с версии 0.95.0 (и с этой версии рекомендуется использовать этот подход).
@@ -77,7 +77,7 @@
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
```
////
@@ -85,7 +85,7 @@
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
////
@@ -93,40 +93,40 @@
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
////
-/// note | "Примечание"
+/// note | Примечание
Path-параметр всегда является обязательным, поскольку он составляет часть пути.
@@ -138,7 +138,7 @@ Path-параметр всегда является обязательным, п
## Задайте нужный вам порядок параметров
-/// tip | "Подсказка"
+/// tip | Подсказка
Это не имеет большого значения, если вы используете `Annotated`.
@@ -160,14 +160,14 @@ Path-параметр всегда является обязательным, п
//// tab | Python 3.8 без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
////
@@ -177,7 +177,7 @@ Path-параметр всегда является обязательным, п
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
```
////
@@ -185,14 +185,14 @@ Path-параметр всегда является обязательным, п
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
```
////
## Задайте нужный вам порядок параметров, полезные приёмы
-/// tip | "Подсказка"
+/// tip | Подсказка
Это не имеет большого значения, если вы используете `Annotated`.
@@ -214,7 +214,7 @@ Path-параметр всегда является обязательным, п
Python не будет ничего делать с `*`, но он будет знать, что все следующие параметры являются именованными аргументами (парами ключ-значение), также известными как kwargs, даже если у них нет значений по умолчанию.
```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
### Лучше с `Annotated`
@@ -224,7 +224,7 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
```
////
@@ -232,7 +232,7 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
```
////
@@ -246,7 +246,7 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
```
////
@@ -254,21 +254,21 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="8"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
////
@@ -283,7 +283,7 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
```
////
@@ -291,21 +291,21 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
////
@@ -323,7 +323,7 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.9+
```Python hl_lines="13"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
```
////
@@ -331,21 +331,21 @@ Python не будет ничего делать с `*`, но он будет з
//// tab | Python 3.8+
```Python hl_lines="12"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="11"
-{!> ../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+{!> ../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
////
@@ -361,7 +361,7 @@ Python не будет ничего делать с `*`, но он будет з
* `lt`: меньше (`l`ess `t`han)
* `le`: меньше или равно (`l`ess than or `e`qual)
-/// info | "Информация"
+/// info | Информация
`Query`, `Path` и другие классы, которые мы разберём позже, являются наследниками общего класса `Param`.
@@ -369,7 +369,7 @@ Python не будет ничего делать с `*`, но он будет з
///
-/// note | "Технические детали"
+/// note | Технические детали
`Query`, `Path` и другие "классы", которые вы импортируете из `fastapi`, на самом деле являются функциями, которые при вызове возвращают экземпляры одноимённых классов.
diff --git a/docs/ru/docs/tutorial/path-params.md b/docs/ru/docs/tutorial/path-params.md
index dc3d64af4..ba23ba5ea 100644
--- a/docs/ru/docs/tutorial/path-params.md
+++ b/docs/ru/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python:
```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
@@ -19,12 +19,12 @@
Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python.
```Python hl_lines="7"
-{!../../../docs_src/path_params/tutorial002.py!}
+{!../../docs_src/path_params/tutorial002.py!}
```
Здесь, `item_id` объявлен типом `int`.
-/// check | "Заметка"
+/// check | Заметка
Это обеспечит поддержку редактора внутри функции (проверка ошибок, автодополнение и т.п.).
@@ -38,7 +38,7 @@
{"item_id":3}
```
-/// check | "Заметка"
+/// check | Заметка
Обратите внимание на значение `3`, которое получила (и вернула) функция. Это целочисленный Python `int`, а не строка `"3"`.
@@ -69,7 +69,7 @@
Та же ошибка возникнет, если вместо `int` передать `float` , например: http://127.0.0.1:8000/items/4.2
-/// check | "Заметка"
+/// check | Заметка
**FastAPI** обеспечивает проверку типов, используя всё те же определения типов.
@@ -85,7 +85,7 @@
-/// check | "Заметка"
+/// check | Заметка
Ещё раз, просто используя определения типов, **FastAPI** обеспечивает автоматическую интерактивную документацию (с интеграцией Swagger UI).
@@ -123,7 +123,7 @@
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
+{!../../docs_src/path_params/tutorial003.py!}
```
Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
@@ -131,7 +131,7 @@
Аналогично, вы не можете переопределить операцию с путем:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003b.py!}
+{!../../docs_src/path_params/tutorial003b.py!}
```
Первый будет выполняться всегда, так как путь совпадает первым.
@@ -149,16 +149,16 @@
Затем создайте атрибуты класса с фиксированными допустимыми значениями:
```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Перечисления (enum) доступны в Python начиная с версии 3.4.
///
-/// tip | "Подсказка"
+/// tip | Подсказка
Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия моделей машинного обучения.
@@ -169,7 +169,7 @@
Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### Проверьте документацию
@@ -187,7 +187,7 @@
Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`:
```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
#### Получение *значения перечисления*
@@ -195,10 +195,10 @@
Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`:
```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Значение `"lenet"` также можно получить с помощью `ModelName.lenet.value`.
@@ -211,7 +211,7 @@
Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
Вы отправите клиенту такой JSON-ответ:
@@ -251,10 +251,10 @@ OpenAPI не поддерживает способов объявления *п
Можете использовать так:
```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
+{!../../docs_src/path_params/tutorial004.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Возможно, вам понадобится, чтобы параметр содержал `/home/johndoe/myfile.txt` с ведущим слэшем (`/`).
diff --git a/docs/ru/docs/tutorial/query-params-str-validations.md b/docs/ru/docs/tutorial/query-params-str-validations.md
index e6653a837..f76570ce8 100644
--- a/docs/ru/docs/tutorial/query-params-str-validations.md
+++ b/docs/ru/docs/tutorial/query-params-str-validations.md
@@ -7,7 +7,7 @@
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial001_py310.py!}
```
////
@@ -15,14 +15,14 @@
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial001.py!}
```
////
Query-параметр `q` имеет тип `Union[str, None]` (или `str | None` в Python 3.10). Это означает, что входной параметр будет типа `str`, но может быть и `None`. Ещё параметр имеет значение по умолчанию `None`, из-за чего FastAPI определит параметр как необязательный.
-/// note | "Технические детали"
+/// note | Технические детали
FastAPI определит параметр `q` как необязательный, потому что его значение по умолчанию `= None`.
@@ -46,7 +46,7 @@ FastAPI определит параметр `q` как необязательн
В Python 3.9 или выше, `Annotated` является частью стандартной библиотеки, таким образом вы можете импортировать его из `typing`.
```Python hl_lines="1 3"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
////
@@ -58,7 +58,7 @@ FastAPI определит параметр `q` как необязательн
Эта библиотека будет установлена вместе с FastAPI.
```Python hl_lines="3-4"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
```
////
@@ -116,7 +116,7 @@ q: Annotated[Union[str, None]] = None
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
////
@@ -124,7 +124,7 @@ q: Annotated[Union[str, None]] = None
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
```
////
@@ -143,7 +143,7 @@ q: Annotated[Union[str, None]] = None
В предыдущих версиях FastAPI (ниже 0.95.0) необходимо было использовать `Query` как значение по умолчанию для query-параметра. Так было вместо размещения его в `Annotated`, так что велика вероятность, что вам встретится такой код. Сейчас объясню.
-/// tip | "Подсказка"
+/// tip | Подсказка
При написании нового кода и везде где это возможно, используйте `Annotated`, как было описано ранее. У этого способа есть несколько преимуществ (о них дальше) и никаких недостатков. 🍰
@@ -154,7 +154,7 @@ q: Annotated[Union[str, None]] = None
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
////
@@ -162,7 +162,7 @@ q: Annotated[Union[str, None]] = None
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial002.py!}
```
////
@@ -195,7 +195,7 @@ q: str | None = None
Но он явно объявляет его как query-параметр.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Запомните, важной частью объявления параметра как необязательного является:
@@ -268,7 +268,7 @@ q: str = Query(default="rick")
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_an_py310.py!}
```
////
@@ -276,7 +276,7 @@ q: str = Query(default="rick")
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_an_py39.py!}
```
////
@@ -284,35 +284,35 @@ q: str = Query(default="rick")
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial003_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial003.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial003.py!}
```
////
@@ -324,7 +324,7 @@ q: str = Query(default="rick")
//// tab | Python 3.10+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an_py310.py!}
```
////
@@ -332,7 +332,7 @@ q: str = Query(default="rick")
//// tab | Python 3.9+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an_py39.py!}
```
////
@@ -340,35 +340,35 @@ q: str = Query(default="rick")
//// tab | Python 3.8+
```Python hl_lines="12"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial004_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial004.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial004.py!}
```
////
@@ -392,7 +392,7 @@ q: str = Query(default="rick")
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial005_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial005_an_py39.py!}
```
////
@@ -400,26 +400,26 @@ q: str = Query(default="rick")
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial005_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial005_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial005.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial005.py!}
```
////
-/// note | "Технические детали"
+/// note | Технические детали
Наличие значения по умолчанию делает параметр необязательным.
@@ -462,7 +462,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006_an_py39.py!}
```
////
@@ -470,24 +470,24 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial006_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Обратите внимание, что даже когда `Query()` используется как значение по умолчанию для параметра функции, мы не передаём `default=None` в `Query()`.
@@ -504,7 +504,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006b_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py!}
```
////
@@ -512,26 +512,26 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial006b_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006b_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006b.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006b.py!}
```
////
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Если вы ранее не сталкивались с `...`: это специальное значение, часть языка Python и называется "Ellipsis".
@@ -550,7 +550,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py!}
```
////
@@ -558,7 +558,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_an_py39.py!}
```
////
@@ -566,40 +566,40 @@ q: Union[str, None] = Query(default=None, min_length=3)
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006c.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006c.py!}
```
////
-/// tip | "Подсказка"
+/// tip | Подсказка
Pydantic, мощь которого используется в FastAPI для валидации и сериализации, имеет специальное поведение для `Optional` или `Union[Something, None]` без значения по умолчанию. Вы можете узнать об этом больше в документации Pydantic, раздел Обязательные Опциональные поля.
@@ -612,7 +612,7 @@ Pydantic, мощь которого используется в FastAPI для
//// tab | Python 3.9+
```Python hl_lines="4 10"
-{!> ../../../docs_src/query_params_str_validations/tutorial006d_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006d_an_py39.py!}
```
////
@@ -620,26 +620,26 @@ Pydantic, мощь которого используется в FastAPI для
//// tab | Python 3.8+
```Python hl_lines="2 9"
-{!> ../../../docs_src/query_params_str_validations/tutorial006d_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006d_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="2 8"
-{!> ../../../docs_src/query_params_str_validations/tutorial006d.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial006d.py!}
```
////
-/// tip | "Подсказка"
+/// tip | Подсказка
Запомните, когда вам необходимо объявить query-параметр обязательным, вы можете просто не указывать параметр `default`. Таким образом, вам редко придётся использовать `...` или `Required`.
@@ -654,7 +654,7 @@ Pydantic, мощь которого используется в FastAPI для
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_an_py310.py!}
```
////
@@ -662,7 +662,7 @@ Pydantic, мощь которого используется в FastAPI для
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_an_py39.py!}
```
////
@@ -670,49 +670,49 @@ Pydantic, мощь которого используется в FastAPI для
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_py310.py!}
```
////
//// tab | Python 3.9+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011_py39.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial011.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial011.py!}
```
////
@@ -736,7 +736,7 @@ http://localhost:8000/items/?q=foo&q=bar
}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Чтобы объявить query-параметр типом `list`, как в примере выше, вам нужно явно использовать `Query`, иначе он будет интерпретирован как тело запроса.
@@ -753,7 +753,7 @@ http://localhost:8000/items/?q=foo&q=bar
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_an_py39.py!}
```
////
@@ -761,35 +761,35 @@ http://localhost:8000/items/?q=foo&q=bar
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_an.py!}
```
////
//// tab | Python 3.9+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial012_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012_py39.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial012.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial012.py!}
```
////
@@ -818,7 +818,7 @@ http://localhost:8000/items/
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial013_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial013_an_py39.py!}
```
////
@@ -826,26 +826,26 @@ http://localhost:8000/items/
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial013_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial013_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial013.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial013.py!}
```
////
-/// note | "Технические детали"
+/// note | Технические детали
Запомните, что в таком случае, FastAPI не будет проверять содержимое списка.
@@ -859,7 +859,7 @@ http://localhost:8000/items/
Указанная информация будет включена в генерируемую OpenAPI документацию и использована в пользовательском интерфейсе и внешних инструментах.
-/// note | "Технические детали"
+/// note | Технические детали
Имейте в виду, что разные инструменты могут иметь разные уровни поддержки OpenAPI.
@@ -872,7 +872,7 @@ http://localhost:8000/items/
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_an_py310.py!}
```
////
@@ -880,7 +880,7 @@ http://localhost:8000/items/
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_an_py39.py!}
```
////
@@ -888,35 +888,35 @@ http://localhost:8000/items/
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial007_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial007.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial007.py!}
```
////
@@ -926,7 +926,7 @@ http://localhost:8000/items/
//// tab | Python 3.10+
```Python hl_lines="14"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_an_py310.py!}
```
////
@@ -934,7 +934,7 @@ http://localhost:8000/items/
//// tab | Python 3.9+
```Python hl_lines="14"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_an_py39.py!}
```
////
@@ -942,35 +942,35 @@ http://localhost:8000/items/
//// tab | Python 3.8+
```Python hl_lines="15"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial008_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="13"
-{!> ../../../docs_src/query_params_str_validations/tutorial008.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial008.py!}
```
////
@@ -996,7 +996,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_an_py310.py!}
```
////
@@ -1004,7 +1004,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_an_py39.py!}
```
////
@@ -1012,35 +1012,35 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/query_params_str_validations/tutorial009_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="9"
-{!> ../../../docs_src/query_params_str_validations/tutorial009.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial009.py!}
```
////
@@ -1056,7 +1056,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_an_py310.py!}
```
////
@@ -1064,7 +1064,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.9+
```Python hl_lines="19"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_an_py39.py!}
```
////
@@ -1072,35 +1072,35 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.8+
```Python hl_lines="20"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="16"
-{!> ../../../docs_src/query_params_str_validations/tutorial010_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="18"
-{!> ../../../docs_src/query_params_str_validations/tutorial010.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial010.py!}
```
////
@@ -1116,7 +1116,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_an_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_an_py310.py!}
```
////
@@ -1124,7 +1124,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.9+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_an_py39.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_an_py39.py!}
```
////
@@ -1132,35 +1132,35 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_an.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="8"
-{!> ../../../docs_src/query_params_str_validations/tutorial014_py310.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014_py310.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать версию с `Annotated` если возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/query_params_str_validations/tutorial014.py!}
+{!> ../../docs_src/query_params_str_validations/tutorial014.py!}
```
////
diff --git a/docs/ru/docs/tutorial/query-params.md b/docs/ru/docs/tutorial/query-params.md
index 061f9be04..2c697224c 100644
--- a/docs/ru/docs/tutorial/query-params.md
+++ b/docs/ru/docs/tutorial/query-params.md
@@ -3,7 +3,7 @@
Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
+{!../../docs_src/query_params/tutorial001.py!}
```
Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`.
@@ -66,7 +66,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial002_py310.py!}
+{!> ../../docs_src/query_params/tutorial002_py310.py!}
```
////
@@ -74,14 +74,14 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial002.py!}
+{!> ../../docs_src/query_params/tutorial002.py!}
```
////
В этом случае, параметр `q` будет не обязательным и будет иметь значение `None` по умолчанию.
-/// check | "Важно"
+/// check | Важно
Также обратите внимание, что **FastAPI** достаточно умён чтобы заметить, что параметр `item_id` является path-параметром, а `q` нет, поэтому, это параметр запроса.
@@ -94,7 +94,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial003_py310.py!}
+{!> ../../docs_src/query_params/tutorial003_py310.py!}
```
////
@@ -102,7 +102,7 @@ http://127.0.0.1:8000/items/?skip=20
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial003.py!}
+{!> ../../docs_src/query_params/tutorial003.py!}
```
////
@@ -151,7 +151,7 @@ http://127.0.0.1:8000/items/foo?short=yes
//// tab | Python 3.10+
```Python hl_lines="6 8"
-{!> ../../../docs_src/query_params/tutorial004_py310.py!}
+{!> ../../docs_src/query_params/tutorial004_py310.py!}
```
////
@@ -159,7 +159,7 @@ http://127.0.0.1:8000/items/foo?short=yes
//// tab | Python 3.8+
```Python hl_lines="8 10"
-{!> ../../../docs_src/query_params/tutorial004.py!}
+{!> ../../docs_src/query_params/tutorial004.py!}
```
////
@@ -173,7 +173,7 @@ http://127.0.0.1:8000/items/foo?short=yes
Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
+{!../../docs_src/query_params/tutorial005.py!}
```
Здесь параметр запроса `needy` является обязательным параметром с типом данных `str`.
@@ -221,7 +221,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params/tutorial006_py310.py!}
+{!> ../../docs_src/query_params/tutorial006_py310.py!}
```
////
@@ -229,7 +229,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params/tutorial006.py!}
+{!> ../../docs_src/query_params/tutorial006.py!}
```
////
@@ -240,7 +240,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
* `skip`, типа `int` и со значением по умолчанию `0`.
* `limit`, необязательный `int`.
-/// tip | "Подсказка"
+/// tip | Подсказка
Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#_7){.internal-link target=_blank}.
diff --git a/docs/ru/docs/tutorial/request-files.md b/docs/ru/docs/tutorial/request-files.md
index 1fbc4acc0..836d6efed 100644
--- a/docs/ru/docs/tutorial/request-files.md
+++ b/docs/ru/docs/tutorial/request-files.md
@@ -2,7 +2,7 @@
Используя класс `File`, мы можем позволить клиентам загружать файлы.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Чтобы получать загруженные файлы, сначала установите `python-multipart`.
@@ -19,7 +19,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/request_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
```
////
@@ -27,21 +27,21 @@
//// tab | Python 3.6+
```Python hl_lines="1"
-{!> ../../../docs_src/request_files/tutorial001_an.py!}
+{!> ../../docs_src/request_files/tutorial001_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_files/tutorial001.py!}
+{!> ../../docs_src/request_files/tutorial001.py!}
```
////
@@ -53,7 +53,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/request_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
```
////
@@ -61,26 +61,26 @@
//// tab | Python 3.6+
```Python hl_lines="8"
-{!> ../../../docs_src/request_files/tutorial001_an.py!}
+{!> ../../docs_src/request_files/tutorial001_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/request_files/tutorial001.py!}
+{!> ../../docs_src/request_files/tutorial001.py!}
```
////
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
`File` - это класс, который наследуется непосредственно от `Form`.
@@ -88,7 +88,7 @@
///
-/// tip | "Подсказка"
+/// tip | Подсказка
Для объявления тела файла необходимо использовать `File`, поскольку в противном случае параметры будут интерпретироваться как параметры запроса или параметры тела (JSON).
@@ -109,7 +109,7 @@
//// tab | Python 3.9+
```Python hl_lines="14"
-{!> ../../../docs_src/request_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
```
////
@@ -117,21 +117,21 @@
//// tab | Python 3.6+
```Python hl_lines="13"
-{!> ../../../docs_src/request_files/tutorial001_an.py!}
+{!> ../../docs_src/request_files/tutorial001_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="12"
-{!> ../../../docs_src/request_files/tutorial001.py!}
+{!> ../../docs_src/request_files/tutorial001.py!}
```
////
@@ -177,13 +177,13 @@ contents = await myfile.read()
contents = myfile.file.read()
```
-/// note | "Технические детали `async`"
+/// note | Технические детали `async`
При использовании методов `async` **FastAPI** запускает файловые методы в пуле потоков и ожидает их.
///
-/// note | "Технические детали Starlette"
+/// note | Технические детали Starlette
**FastAPI** наследует `UploadFile` непосредственно из **Starlette**, но добавляет некоторые детали для совместимости с **Pydantic** и другими частями FastAPI.
@@ -195,7 +195,7 @@ contents = myfile.file.read()
**FastAPI** позаботится о том, чтобы считать эти данные из нужного места, а не из JSON.
-/// note | "Технические детали"
+/// note | Технические детали
Данные из форм обычно кодируются с использованием "media type" `application/x-www-form-urlencoded` когда он не включает файлы.
@@ -205,7 +205,7 @@ contents = myfile.file.read()
///
-/// warning | "Внимание"
+/// warning | Внимание
В операции *функции операции пути* можно объявить несколько параметров `File` и `Form`, но нельзя также объявлять поля `Body`, которые предполагается получить в виде JSON, поскольку тело запроса будет закодировано с помощью `multipart/form-data`, а не `application/json`.
@@ -220,7 +220,7 @@ contents = myfile.file.read()
//// tab | Python 3.10+
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02_an_py310.py!}
+{!> ../../docs_src/request_files/tutorial001_02_an_py310.py!}
```
////
@@ -228,7 +228,7 @@ contents = myfile.file.read()
//// tab | Python 3.9+
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_02_an_py39.py!}
```
////
@@ -236,35 +236,35 @@ contents = myfile.file.read()
//// tab | Python 3.6+
```Python hl_lines="10 18"
-{!> ../../../docs_src/request_files/tutorial001_02_an.py!}
+{!> ../../docs_src/request_files/tutorial001_02_an.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="7 15"
-{!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
+{!> ../../docs_src/request_files/tutorial001_02_py310.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="9 17"
-{!> ../../../docs_src/request_files/tutorial001_02.py!}
+{!> ../../docs_src/request_files/tutorial001_02.py!}
```
////
@@ -276,7 +276,7 @@ contents = myfile.file.read()
//// tab | Python 3.9+
```Python hl_lines="9 15"
-{!> ../../../docs_src/request_files/tutorial001_03_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial001_03_an_py39.py!}
```
////
@@ -284,21 +284,21 @@ contents = myfile.file.read()
//// tab | Python 3.6+
```Python hl_lines="8 14"
-{!> ../../../docs_src/request_files/tutorial001_03_an.py!}
+{!> ../../docs_src/request_files/tutorial001_03_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="7 13"
-{!> ../../../docs_src/request_files/tutorial001_03.py!}
+{!> ../../docs_src/request_files/tutorial001_03.py!}
```
////
@@ -314,7 +314,7 @@ contents = myfile.file.read()
//// tab | Python 3.9+
```Python hl_lines="10 15"
-{!> ../../../docs_src/request_files/tutorial002_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial002_an_py39.py!}
```
////
@@ -322,42 +322,42 @@ contents = myfile.file.read()
//// tab | Python 3.6+
```Python hl_lines="11 16"
-{!> ../../../docs_src/request_files/tutorial002_an.py!}
+{!> ../../docs_src/request_files/tutorial002_an.py!}
```
////
//// tab | Python 3.9+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="8 13"
-{!> ../../../docs_src/request_files/tutorial002_py39.py!}
+{!> ../../docs_src/request_files/tutorial002_py39.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="10 15"
-{!> ../../../docs_src/request_files/tutorial002.py!}
+{!> ../../docs_src/request_files/tutorial002.py!}
```
////
Вы получите, как и было объявлено, список `list` из `bytes` или `UploadFile`.
-/// note | "Technical Details"
+/// note | Technical Details
Можно также использовать `from starlette.responses import HTMLResponse`.
@@ -372,7 +372,7 @@ contents = myfile.file.read()
//// tab | Python 3.9+
```Python hl_lines="11 18-20"
-{!> ../../../docs_src/request_files/tutorial003_an_py39.py!}
+{!> ../../docs_src/request_files/tutorial003_an_py39.py!}
```
////
@@ -380,35 +380,35 @@ contents = myfile.file.read()
//// tab | Python 3.6+
```Python hl_lines="12 19-21"
-{!> ../../../docs_src/request_files/tutorial003_an.py!}
+{!> ../../docs_src/request_files/tutorial003_an.py!}
```
////
//// tab | Python 3.9+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="9 16"
-{!> ../../../docs_src/request_files/tutorial003_py39.py!}
+{!> ../../docs_src/request_files/tutorial003_py39.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="11 18"
-{!> ../../../docs_src/request_files/tutorial003.py!}
+{!> ../../docs_src/request_files/tutorial003.py!}
```
////
diff --git a/docs/ru/docs/tutorial/request-forms-and-files.md b/docs/ru/docs/tutorial/request-forms-and-files.md
index b38962866..fd98ec953 100644
--- a/docs/ru/docs/tutorial/request-forms-and-files.md
+++ b/docs/ru/docs/tutorial/request-forms-and-files.md
@@ -2,7 +2,7 @@
Вы можете определять файлы и поля формы одновременно, используя `File` и `Form`.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Чтобы получать загруженные файлы и/или данные форм, сначала установите `python-multipart`.
@@ -15,7 +15,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
```
////
@@ -23,21 +23,21 @@
//// tab | Python 3.6+
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001.py!}
```
////
@@ -49,7 +49,7 @@
//// tab | Python 3.9+
```Python hl_lines="10-12"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
```
////
@@ -57,21 +57,21 @@
//// tab | Python 3.6+
```Python hl_lines="9-11"
-{!> ../../../docs_src/request_forms_and_files/tutorial001_an.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001_an.py!}
```
////
//// tab | Python 3.6+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="8"
-{!> ../../../docs_src/request_forms_and_files/tutorial001.py!}
+{!> ../../docs_src/request_forms_and_files/tutorial001.py!}
```
////
@@ -80,7 +80,7 @@
Вы можете объявить некоторые файлы как `bytes`, а некоторые - как `UploadFile`.
-/// warning | "Внимание"
+/// warning | Внимание
Вы можете объявить несколько параметров `File` и `Form` в операции *path*, но вы не можете также объявить поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с помощью `multipart/form-data` вместо `application/json`.
diff --git a/docs/ru/docs/tutorial/request-forms.md b/docs/ru/docs/tutorial/request-forms.md
index 3737f1347..cd17613de 100644
--- a/docs/ru/docs/tutorial/request-forms.md
+++ b/docs/ru/docs/tutorial/request-forms.md
@@ -2,7 +2,7 @@
Когда вам нужно получить поля формы вместо JSON, вы можете использовать `Form`.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Чтобы использовать формы, сначала установите `python-multipart`.
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
```
////
@@ -25,21 +25,21 @@
//// tab | Python 3.8+
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms/tutorial001_an.py!}
+{!> ../../docs_src/request_forms/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать 'Annotated' версию, если это возможно.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms/tutorial001.py!}
+{!> ../../docs_src/request_forms/tutorial001.py!}
```
////
@@ -51,7 +51,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
```
////
@@ -59,21 +59,21 @@
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/request_forms/tutorial001_an.py!}
+{!> ../../docs_src/request_forms/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Рекомендуется использовать 'Annotated' версию, если это возможно.
///
```Python hl_lines="7"
-{!> ../../../docs_src/request_forms/tutorial001.py!}
+{!> ../../docs_src/request_forms/tutorial001.py!}
```
////
@@ -84,13 +84,13 @@
Вы можете настроить `Form` точно так же, как настраиваете и `Body` ( `Query`, `Path`, `Cookie`), включая валидации, примеры, псевдонимы (например, `user-name` вместо `username`) и т.д.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
`Form` - это класс, который наследуется непосредственно от `Body`.
///
-/// tip | "Подсказка"
+/// tip | Подсказка
Вам необходимо явно указывать параметр `Form` при объявлении каждого поля, иначе поля будут интерпретироваться как параметры запроса или параметры тела (JSON).
@@ -102,7 +102,7 @@
**FastAPI** гарантирует правильное чтение этих данных из соответствующего места, а не из JSON.
-/// note | "Технические детали"
+/// note | Технические детали
Данные из форм обычно кодируются с использованием "типа медиа" `application/x-www-form-urlencoded`.
@@ -112,7 +112,7 @@
///
-/// warning | "Предупреждение"
+/// warning | Предупреждение
Вы можете объявлять несколько параметров `Form` в *операции пути*, но вы не можете одновременно с этим объявлять поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с использованием `application/x-www-form-urlencoded`, а не `application/json`.
diff --git a/docs/ru/docs/tutorial/response-model.md b/docs/ru/docs/tutorial/response-model.md
index f8c910fe9..c55be38ef 100644
--- a/docs/ru/docs/tutorial/response-model.md
+++ b/docs/ru/docs/tutorial/response-model.md
@@ -7,7 +7,7 @@ FastAPI позволяет использовать **аннотации тип
//// tab | Python 3.10+
```Python hl_lines="16 21"
-{!> ../../../docs_src/response_model/tutorial001_01_py310.py!}
+{!> ../../docs_src/response_model/tutorial001_01_py310.py!}
```
////
@@ -15,7 +15,7 @@ FastAPI позволяет использовать **аннотации тип
//// tab | Python 3.9+
```Python hl_lines="18 23"
-{!> ../../../docs_src/response_model/tutorial001_01_py39.py!}
+{!> ../../docs_src/response_model/tutorial001_01_py39.py!}
```
////
@@ -23,7 +23,7 @@ FastAPI позволяет использовать **аннотации тип
//// tab | Python 3.8+
```Python hl_lines="18 23"
-{!> ../../../docs_src/response_model/tutorial001_01.py!}
+{!> ../../docs_src/response_model/tutorial001_01.py!}
```
////
@@ -62,7 +62,7 @@ FastAPI будет использовать этот возвращаемый т
//// tab | Python 3.10+
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001_py310.py!}
+{!> ../../docs_src/response_model/tutorial001_py310.py!}
```
////
@@ -70,7 +70,7 @@ FastAPI будет использовать этот возвращаемый т
//// tab | Python 3.9+
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001_py39.py!}
+{!> ../../docs_src/response_model/tutorial001_py39.py!}
```
////
@@ -78,12 +78,12 @@ FastAPI будет использовать этот возвращаемый т
//// tab | Python 3.8+
```Python hl_lines="17 22 24-27"
-{!> ../../../docs_src/response_model/tutorial001.py!}
+{!> ../../docs_src/response_model/tutorial001.py!}
```
////
-/// note | "Технические детали"
+/// note | Технические детали
Помните, что параметр `response_model` является параметром именно декоратора http-методов (`get`, `post`, и т.п.). Не следует его указывать для *функций операций пути*, как вы бы поступили с другими параметрами или с телом запроса.
@@ -93,7 +93,7 @@ FastAPI будет использовать этот возвращаемый т
FastAPI будет использовать значение `response_model` для того, чтобы автоматически генерировать документацию, производить валидацию и т.п. А также для **конвертации и фильтрации выходных данных** в объявленный тип.
-/// tip | "Подсказка"
+/// tip | Подсказка
Если вы используете анализаторы типов со строгой проверкой (например, mypy), можно указать `Any` в качестве типа возвращаемого значения функции.
@@ -116,7 +116,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.10+
```Python hl_lines="7 9"
-{!> ../../../docs_src/response_model/tutorial002_py310.py!}
+{!> ../../docs_src/response_model/tutorial002_py310.py!}
```
////
@@ -124,12 +124,12 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.8+
```Python hl_lines="9 11"
-{!> ../../../docs_src/response_model/tutorial002.py!}
+{!> ../../docs_src/response_model/tutorial002.py!}
```
////
-/// info | "Информация"
+/// info | Информация
Чтобы использовать `EmailStr`, прежде необходимо установить `email-validator`.
Используйте `pip install email-validator`
@@ -142,7 +142,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.10+
```Python hl_lines="16"
-{!> ../../../docs_src/response_model/tutorial002_py310.py!}
+{!> ../../docs_src/response_model/tutorial002_py310.py!}
```
////
@@ -150,7 +150,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/response_model/tutorial002.py!}
+{!> ../../docs_src/response_model/tutorial002.py!}
```
////
@@ -161,7 +161,7 @@ FastAPI будет использовать значение `response_model` д
Но что если мы захотим использовать эту модель для какой-либо другой *операции пути*? Мы можем, сами того не желая, отправить пароль любому другому пользователю.
-/// danger | "Осторожно"
+/// danger | Осторожно
Никогда не храните пароли пользователей в открытом виде, а также никогда не возвращайте их в ответе, как в примере выше. В противном случае - убедитесь, что вы хорошо продумали и учли все возможные риски такого подхода и вам известно, что вы делаете.
@@ -174,7 +174,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.10+
```Python hl_lines="9 11 16"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -182,7 +182,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.8+
```Python hl_lines="9 11 16"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -192,7 +192,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.10+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -200,7 +200,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.8+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -210,7 +210,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.10+
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial003_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_py310.py!}
```
////
@@ -218,7 +218,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.8+
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial003.py!}
+{!> ../../docs_src/response_model/tutorial003.py!}
```
////
@@ -248,7 +248,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.10+
```Python hl_lines="7-10 13-14 18"
-{!> ../../../docs_src/response_model/tutorial003_01_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_01_py310.py!}
```
////
@@ -256,7 +256,7 @@ FastAPI будет использовать значение `response_model` д
//// tab | Python 3.8+
```Python hl_lines="9-13 15-16 20"
-{!> ../../../docs_src/response_model/tutorial003_01.py!}
+{!> ../../docs_src/response_model/tutorial003_01.py!}
```
////
@@ -302,7 +302,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
Самый частый сценарий использования - это [возвращать Response напрямую, как описано в расширенной документации](../advanced/response-directly.md){.internal-link target=_blank}.
```Python hl_lines="8 10-11"
-{!> ../../../docs_src/response_model/tutorial003_02.py!}
+{!> ../../docs_src/response_model/tutorial003_02.py!}
```
Это поддерживается FastAPI по-умолчанию, т.к. аннотация проставлена в классе (или подклассе) `Response`.
@@ -314,7 +314,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
Вы также можете указать подкласс `Response` в аннотации типа:
```Python hl_lines="8-9"
-{!> ../../../docs_src/response_model/tutorial003_03.py!}
+{!> ../../docs_src/response_model/tutorial003_03.py!}
```
Это сработает, потому что `RedirectResponse` является подклассом `Response` и FastAPI автоматически обработает этот простейший случай.
@@ -328,7 +328,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/response_model/tutorial003_04_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_04_py310.py!}
```
////
@@ -336,7 +336,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/response_model/tutorial003_04.py!}
+{!> ../../docs_src/response_model/tutorial003_04.py!}
```
////
@@ -354,7 +354,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/response_model/tutorial003_05_py310.py!}
+{!> ../../docs_src/response_model/tutorial003_05_py310.py!}
```
////
@@ -362,7 +362,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/response_model/tutorial003_05.py!}
+{!> ../../docs_src/response_model/tutorial003_05.py!}
```
////
@@ -376,7 +376,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.10+
```Python hl_lines="9 11-12"
-{!> ../../../docs_src/response_model/tutorial004_py310.py!}
+{!> ../../docs_src/response_model/tutorial004_py310.py!}
```
////
@@ -384,7 +384,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.9+
```Python hl_lines="11 13-14"
-{!> ../../../docs_src/response_model/tutorial004_py39.py!}
+{!> ../../docs_src/response_model/tutorial004_py39.py!}
```
////
@@ -392,7 +392,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.8+
```Python hl_lines="11 13-14"
-{!> ../../../docs_src/response_model/tutorial004.py!}
+{!> ../../docs_src/response_model/tutorial004.py!}
```
////
@@ -412,7 +412,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.10+
```Python hl_lines="22"
-{!> ../../../docs_src/response_model/tutorial004_py310.py!}
+{!> ../../docs_src/response_model/tutorial004_py310.py!}
```
////
@@ -420,7 +420,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.9+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial004_py39.py!}
+{!> ../../docs_src/response_model/tutorial004_py39.py!}
```
////
@@ -428,7 +428,7 @@ FastAPI совместно с Pydantic выполнит некоторую ма
//// tab | Python 3.8+
```Python hl_lines="24"
-{!> ../../../docs_src/response_model/tutorial004.py!}
+{!> ../../docs_src/response_model/tutorial004.py!}
```
////
@@ -444,13 +444,13 @@ FastAPI совместно с Pydantic выполнит некоторую ма
}
```
-/// info | "Информация"
+/// info | Информация
"Под капотом" FastAPI использует метод `.dict()` у объектов моделей Pydantic с параметром `exclude_unset`, чтобы достичь такого эффекта.
///
-/// info | "Информация"
+/// info | Информация
Вы также можете использовать:
@@ -494,7 +494,7 @@ FastAPI достаточно умен (на самом деле, это засл
И поэтому, они также будут включены в JSON ответа.
-/// tip | "Подсказка"
+/// tip | Подсказка
Значением по умолчанию может быть что угодно, не только `None`.
@@ -510,7 +510,7 @@ FastAPI достаточно умен (на самом деле, это засл
Это можно использовать как быстрый способ исключить данные из ответа, не создавая отдельную модель Pydantic.
-/// tip | "Подсказка"
+/// tip | Подсказка
Но по-прежнему рекомендуется следовать изложенным выше советам и использовать несколько моделей вместо данных параметров.
@@ -523,7 +523,7 @@ FastAPI достаточно умен (на самом деле, это засл
//// tab | Python 3.10+
```Python hl_lines="29 35"
-{!> ../../../docs_src/response_model/tutorial005_py310.py!}
+{!> ../../docs_src/response_model/tutorial005_py310.py!}
```
////
@@ -531,12 +531,12 @@ FastAPI достаточно умен (на самом деле, это засл
//// tab | Python 3.8+
```Python hl_lines="31 37"
-{!> ../../../docs_src/response_model/tutorial005.py!}
+{!> ../../docs_src/response_model/tutorial005.py!}
```
////
-/// tip | "Подсказка"
+/// tip | Подсказка
При помощи кода `{"name","description"}` создается объект множества (`set`) с двумя строковыми значениями.
@@ -551,7 +551,7 @@ FastAPI достаточно умен (на самом деле, это засл
//// tab | Python 3.10+
```Python hl_lines="29 35"
-{!> ../../../docs_src/response_model/tutorial006_py310.py!}
+{!> ../../docs_src/response_model/tutorial006_py310.py!}
```
////
@@ -559,7 +559,7 @@ FastAPI достаточно умен (на самом деле, это засл
//// tab | Python 3.8+
```Python hl_lines="31 37"
-{!> ../../../docs_src/response_model/tutorial006.py!}
+{!> ../../docs_src/response_model/tutorial006.py!}
```
////
diff --git a/docs/ru/docs/tutorial/response-status-code.md b/docs/ru/docs/tutorial/response-status-code.md
index a36c42d05..f08b15379 100644
--- a/docs/ru/docs/tutorial/response-status-code.md
+++ b/docs/ru/docs/tutorial/response-status-code.md
@@ -9,10 +9,10 @@
* и других.
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
-/// note | "Примечание"
+/// note | Примечание
Обратите внимание, что `status_code` является атрибутом метода-декоратора (`get`, `post` и т.д.), а не *функции-обработчика пути* в отличие от всех остальных параметров и тела запроса.
@@ -20,7 +20,7 @@
Параметр `status_code` принимает число, обозначающее HTTP код статуса ответа.
-/// info | "Информация"
+/// info | Информация
В качестве значения параметра `status_code` также может использоваться `IntEnum`, например, из библиотеки `http.HTTPStatus` в Python.
@@ -33,7 +33,7 @@
-/// note | "Примечание"
+/// note | Примечание
Некоторые коды статуса ответа (см. следующий раздел) указывают на то, что ответ не имеет тела.
@@ -43,7 +43,7 @@ FastAPI знает об этом и создаст документацию Open
## Об HTTP кодах статуса ответа
-/// note | "Примечание"
+/// note | Примечание
Если вы уже знаете, что представляют собой HTTP коды статуса ответа, можете перейти к следующему разделу.
@@ -66,7 +66,7 @@ FastAPI знает об этом и создаст документацию Open
* Для общих ошибок со стороны клиента можно просто использовать код `400`.
* `5XX` – статус-коды, сообщающие о серверной ошибке. Они почти никогда не используются разработчиками напрямую. Когда что-то идет не так в какой-то части кода вашего приложения или на сервере, он автоматически вернёт один из 5XX кодов.
-/// tip | "Подсказка"
+/// tip | Подсказка
Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с документацией MDN об HTTP кодах статуса ответа.
@@ -77,7 +77,7 @@ FastAPI знает об этом и создаст документацию Open
Рассмотрим предыдущий пример еще раз:
```Python hl_lines="6"
-{!../../../docs_src/response_status_code/tutorial001.py!}
+{!../../docs_src/response_status_code/tutorial001.py!}
```
`201` – это код статуса "Создано".
@@ -87,14 +87,14 @@ FastAPI знает об этом и создаст документацию Open
Для удобства вы можете использовать переменные из `fastapi.status`.
```Python hl_lines="1 6"
-{!../../../docs_src/response_status_code/tutorial002.py!}
+{!../../docs_src/response_status_code/tutorial002.py!}
```
Они содержат те же числовые значения, но позволяют использовать подсказки редактора для выбора кода статуса:
-/// note | "Технические детали"
+/// note | Технические детали
Вы также можете использовать `from starlette import status` вместо `from fastapi import status`.
diff --git a/docs/ru/docs/tutorial/schema-extra-example.md b/docs/ru/docs/tutorial/schema-extra-example.md
index 1b216de3a..daa264afc 100644
--- a/docs/ru/docs/tutorial/schema-extra-example.md
+++ b/docs/ru/docs/tutorial/schema-extra-example.md
@@ -11,7 +11,7 @@
//// tab | Python 3.10+
```Python hl_lines="13-21"
-{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial001_py310.py!}
```
////
@@ -19,7 +19,7 @@
//// tab | Python 3.8+
```Python hl_lines="15-23"
-{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
+{!> ../../docs_src/schema_extra_example/tutorial001.py!}
```
////
@@ -43,7 +43,7 @@
//// tab | Python 3.10+
```Python hl_lines="2 8-11"
-{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial002_py310.py!}
```
////
@@ -51,7 +51,7 @@
//// tab | Python 3.8+
```Python hl_lines="4 10-13"
-{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
+{!> ../../docs_src/schema_extra_example/tutorial002.py!}
```
////
@@ -83,7 +83,7 @@
//// tab | Python 3.10+
```Python hl_lines="22-27"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
```
////
@@ -91,7 +91,7 @@
//// tab | Python 3.9+
```Python hl_lines="22-27"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
```
////
@@ -99,7 +99,7 @@
//// tab | Python 3.8+
```Python hl_lines="23-28"
-{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003_an.py!}
```
////
@@ -113,7 +113,7 @@
///
```Python hl_lines="18-23"
-{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003_py310.py!}
```
////
@@ -127,7 +127,7 @@
///
```Python hl_lines="20-25"
-{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
+{!> ../../docs_src/schema_extra_example/tutorial003.py!}
```
////
@@ -154,7 +154,7 @@
//// tab | Python 3.10+
```Python hl_lines="23-49"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
```
////
@@ -162,7 +162,7 @@
//// tab | Python 3.9+
```Python hl_lines="23-49"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
```
////
@@ -170,7 +170,7 @@
//// tab | Python 3.8+
```Python hl_lines="24-50"
-{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004_an.py!}
```
////
@@ -184,7 +184,7 @@
///
```Python hl_lines="19-45"
-{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004_py310.py!}
```
////
@@ -198,7 +198,7 @@
///
```Python hl_lines="21-47"
-{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
+{!> ../../docs_src/schema_extra_example/tutorial004.py!}
```
////
diff --git a/docs/ru/docs/tutorial/security/first-steps.md b/docs/ru/docs/tutorial/security/first-steps.md
index 444a06915..484dfceff 100644
--- a/docs/ru/docs/tutorial/security/first-steps.md
+++ b/docs/ru/docs/tutorial/security/first-steps.md
@@ -23,7 +23,7 @@
//// tab | Python 3.9+
```Python
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -31,28 +31,28 @@
//// tab | Python 3.8+
```Python
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
## Запуск
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Вначале, установите библиотеку `python-multipart`.
@@ -82,7 +82,7 @@ $ uvicorn main:app --reload
-/// check | "Кнопка авторизации!"
+/// check | Кнопка авторизации!
У вас уже появилась новая кнопка "Authorize".
@@ -94,7 +94,7 @@ $ uvicorn main:app --reload
-/// note | "Технические детали"
+/// note | Технические детали
Неважно, что вы введете в форму, она пока не будет работать. Но мы к этому еще придем.
@@ -140,7 +140,7 @@ OAuth2 был разработан для того, чтобы бэкэнд ил
В данном примере мы будем использовать **OAuth2**, с аутентификацией по паролю, используя токен **Bearer**. Для этого мы используем класс `OAuth2PasswordBearer`.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Токен "bearer" - не единственный вариант, но для нашего случая он является наилучшим.
@@ -155,7 +155,7 @@ OAuth2 был разработан для того, чтобы бэкэнд ил
//// tab | Python 3.9+
```Python hl_lines="8"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -163,26 +163,26 @@ OAuth2 был разработан для того, чтобы бэкэнд ил
//// tab | Python 3.8+
```Python hl_lines="7"
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="6"
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
-/// tip | "Подсказка"
+/// tip | Подсказка
Здесь `tokenUrl="token"` ссылается на относительный URL `token`, который мы еще не создали. Поскольку это относительный URL, он эквивалентен `./token`.
@@ -196,7 +196,7 @@ OAuth2 был разработан для того, чтобы бэкэнд ил
Вскоре мы создадим и саму операцию пути.
-/// info | "Дополнительная информация"
+/// info | Дополнительная информация
Если вы очень строгий "питонист", то вам может не понравиться стиль названия параметра `tokenUrl` вместо `token_url`.
@@ -221,7 +221,7 @@ oauth2_scheme(some, parameters)
//// tab | Python 3.9+
```Python hl_lines="12"
-{!> ../../../docs_src/security/tutorial001_an_py39.py!}
+{!> ../../docs_src/security/tutorial001_an_py39.py!}
```
////
@@ -229,21 +229,21 @@ oauth2_scheme(some, parameters)
//// tab | Python 3.8+
```Python hl_lines="11"
-{!> ../../../docs_src/security/tutorial001_an.py!}
+{!> ../../docs_src/security/tutorial001_an.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
Предпочтительнее использовать версию с аннотацией, если это возможно.
///
```Python hl_lines="10"
-{!> ../../../docs_src/security/tutorial001.py!}
+{!> ../../docs_src/security/tutorial001.py!}
```
////
@@ -252,7 +252,7 @@ oauth2_scheme(some, parameters)
**FastAPI** будет знать, что он может использовать эту зависимость для определения "схемы безопасности" в схеме OpenAPI (и автоматической документации по API).
-/// info | "Технические детали"
+/// info | Технические детали
**FastAPI** будет знать, что он может использовать класс `OAuth2PasswordBearer` (объявленный в зависимости) для определения схемы безопасности в OpenAPI, поскольку он наследуется от `fastapi.security.oauth2.OAuth2`, который, в свою очередь, наследуется от `fastapi.security.base.SecurityBase`.
diff --git a/docs/ru/docs/tutorial/security/index.md b/docs/ru/docs/tutorial/security/index.md
index bd512fde3..e4969c4cf 100644
--- a/docs/ru/docs/tutorial/security/index.md
+++ b/docs/ru/docs/tutorial/security/index.md
@@ -32,7 +32,7 @@ OAuth2 включает в себя способы аутентификации
OAuth2 не указывает, как шифровать сообщение, он ожидает, что ваше приложение будет обслуживаться по протоколу HTTPS.
-/// tip | "Подсказка"
+/// tip | Подсказка
В разделе **Развертывание** вы увидите [как настроить протокол HTTPS бесплатно, используя Traefik и Let's Encrypt.](https://fastapi.tiangolo.com/ru/deployment/https/)
@@ -89,7 +89,7 @@ OpenAPI может использовать следующие схемы авт
* Это автоматическое обнаружение определено в спецификации OpenID Connect.
-/// tip | "Подсказка"
+/// tip | Подсказка
Интеграция сторонних сервисов для аутентификации/авторизации таких как Google, Facebook, Twitter, GitHub и т.д. осуществляется достаточно легко.
diff --git a/docs/ru/docs/tutorial/static-files.md b/docs/ru/docs/tutorial/static-files.md
index ccddae249..0287fb017 100644
--- a/docs/ru/docs/tutorial/static-files.md
+++ b/docs/ru/docs/tutorial/static-files.md
@@ -8,10 +8,10 @@
* "Примонтируйте" экземпляр `StaticFiles()` с указанием определенной директории.
```Python hl_lines="2 6"
-{!../../../docs_src/static_files/tutorial001.py!}
+{!../../docs_src/static_files/tutorial001.py!}
```
-/// note | "Технические детали"
+/// note | Технические детали
Вы также можете использовать `from starlette.staticfiles import StaticFiles`.
diff --git a/docs/ru/docs/tutorial/testing.md b/docs/ru/docs/tutorial/testing.md
index efefbfb01..0485ef801 100644
--- a/docs/ru/docs/tutorial/testing.md
+++ b/docs/ru/docs/tutorial/testing.md
@@ -8,7 +8,7 @@
## Использование класса `TestClient`
-/// info | "Информация"
+/// info | Информация
Для использования класса `TestClient` необходимо установить библиотеку `httpx`.
@@ -27,10 +27,10 @@
Напишите простое утверждение с `assert` дабы проверить истинность Python-выражения (это тоже стандарт `pytest`).
```Python hl_lines="2 12 15-18"
-{!../../../docs_src/app_testing/tutorial001.py!}
+{!../../docs_src/app_testing/tutorial001.py!}
```
-/// tip | "Подсказка"
+/// tip | Подсказка
Обратите внимание, что тестирующая функция является обычной `def`, а не асинхронной `async def`.
@@ -40,7 +40,7 @@
///
-/// note | "Технические детали"
+/// note | Технические детали
Также можно написать `from starlette.testclient import TestClient`.
@@ -48,7 +48,7 @@
///
-/// tip | "Подсказка"
+/// tip | Подсказка
Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md){.internal-link target=_blank} в расширенном руководстве.
@@ -75,7 +75,7 @@
```Python
-{!../../../docs_src/app_testing/main.py!}
+{!../../docs_src/app_testing/main.py!}
```
### Файл тестов
@@ -93,7 +93,7 @@
Так как оба файла находятся в одной директории, для импорта объекта приложения из файла `main` в файл `test_main` Вы можете использовать относительный импорт:
```Python hl_lines="3"
-{!../../../docs_src/app_testing/test_main.py!}
+{!../../docs_src/app_testing/test_main.py!}
```
...и писать дальше тесты, как и раньше.
@@ -125,7 +125,7 @@
//// tab | Python 3.10+
```Python
-{!> ../../../docs_src/app_testing/app_b_an_py310/main.py!}
+{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
```
////
@@ -133,7 +133,7 @@
//// tab | Python 3.9+
```Python
-{!> ../../../docs_src/app_testing/app_b_an_py39/main.py!}
+{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
```
////
@@ -141,35 +141,35 @@
//// tab | Python 3.8+
```Python
-{!> ../../../docs_src/app_testing/app_b_an/main.py!}
+{!> ../../docs_src/app_testing/app_b_an/main.py!}
```
////
//// tab | Python 3.10+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
По возможности используйте версию с `Annotated`.
///
```Python
-{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
+{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
//// tab | Python 3.8+ без Annotated
-/// tip | "Подсказка"
+/// tip | Подсказка
По возможности используйте версию с `Annotated`.
///
```Python
-{!> ../../../docs_src/app_testing/app_b/main.py!}
+{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
@@ -179,7 +179,7 @@
Теперь обновим файл `test_main.py`, добавив в него тестов:
```Python
-{!> ../../../docs_src/app_testing/app_b/test_main.py!}
+{!> ../../docs_src/app_testing/app_b/test_main.py!}
```
Если Вы не знаете, как передать информацию в запросе, можете воспользоваться поисковиком (погуглить) и задать вопрос: "Как передать информацию в запросе с помощью `httpx`", можно даже спросить: "Как передать информацию в запросе с помощью `requests`", поскольку дизайн HTTPX основан на дизайне Requests.
@@ -196,7 +196,7 @@
Для получения дополнительной информации о передаче данных на бэкенд с помощью `httpx` или `TestClient` ознакомьтесь с документацией HTTPX.
-/// info | "Информация"
+/// info | Информация
Обратите внимание, что `TestClient` принимает данные, которые можно конвертировать в JSON, но не модели Pydantic.
diff --git a/docs/tr/docs/advanced/index.md b/docs/tr/docs/advanced/index.md
index 6c057162e..836e63c8a 100644
--- a/docs/tr/docs/advanced/index.md
+++ b/docs/tr/docs/advanced/index.md
@@ -6,7 +6,7 @@
İlerleyen bölümlerde diğer seçenekler, konfigürasyonlar ve ek özellikleri göreceğiz.
-/// tip | "İpucu"
+/// tip | İpucu
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
diff --git a/docs/tr/docs/advanced/security/index.md b/docs/tr/docs/advanced/security/index.md
index 227674bd4..709f74c72 100644
--- a/docs/tr/docs/advanced/security/index.md
+++ b/docs/tr/docs/advanced/security/index.md
@@ -4,7 +4,7 @@
[Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
-/// tip | "İpucu"
+/// tip | İpucu
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
diff --git a/docs/tr/docs/advanced/testing-websockets.md b/docs/tr/docs/advanced/testing-websockets.md
index 59a2499e2..12b6ab60f 100644
--- a/docs/tr/docs/advanced/testing-websockets.md
+++ b/docs/tr/docs/advanced/testing-websockets.md
@@ -5,10 +5,10 @@ WebSockets testi yapmak için `TestClient`'ı kullanabilirsiniz.
Bu işlem için, `TestClient`'ı bir `with` ifadesinde kullanarak WebSocket'e bağlanabilirsiniz:
```Python hl_lines="27-31"
-{!../../../docs_src/app_testing/tutorial002.py!}
+{!../../docs_src/app_testing/tutorial002.py!}
```
-/// note | "Not"
+/// note | Not
Daha fazla detay için Starlette'in Websockets'i Test Etmek dokümantasyonunu inceleyin.
diff --git a/docs/tr/docs/advanced/wsgi.md b/docs/tr/docs/advanced/wsgi.md
index 54a6f20e2..bc8da16df 100644
--- a/docs/tr/docs/advanced/wsgi.md
+++ b/docs/tr/docs/advanced/wsgi.md
@@ -13,7 +13,7 @@ Ardından WSGI (örneğin Flask) uygulamanızı middleware ile sarmalayın.
Son olarak da bir yol altında bağlama işlemini gerçekleştirin.
```Python hl_lines="2-3 23"
-{!../../../docs_src/wsgi/tutorial001.py!}
+{!../../docs_src/wsgi/tutorial001.py!}
```
## Kontrol Edelim
diff --git a/docs/tr/docs/alternatives.md b/docs/tr/docs/alternatives.md
index bd668ca45..c98b966b5 100644
--- a/docs/tr/docs/alternatives.md
+++ b/docs/tr/docs/alternatives.md
@@ -30,13 +30,13 @@ Django REST framework'ü, Django'nun API kabiliyetlerini arttırmak için arka p
**Otomatik API dökümantasyonu**nun ilk örneklerinden biri olduğu için, **FastAPI** arayışına ilham veren ilk fikirlerden biri oldu.
-/// note | "Not"
+/// note | Not
Django REST Framework'ü, aynı zamanda **FastAPI**'ın dayandığı Starlette ve Uvicorn'un da yaratıcısı olan Tom Christie tarafından geliştirildi.
///
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
Kullanıcılar için otomatik API dökümantasyonu sunan bir web arayüzüne sahip olmalı.
@@ -56,7 +56,7 @@ Uygulama parçalarının böyle ayrılıyor oluşu ve istenilen özelliklerle ge
Flask'ın basitliği göz önünde bulundurulduğu zaman, API geliştirmek için iyi bir seçim gibi görünüyordu. Sıradaki şey ise Flask için bir "Django REST Framework"!
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
Gereken araçları ve parçaları birleştirip eşleştirmeyi kolaylaştıracak bir mikro framework olmalı.
@@ -98,7 +98,7 @@ def read_url():
`requests.get(...)` ile `@app.get(...)` arasındaki benzerliklere bakın.
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
* Basit ve sezgisel bir API'ya sahip olmalı.
* HTTP metot isimlerini (işlemlerini) anlaşılır olacak bir şekilde, direkt kullanmalı.
@@ -118,7 +118,7 @@ Swagger bir noktada Linux Foundation'a verildi ve adı OpenAPI olarak değiştir
İşte bu yüzden versiyon 2.0 hakkında konuşurken "Swagger", versiyon 3 ve üzeri için ise "OpenAPI" adını kullanmak daha yaygın.
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
API spesifikasyonları için özel bir şema yerine bir açık standart benimseyip kullanmalı.
@@ -147,7 +147,7 @@ Marshmallow bu özellikleri sağlamak için geliştirilmişti. Benim de geçmiş
Ama... Python'un tip belirteçleri gelmeden önce oluşturulmuştu. Yani her şemayı tanımlamak için Marshmallow'un sunduğu spesifik araçları ve sınıfları kullanmanız gerekiyordu.
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
Kod kullanarak otomatik olarak veri tipini ve veri doğrulamayı belirten "şemalar" tanımlamalı.
@@ -163,13 +163,13 @@ Veri doğrulama için arka planda Marshmallow kullanıyor, hatta aynı geliştir
Webargs da harika bir araç ve onu da geçmişte henüz **FastAPI** yokken çok kullandım.
-/// info | "Bilgi"
+/// info | Bilgi
Webargs aynı Marshmallow geliştirileri tarafından oluşturuldu.
///
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
Gelen istek verisi için otomatik veri doğrulamaya sahip olmalı.
@@ -191,13 +191,13 @@ Fakat sonrasında yine mikro sözdizimi problemiyle karşılaşıyoruz. Python m
Editör bu konuda pek yardımcı olamaz. Üstelik eğer parametreleri ya da Marshmallow şemalarını değiştirip YAML kodunu güncellemeyi unutursak artık döküman geçerliliğini yitiriyor.
-/// info | "Bilgi"
+/// info | Bilgi
APISpec de aynı Marshmallow geliştiricileri tarafından oluşturuldu.
///
-/// check | "**FastAPI**'a nasıl ilham verdi?"
+/// check | **FastAPI**'a nasıl ilham verdi?
API'lar için açık standart desteği olmalı (OpenAPI gibi).
@@ -223,13 +223,13 @@ Bunu kullanmak, bir kaç `uvloop` kullanıldı. Hızının asıl kaynağı buydu.
@@ -269,7 +269,7 @@ Uvicorn ve Starlette'e ilham kaynağı olduğu oldukça açık, şu anda ikisi d
///
-/// check | "**FastAPI**'a nasıl ilham oldu?"
+/// check | **FastAPI**'a nasıl ilham oldu?
Uçuk performans sağlayacak bir yol bulmalı.
@@ -285,7 +285,7 @@ Falcon ise bir diğer yüksek performanslı Python framework'ü. Minimal olacak
Yani veri doğrulama, veri dönüştürme ve dökümantasyonun hepsi kodda yer almalı, otomatik halledemiyoruz. Ya da Falcon üzerine bir framework olarak uygulanmaları gerekiyor, aynı Hug'da olduğu gibi. Bu ayrım Falcon'un tasarımından esinlenen, istek ve cevap objelerini parametre olarak işleyen diğer kütüphanelerde de yer alıyor.
-/// check | "**FastAPI**'a nasıl ilham oldu?"
+/// check | **FastAPI**'a nasıl ilham oldu?
Harika bir performans'a sahip olmanın yollarını bulmalı.
@@ -311,7 +311,7 @@ Biraz daha detaylı ayarlamalara gerek duyuyor. Ayrıca Yol'lar fonksiyonun üstünde endpoint'i işleyen dekoratörler yerine farklı yerlerde tanımlanan fonksiyonlarla belirlenir. Bu Flask (ve Starlette) yerine daha çok Django'nun yaklaşımına daha yakın bir metot. Bu, kodda nispeten birbiriyle sıkı ilişkili olan şeyleri ayırmaya sebep oluyor.
-/// check | "**FastAPI**'a nasıl ilham oldu?"
+/// check | **FastAPI**'a nasıl ilham oldu?
Model özelliklerinin "standart" değerlerini kullanarak veri tipleri için ekstra veri doğrulama koşulları tanımlamalı. Bu editör desteğini geliştiriyor ve daha önceden Pydantic'te yoktu.
@@ -319,7 +319,7 @@ Bu aslında Pydantic'in de aynı doğrulama stiline geçmesinde ilham kaynağı
///
-### Hug
+### Hug
Hug, Python tip belirteçlerini kullanarak API parametrelerinin tipini belirlemeyi uygulayan ilk framework'lerdendi. Bu, diğer araçlara da ilham kaynağı olan harika bir fikirdi.
@@ -333,13 +333,13 @@ Ayrıca ilginç ve çok rastlanmayan bir özelliği vardı: aynı framework'ü k
Senkron çalışan Python web framework'lerinin standardına (WSGI) dayandığından dolayı Websocket'leri ve diğer şeyleri işleyemiyor, ancak yine de yüksek performansa sahip.
-/// info | "Bilgi"
+/// info | Bilgi
Hug, Python dosyalarında bulunan dahil etme satırlarını otomatik olarak sıralayan harika bir araç olan `isort`'un geliştiricisi Timothy Crosley tarafından geliştirildi.
///
-/// check | "**FastAPI**'a nasıl ilham oldu?"
+/// check | **FastAPI**'a nasıl ilham oldu?
Hug, APIStar'ın çeşitli kısımlarında esin kaynağı oldu ve APIStar'la birlikte en umut verici bulduğum araçlardan biriydi.
@@ -373,7 +373,7 @@ Geliştiricinin Starlette'e odaklanması gerekince proje de artık bir API web f
Artık APIStar, OpenAPI özelliklerini doğrulamak için bir dizi araç sunan bir proje haline geldi.
-/// info | "Bilgi"
+/// info | Bilgi
APIStar, aşağıdaki projeleri de üreten Tom Christie tarafından geliştirildi:
@@ -383,7 +383,7 @@ APIStar, aşağıdaki projeleri de üreten Tom Christie tarafından geliştirild
///
-/// check | "**FastAPI**'a nasıl ilham oldu?"
+/// check | **FastAPI**'a nasıl ilham oldu?
Var oldu.
@@ -407,7 +407,7 @@ Tip belirteçleri kullanıyor olması onu aşırı sezgisel yapıyor.
Marshmallow ile karşılaştırılabilir. Ancak karşılaştırmalarda Marshmallowdan daha hızlı görünüyor. Aynı Python tip belirteçlerine dayanıyor ve editör desteği de harika.
-/// check | "**FastAPI** nerede kullanıyor?"
+/// check | **FastAPI** nerede kullanıyor?
Bütün veri doğrulama, veri dönüştürme ve JSON Şemasına bağlı otomatik model dökümantasyonunu halletmek için!
@@ -442,7 +442,7 @@ Ancak otomatik veri doğrulama, veri dönüştürme ve dökümantasyon sağlamyo
Bu, **FastAPI**'ın onun üzerine tamamen Python tip belirteçlerine bağlı olarak eklediği (Pydantic ile) ana şeylerden biri. **FastAPI** bunun yanında artı olarak bağımlılık enjeksiyonu sistemi, güvenlik araçları, OpenAPI şema üretimi ve benzeri özellikler de ekliyor.
-/// note | "Teknik Detaylar"
+/// note | Teknik Detaylar
ASGI, Django'nun ana ekibi tarafından geliştirilen yeni bir "standart". Bir "Python standardı" (PEP) olma sürecinde fakat henüz bir standart değil.
@@ -450,7 +450,7 @@ Bununla birlikte, halihazırda birçok araç tarafından bir "standart" olarak k
///
-/// check | "**FastAPI** nerede kullanıyor?"
+/// check | **FastAPI** nerede kullanıyor?
Tüm temel web kısımlarında üzerine özellikler eklenerek kullanılmakta.
@@ -468,7 +468,7 @@ Bir web framework'ünden ziyade bir sunucudur, yani yollara bağlı yönlendirme
Starlette ve **FastAPI** için tavsiye edilen sunucu Uvicorndur.
-/// check | "**FastAPI** neden tavsiye ediyor?"
+/// check | **FastAPI** neden tavsiye ediyor?
**FastAPI** uygulamalarını çalıştırmak için ana web sunucusu Uvicorn!
diff --git a/docs/tr/docs/async.md b/docs/tr/docs/async.md
index 0d463a2f0..558a79cb7 100644
--- a/docs/tr/docs/async.md
+++ b/docs/tr/docs/async.md
@@ -21,7 +21,7 @@ async def read_results():
return results
```
-/// note | "Not"
+/// note | Not
Sadece `async def` ile tanımlanan fonksiyonlar içinde `await` kullanabilirsiniz.
diff --git a/docs/tr/docs/how-to/index.md b/docs/tr/docs/how-to/index.md
index 798adca61..26dd9026c 100644
--- a/docs/tr/docs/how-to/index.md
+++ b/docs/tr/docs/how-to/index.md
@@ -6,7 +6,7 @@ Bu fikirlerin büyük bir kısmı aşağı yukarı **bağımsız** olacaktır,
Projeniz için ilginç ve yararlı görünen bir şey varsa devam edin ve inceleyin, aksi halde bunları atlayabilirsiniz.
-/// tip | "İpucu"
+/// tip | İpucu
**FastAPI**'ı düzgün (ve önerilen) şekilde öğrenmek istiyorsanız [Öğretici - Kullanıcı Rehberi](../tutorial/index.md){.internal-link target=_blank}'ni bölüm bölüm okuyun.
diff --git a/docs/tr/docs/python-types.md b/docs/tr/docs/python-types.md
index b8b880c6d..308dfa6fb 100644
--- a/docs/tr/docs/python-types.md
+++ b/docs/tr/docs/python-types.md
@@ -12,7 +12,7 @@ Bu pythonda tip belirteçleri için **hızlı bir başlangıç / bilgi tazeleme
**FastAPI** kullanmayacak olsanız bile tür belirteçleri hakkında bilgi edinmenizde fayda var.
-/// note | "Not"
+/// note | Not
Python uzmanıysanız ve tip belirteçleri ilgili her şeyi zaten biliyorsanız, sonraki bölüme geçin.
@@ -23,7 +23,7 @@ Python uzmanıysanız ve tip belirteçleri ilgili her şeyi zaten biliyorsanız,
Basit bir örnek ile başlayalım:
```Python
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
Programın çıktısı:
@@ -39,7 +39,7 @@ Fonksiyon sırayla şunları yapar:
* Değişkenleri aralarında bir boşlukla beraber Birleştirir.
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
### Düzenle
@@ -83,7 +83,7 @@ Bu kadar.
İşte bunlar "tip belirteçleri":
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
+{!../../docs_src/python_types/tutorial002.py!}
```
Bu, aşağıdaki gibi varsayılan değerleri bildirmekle aynı şey değildir:
@@ -113,7 +113,7 @@ Aradığınızı bulana kadar seçenekleri kaydırabilirsiniz:
Bu fonksiyon, zaten tür belirteçlerine sahip:
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
+{!../../docs_src/python_types/tutorial003.py!}
```
Editör değişkenlerin tiplerini bildiğinden, yalnızca otomatik tamamlama değil, hata kontrolleri de sağlar:
@@ -123,7 +123,7 @@ Editör değişkenlerin tiplerini bildiğinden, yalnızca otomatik tamamlama de
Artık `age` değişkenini `str(age)` olarak kullanmanız gerektiğini biliyorsunuz:
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
+{!../../docs_src/python_types/tutorial004.py!}
```
## Tip bildirme
@@ -144,7 +144,7 @@ Yalnızca `str` değil, tüm standart Python tiplerinin bildirebilirsiniz.
* `bytes`
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
+{!../../docs_src/python_types/tutorial005.py!}
```
### Tip parametreleri ile Generic tipler
@@ -162,7 +162,7 @@ Bu tür tip belirteçlerini desteklemek için özel olarak mevcuttur.
From `typing`, import `List` (büyük harf olan `L` ile):
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial006.py!}
+{!../../docs_src/python_types/tutorial006.py!}
```
Değişkenin tipini yine iki nokta üstüste (`:`) ile belirleyin.
@@ -172,10 +172,10 @@ tip olarak `List` kullanın.
Liste, bazı dahili tipleri içeren bir tür olduğundan, bunları köşeli parantez içine alırsınız:
```Python hl_lines="4"
-{!../../../docs_src/python_types/tutorial006.py!}
+{!../../docs_src/python_types/tutorial006.py!}
```
-/// tip | "Ipucu"
+/// tip | Ipucu
Köşeli parantez içindeki bu dahili tiplere "tip parametreleri" denir.
@@ -200,7 +200,7 @@ Ve yine, editör bunun bir `str` olduğunu biliyor ve bunun için destek s
`Tuple` ve `set`lerin tiplerini bildirmek için de aynısını yapıyoruz:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial007.py!}
+{!../../docs_src/python_types/tutorial007.py!}
```
Bu şu anlama geliyor:
@@ -217,7 +217,7 @@ Bir `dict` tanımlamak için virgülle ayrılmış iki parametre verebilirsiniz.
İkinci parametre ise `dict` değerinin `value` değeri içindir:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial008.py!}
+{!../../docs_src/python_types/tutorial008.py!}
```
Bu şu anlama gelir:
@@ -231,7 +231,7 @@ Bu şu anlama gelir:
`Optional` bir değişkenin `str`gibi bir tipi olabileceğini ama isteğe bağlı olarak tipinin `None` olabileceğini belirtir:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009.py!}
```
`str` yerine `Optional[str]` kullanmak editorün bu değerin her zaman `str` tipinde değil bazen `None` tipinde de olabileceğini belirtir ve hataları tespit etmemizde yardımcı olur.
@@ -256,13 +256,13 @@ Bir değişkenin tipini bir sınıf ile bildirebilirsiniz.
Diyelim ki `name` değerine sahip `Person` sınıfınız var:
```Python hl_lines="1-3"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
Sonra bir değişkeni 'Person' tipinde tanımlayabilirsiniz:
```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
Ve yine bütün editör desteğini alırsınız:
@@ -284,7 +284,7 @@ Ve ortaya çıkan nesne üzerindeki bütün editör desteğini alırsınız.
Resmi Pydantic dokümanlarından alınmıştır:
```Python
-{!../../../docs_src/python_types/tutorial011.py!}
+{!../../docs_src/python_types/tutorial011.py!}
```
/// info
diff --git a/docs/tr/docs/tutorial/cookie-params.md b/docs/tr/docs/tutorial/cookie-params.md
index 807f85e8a..56bcc0c86 100644
--- a/docs/tr/docs/tutorial/cookie-params.md
+++ b/docs/tr/docs/tutorial/cookie-params.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -25,35 +25,35 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "İpucu"
+/// tip | İpucu
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
///
```Python hl_lines="1"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "İpucu"
+/// tip | İpucu
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
///
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
@@ -67,7 +67,7 @@ Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -75,7 +75,7 @@ Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -83,40 +83,40 @@ Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
-/// tip | "İpucu"
+/// tip | İpucu
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
///
```Python hl_lines="7"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
//// tab | Python 3.8+ non-Annotated
-/// tip | "İpucu"
+/// tip | İpucu
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
///
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
-/// note | "Teknik Detaylar"
+/// note | Teknik Detaylar
`Cookie` sınıfı `Path` ve `Query` sınıflarının kardeşidir. Diğerleri gibi `Param` sınıfını miras alan bir sınıftır.
@@ -124,7 +124,7 @@ Ancak `fastapi`'dan projenize dahil ettiğiniz `Query`, `Path`, `Cookie` ve diğ
///
-/// info | "Bilgi"
+/// info | Bilgi
Çerez tanımlamak için `Cookie` sınıfını kullanmanız gerekmektedir, aksi taktirde parametreler sorgu parametreleri olarak yorumlanır.
diff --git a/docs/tr/docs/tutorial/first-steps.md b/docs/tr/docs/tutorial/first-steps.md
index 76c035992..da9057204 100644
--- a/docs/tr/docs/tutorial/first-steps.md
+++ b/docs/tr/docs/tutorial/first-steps.md
@@ -3,7 +3,7 @@
En sade FastAPI dosyası şu şekilde görünür:
```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Yukarıdaki içeriği bir `main.py` dosyasına kopyalayalım.
@@ -24,7 +24,7 @@ $ uvicorn main:app --reload
-/// note | "Not"
+/// note | Not
`uvicorn main:app` komutunu şu şekilde açıklayabiliriz:
@@ -134,12 +134,12 @@ Ayrıca, API'ınızla iletişim kuracak önyüz, mobil veya IoT uygulamaları gi
### Adım 1: `FastAPI`yı Projemize Dahil Edelim
```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI`, API'niz için tüm işlevselliği sağlayan bir Python sınıfıdır.
-/// note | "Teknik Detaylar"
+/// note | Teknik Detaylar
`FastAPI` doğrudan `Starlette`'i miras alan bir sınıftır.
@@ -150,7 +150,7 @@ Ayrıca, API'ınızla iletişim kuracak önyüz, mobil veya IoT uygulamaları gi
### Adım 2: Bir `FastAPI` "Örneği" Oluşturalım
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Burada `app` değişkeni `FastAPI` sınıfının bir örneği olacaktır.
@@ -172,7 +172,7 @@ $ uvicorn main:app --reload
Uygulamanızı aşağıdaki gibi oluşturursanız:
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial002.py!}
+{!../../docs_src/first_steps/tutorial002.py!}
```
Ve bunu `main.py` dosyasına yerleştirirseniz eğer `uvicorn` komutunu şu şekilde çalıştırabilirsiniz:
@@ -205,7 +205,7 @@ https://example.com/items/foo
/items/foo
```
-/// info | "Bilgi"
+/// info | Bilgi
"Yol" genellikle "endpoint" veya "route" olarak adlandırılır.
@@ -251,7 +251,7 @@ Biz de onları "**operasyonlar**" olarak adlandıracağız.
#### Bir *Yol Operasyonu Dekoratörü* Tanımlayalım
```Python hl_lines="6"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`@app.get("/")` dekoratörü, **FastAPI**'a hemen altındaki fonksiyonun aşağıdaki durumlardan sorumlu olduğunu söyler:
@@ -259,7 +259,7 @@ Biz de onları "**operasyonlar**" olarak adlandıracağız.
* get operasyonu ile
* `/` yoluna gelen istekler
-/// info | "`@decorator` Bilgisi"
+/// info | `@decorator` Bilgisi
Python'da `@something` sözdizimi "dekoratör" olarak adlandırılır.
@@ -286,7 +286,7 @@ Daha az kullanılanları da kullanabilirsiniz:
* `@app.patch()`
* `@app.trace()`
-/// tip | "İpucu"
+/// tip | İpucu
Her işlemi (HTTP metod) istediğiniz gibi kullanmakta özgürsünüz.
@@ -307,7 +307,7 @@ Aşağıdaki, bizim **yol operasyonu fonksiyonumuzdur**:
* **fonksiyon**: "dekoratör"ün (`@app.get("/")`'in) altındaki fonksiyondur.
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Bu bir Python fonksiyonudur.
@@ -321,10 +321,10 @@ Bu durumda bu fonksiyon bir `async` fonksiyondur.
Bu fonksiyonu `async def` yerine normal bir fonksiyon olarak da tanımlayabilirsiniz.
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
+{!../../docs_src/first_steps/tutorial003.py!}
```
-/// note | "Not"
+/// note | Not
Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurry){.internal-link target=_blank} sayfasını kontrol edebilirsiniz.
@@ -333,7 +333,7 @@ Eğer farkı bilmiyorsanız, [Async: *"Aceleniz mi var?"*](../async.md#in-a-hurr
### Adım 5: İçeriği Geri Döndürün
```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Bir `dict`, `list` veya `str`, `int` gibi tekil değerler döndürebilirsiniz.
diff --git a/docs/tr/docs/tutorial/path-params.md b/docs/tr/docs/tutorial/path-params.md
index d36242083..c883c2f9f 100644
--- a/docs/tr/docs/tutorial/path-params.md
+++ b/docs/tr/docs/tutorial/path-params.md
@@ -3,7 +3,7 @@
Yol "parametrelerini" veya "değişkenlerini" Python string biçimlemede kullanılan sözdizimi ile tanımlayabilirsiniz.
```Python hl_lines="6-7"
-{!../../../docs_src/path_params/tutorial001.py!}
+{!../../docs_src/path_params/tutorial001.py!}
```
Yol parametresi olan `item_id`'nin değeri, fonksiyonunuza `item_id` argümanı olarak aktarılacaktır.
@@ -19,12 +19,12 @@ Eğer bu örneği çalıştırıp http://127.0.0.1:8000/items/4.2 sayfasında olduğu gibi `int` yerine `float` bir değer verseydik de ortaya çıkardı.
-/// check | "Ek bilgi"
+/// check | Ek bilgi
Böylece, aynı Python tip tanımlaması ile birlikte, **FastAPI** veri doğrulama özelliği sağlar.
@@ -87,7 +87,7 @@ Ayrıca, tarayıcınızı
-/// check | "Ek bilgi"
+/// check | Ek bilgi
Üstelik, sadece aynı Python tip tanımlaması ile, **FastAPI** size otomatik ve interaktif (Swagger UI ile entegre) bir dokümantasyon sağlar.
@@ -124,7 +124,7 @@ Benzer şekilde `/users/{user_id}` gibi tanımlanmış ve belirli bir kullanıc
*Yol operasyonları* sıralı bir şekilde gözden geçirildiğinden dolayı `/users/me` yolunun `/users/{user_id}` yolundan önce tanımlanmış olmasından emin olmanız gerekmektedir:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003.py!}
+{!../../docs_src/path_params/tutorial003.py!}
```
Aksi halde, `/users/{user_id}` yolu `"me"` değerinin `user_id` parametresi için gönderildiğini "düşünerek" `/users/me` ile de eşleşir.
@@ -132,7 +132,7 @@ Aksi halde, `/users/{user_id}` yolu `"me"` değerinin `user_id` parametresi içi
Benzer şekilde, bir yol operasyonunu yeniden tanımlamanız mümkün değildir:
```Python hl_lines="6 11"
-{!../../../docs_src/path_params/tutorial003b.py!}
+{!../../docs_src/path_params/tutorial003b.py!}
```
Yol, ilk kısım ile eşleştiğinden dolayı her koşulda ilk yol operasyonu kullanılacaktır.
@@ -150,16 +150,16 @@ Eğer *yol parametresi* alan bir *yol operasyonunuz* varsa ve alabileceği *yol
Sonrasında, sınıf içerisinde, mevcut ve geçerli değerler olacak olan sabit değerli özelliklerini oluşturalım:
```Python hl_lines="1 6-9"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// info | "Bilgi"
+/// info | Bilgi
3.4 sürümünden beri enumerationlar (ya da enumlar) Python'da mevcuttur.
///
-/// tip | "İpucu"
+/// tip | İpucu
Merak ediyorsanız söyleyeyim, "AlexNet", "ResNet" ve "LeNet" isimleri Makine Öğrenmesi modellerini temsil eder.
@@ -170,7 +170,7 @@ Merak ediyorsanız söyleyeyim, "AlexNet", "ResNet" ve "LeNet" isimleri Makine
Sonrasında, yarattığımız enum sınıfını (`ModelName`) kullanarak tip belirteci aracılığıyla bir *yol parametresi* oluşturalım:
```Python hl_lines="16"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
### Dokümana Göz Atalım
@@ -188,7 +188,7 @@ Sonrasında, yarattığımız enum sınıfını (`ModelName`) kullanarak tip bel
Parametreyi, yarattığınız enum olan `ModelName` içerisindeki *enumeration üyesi* ile karşılaştırabilirsiniz:
```Python hl_lines="17"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
#### *Enumeration Değerini* Edinelim
@@ -196,10 +196,10 @@ Parametreyi, yarattığınız enum olan `ModelName` içerisindeki *enumeration
`model_name.value` veya genel olarak `your_enum_member.value` tanımlarını kullanarak (bu durumda bir `str` olan) gerçek değere ulaşabilirsiniz:
```Python hl_lines="20"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
-/// tip | "İpucu"
+/// tip | İpucu
`"lenet"` değerine `ModelName.lenet.value` tanımı ile de ulaşabilirsiniz.
@@ -212,7 +212,7 @@ JSON gövdesine (örneğin bir `dict`) gömülü olsalar bile *yol operasyonunda
Bu üyeler istemciye iletilmeden önce kendilerine karşılık gelen değerlerine (bu durumda string) dönüştürüleceklerdir:
```Python hl_lines="18 21 23"
-{!../../../docs_src/path_params/tutorial005.py!}
+{!../../docs_src/path_params/tutorial005.py!}
```
İstemci tarafında şuna benzer bir JSON yanıtı ile karşılaşırsınız:
@@ -253,10 +253,10 @@ Bu durumda, parametrenin adı `file_path` olacaktır ve son kısım olan `:path`
Böylece şunun gibi bir kullanım yapabilirsiniz:
```Python hl_lines="6"
-{!../../../docs_src/path_params/tutorial004.py!}
+{!../../docs_src/path_params/tutorial004.py!}
```
-/// tip | "İpucu"
+/// tip | İpucu
Parametrenin başında `/home/johndoe/myfile.txt` yolunda olduğu gibi (`/`) işareti ile birlikte kullanmanız gerektiği durumlar olabilir.
diff --git a/docs/tr/docs/tutorial/query-params.md b/docs/tr/docs/tutorial/query-params.md
index bf66dbe74..b31d13be4 100644
--- a/docs/tr/docs/tutorial/query-params.md
+++ b/docs/tr/docs/tutorial/query-params.md
@@ -3,7 +3,7 @@
Fonksiyonda yol parametrelerinin parçası olmayan diğer tanımlamalar otomatik olarak "sorgu" parametresi olarak yorumlanır.
```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial001.py!}
+{!../../docs_src/query_params/tutorial001.py!}
```
Sorgu, bağlantıdaki `?` kısmından sonra gelen ve `&` işareti ile ayrılan anahtar-değer çiftlerinin oluşturduğu bir kümedir.
@@ -66,7 +66,7 @@ Aynı şekilde, varsayılan değerlerini `None` olarak atayarak isteğe bağlı
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial002_py310.py!}
+{!> ../../docs_src/query_params/tutorial002_py310.py!}
```
////
@@ -74,14 +74,14 @@ Aynı şekilde, varsayılan değerlerini `None` olarak atayarak isteğe bağlı
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial002.py!}
+{!> ../../docs_src/query_params/tutorial002.py!}
```
////
Bu durumda, `q` fonksiyon parametresi isteğe bağlı olacak ve varsayılan değer olarak `None` alacaktır.
-/// check | "Ek bilgi"
+/// check | Ek bilgi
Ayrıca, dikkatinizi çekerim ki; **FastAPI**, `item_id` parametresinin bir yol parametresi olduğunu ve `q` parametresinin yol değil bir sorgu parametresi olduğunu fark edecek kadar beceriklidir.
@@ -94,7 +94,7 @@ Aşağıda görüldüğü gibi dönüştürülmek üzere `bool` tipleri de tanı
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/query_params/tutorial003_py310.py!}
+{!> ../../docs_src/query_params/tutorial003_py310.py!}
```
////
@@ -102,7 +102,7 @@ Aşağıda görüldüğü gibi dönüştürülmek üzere `bool` tipleri de tanı
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/query_params/tutorial003.py!}
+{!> ../../docs_src/query_params/tutorial003.py!}
```
////
@@ -151,7 +151,7 @@ Ve parametreleri, herhangi bir sıraya koymanıza da gerek yoktur.
//// tab | Python 3.10+
```Python hl_lines="6 8"
-{!> ../../../docs_src/query_params/tutorial004_py310.py!}
+{!> ../../docs_src/query_params/tutorial004_py310.py!}
```
////
@@ -159,7 +159,7 @@ Ve parametreleri, herhangi bir sıraya koymanıza da gerek yoktur.
//// tab | Python 3.8+
```Python hl_lines="8 10"
-{!> ../../../docs_src/query_params/tutorial004.py!}
+{!> ../../docs_src/query_params/tutorial004.py!}
```
////
@@ -173,7 +173,7 @@ Parametre için belirli bir değer atamak istemeyip parametrenin sadece isteğe
Fakat, bir sorgu parametresini zorunlu yapmak istiyorsanız varsayılan bir değer atamamanız yeterli olacaktır:
```Python hl_lines="6-7"
-{!../../../docs_src/query_params/tutorial005.py!}
+{!../../docs_src/query_params/tutorial005.py!}
```
Burada `needy` parametresi `str` tipinden oluşan zorunlu bir sorgu parametresidir.
@@ -223,7 +223,7 @@ Ve elbette, bazı parametreleri zorunlu, bazılarını varsayılan değerli ve b
//// tab | Python 3.10+
```Python hl_lines="8"
-{!> ../../../docs_src/query_params/tutorial006_py310.py!}
+{!> ../../docs_src/query_params/tutorial006_py310.py!}
```
////
@@ -231,7 +231,7 @@ Ve elbette, bazı parametreleri zorunlu, bazılarını varsayılan değerli ve b
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/query_params/tutorial006.py!}
+{!> ../../docs_src/query_params/tutorial006.py!}
```
////
@@ -242,7 +242,7 @@ Bu durumda, 3 tane sorgu parametresi var olacaktır:
* `skip`, varsayılan değeri `0` olan bir `int`.
* `limit`, isteğe bağlı bir `int`.
-/// tip | "İpucu"
+/// tip | İpucu
Ayrıca, [Yol Parametrelerinde](path-params.md#on-tanml-degerler){.internal-link target=_blank} de kullanıldığı şekilde `Enum` sınıfından faydalanabilirsiniz.
diff --git a/docs/tr/docs/tutorial/request-forms.md b/docs/tr/docs/tutorial/request-forms.md
index 8e8ccfba4..4ed8ac021 100644
--- a/docs/tr/docs/tutorial/request-forms.md
+++ b/docs/tr/docs/tutorial/request-forms.md
@@ -2,7 +2,7 @@
İstek gövdesinde JSON verisi yerine form alanlarını karşılamanız gerketiğinde `Form` sınıfını kullanabilirsiniz.
-/// info | "Bilgi"
+/// info | Bilgi
Formları kullanmak için öncelikle `python-multipart` paketini indirmeniz gerekmektedir.
@@ -17,7 +17,7 @@ Formları kullanmak için öncelikle ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
```
////
@@ -25,7 +25,7 @@ Formları kullanmak için öncelikle ../../../docs_src/request_forms/tutorial001_an.py!}
+{!> ../../docs_src/request_forms/tutorial001_an.py!}
```
////
@@ -39,7 +39,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="1"
-{!> ../../../docs_src/request_forms/tutorial001.py!}
+{!> ../../docs_src/request_forms/tutorial001.py!}
```
////
@@ -51,7 +51,7 @@ Form parametrelerini `Body` veya `Query` için yaptığınız gibi oluşturun:
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
```
////
@@ -59,7 +59,7 @@ Form parametrelerini `Body` veya `Query` için yaptığınız gibi oluşturun:
//// tab | Python 3.8+
```Python hl_lines="8"
-{!> ../../../docs_src/request_forms/tutorial001_an.py!}
+{!> ../../docs_src/request_forms/tutorial001_an.py!}
```
////
@@ -73,7 +73,7 @@ Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="7"
-{!> ../../../docs_src/request_forms/tutorial001.py!}
+{!> ../../docs_src/request_forms/tutorial001.py!}
```
////
@@ -84,13 +84,13 @@ Bu spesifikasyon form alanlar
`Form` sınıfıyla tanımlama yaparken `Body`, `Query`, `Path` ve `Cookie` sınıflarında kullandığınız aynı validasyon, örnekler, isimlendirme (örneğin `username` yerine `user-name` kullanımı) ve daha fazla konfigurasyonu kullanabilirsiniz.
-/// info | "Bilgi"
+/// info | Bilgi
`Form` doğrudan `Body` sınıfını miras alan bir sınıftır.
///
-/// tip | "İpucu"
+/// tip | İpucu
Form gövdelerini tanımlamak için `Form` sınıfını kullanmanız gerekir; çünkü bu olmadan parametreler sorgu parametreleri veya gövde (JSON) parametreleri olarak yorumlanır.
@@ -102,7 +102,7 @@ HTML formlarının (``) verileri sunucuya gönderirken JSON'dan far
**FastAPI** bu verilerin JSON yerine doğru şekilde okunmasını sağlayacaktır.
-/// note | "Teknik Detaylar"
+/// note | Teknik Detaylar
Form verileri normalde `application/x-www-form-urlencoded` medya tipiyle kodlanır.
@@ -112,7 +112,7 @@ Form kodlama türleri ve form alanları hakkında daha fazla bilgi edinmek istiy
///
-/// warning | "Uyarı"
+/// warning | Uyarı
*Yol operasyonları* içerisinde birden fazla `Form` parametresi tanımlayabilirsiniz ancak bunlarla birlikte JSON verisi kabul eden `Body` alanları tanımlayamazsınız çünkü bu durumda istek gövdesi `application/json` yerine `application/x-www-form-urlencoded` ile kodlanmış olur.
diff --git a/docs/tr/docs/tutorial/static-files.md b/docs/tr/docs/tutorial/static-files.md
index b82be611f..da8bed86a 100644
--- a/docs/tr/docs/tutorial/static-files.md
+++ b/docs/tr/docs/tutorial/static-files.md
@@ -8,10 +8,10 @@
* Bir `StaticFiles()` örneğini belirli bir yola bağlayın.
```Python hl_lines="2 6"
-{!../../../docs_src/static_files/tutorial001.py!}
+{!../../docs_src/static_files/tutorial001.py!}
```
-/// note | "Teknik Detaylar"
+/// note | Teknik Detaylar
Projenize dahil etmek için `from starlette.staticfiles import StaticFiles` kullanabilirsiniz.
diff --git a/docs/uk/docs/alternatives.md b/docs/uk/docs/alternatives.md
index eb48d6be7..1acbe237a 100644
--- a/docs/uk/docs/alternatives.md
+++ b/docs/uk/docs/alternatives.md
@@ -30,13 +30,13 @@
Це був один із перших прикладів **автоматичної документації API**, і саме це була одна з перших ідей, яка надихнула на «пошук» **FastAPI**.
-/// note | "Примітка"
+/// note | Примітка
Django REST Framework створив Том Крісті. Той самий творець Starlette і Uvicorn, на яких базується **FastAPI**.
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Мати автоматичний веб-інтерфейс документації API.
@@ -56,7 +56,7 @@ Flask — це «мікрофреймворк», він не включає ін
Враховуючи простоту Flask, він здавався хорошим підходом для створення API. Наступним, що знайшов, був «Django REST Framework» для Flask.
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Бути мікрофреймоворком. Зробити легким комбінування та поєднання необхідних інструментів та частин.
@@ -98,7 +98,7 @@ def read_url():
Зверніть увагу на схожість у `requests.get(...)` і `@app.get(...)`.
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
* Майте простий та інтуїтивно зрозумілий API.
* Використовуйте імена (операції) методів HTTP безпосередньо, простим та інтуїтивно зрозумілим способом.
@@ -118,7 +118,7 @@ def read_url():
Тому, коли говорять про версію 2.0, прийнято говорити «Swagger», а про версію 3+ «OpenAPI».
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Прийняти і використовувати відкритий стандарт для специфікацій API замість спеціальної схеми.
@@ -147,7 +147,7 @@ Marshmallow створено для забезпечення цих функці
Але він був створений до того, як існували підказки типу Python. Отже, щоб визначити кожну схему, вам потрібно використовувати спеціальні утиліти та класи, надані Marshmallow.
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Використовувати код для автоматичного визначення "схем", які надають типи даних і перевірку.
@@ -163,13 +163,13 @@ Webargs — це інструмент, створений, щоб забезпе
Це чудовий інструмент, і я також часто використовував його, перш ніж створити **FastAPI**.
-/// info | "Інформація"
+/// info | Інформація
Webargs був створений тими ж розробниками Marshmallow.
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Мати автоматичну перевірку даних вхідного запиту.
@@ -193,13 +193,13 @@ Marshmallow і Webargs забезпечують перевірку, аналіз
Редактор тут нічим не може допомогти. І якщо ми змінимо параметри чи схеми Marshmallow і забудемо також змінити цю строку документа YAML, згенерована схема буде застарілою.
-/// info | "Інформація"
+/// info | Інформація
APISpec був створений тими ж розробниками Marshmallow.
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Підтримувати відкритий стандарт API, OpenAPI.
@@ -225,13 +225,13 @@ APISpec був створений тими ж розробниками Marshmall
І ці самі генератори повного стеку були основою [**FastAPI** генераторів проектів](project-generation.md){.internal-link target=_blank}.
-/// info | "Інформація"
+/// info | Інформація
Flask-apispec був створений тими ж розробниками Marshmallow.
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Створення схеми OpenAPI автоматично з того самого коду, який визначає серіалізацію та перевірку.
@@ -251,7 +251,7 @@ Flask-apispec був створений тими ж розробниками Mar
Він не дуже добре обробляє вкладені моделі. Отже, якщо тіло JSON у запиті є об’єктом JSON із внутрішніми полями, які, у свою чергу, є вкладеними об’єктами JSON, його неможливо належним чином задокументувати та перевірити.
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Використовувати типи Python, щоб мати чудову підтримку редактора.
@@ -263,7 +263,7 @@ Flask-apispec був створений тими ж розробниками Mar
Це був один із перших надзвичайно швидких фреймворків Python на основі `asyncio`. Він був дуже схожий на Flask.
-/// note | "Технічні деталі"
+/// note | Технічні деталі
Він використовував `uvloop` замість стандартного циклу Python `asyncio`. Ось що зробило його таким швидким.
@@ -271,7 +271,7 @@ Flask-apispec був створений тими ж розробниками Mar
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Знайти спосіб отримати божевільну продуктивність.
@@ -287,7 +287,7 @@ Falcon — ще один високопродуктивний фреймворк
Таким чином, перевірка даних, серіалізація та документація повинні виконуватися в коді, а не автоматично. Або вони повинні бути реалізовані як фреймворк поверх Falcon, як Hug. Така сама відмінність спостерігається в інших фреймворках, натхненних дизайном Falcon, що мають один об’єкт запиту та один об’єкт відповіді як параметри.
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Знайти способи отримати чудову продуктивність.
@@ -313,7 +313,7 @@ Falcon — ще один високопродуктивний фреймворк
Маршрути оголошуються в одному місці з використанням функцій, оголошених в інших місцях (замість використання декораторів, які можна розмістити безпосередньо поверх функції, яка обробляє кінцеву точку). Це ближче до того, як це робить Django, ніж до Flask (і Starlette). Він розділяє в коді речі, які відносно тісно пов’язані.
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Визначити додаткові перевірки для типів даних, використовуючи значення "за замовчуванням" атрибутів моделі. Це покращує підтримку редактора, а раніше вона була недоступна в Pydantic.
@@ -321,7 +321,7 @@ Falcon — ще один високопродуктивний фреймворк
///
-### Hug
+### Hug
Hug був одним із перших фреймворків, який реалізував оголошення типів параметрів API за допомогою підказок типу Python. Це була чудова ідея, яка надихнула інші інструменти зробити те саме.
@@ -335,13 +335,13 @@ Hug був одним із перших фреймворків, який реа
Оскільки він заснований на попередньому стандарті для синхронних веб-фреймворків Python (WSGI), він не може працювати з Websockets та іншими речами, хоча він також має високу продуктивність.
-/// info | "Інформація"
+/// info | Інформація
Hug створив Тімоті Крослі, той самий творець `isort`, чудовий інструмент для автоматичного сортування імпорту у файлах Python.
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Hug надихнув частину APIStar і був одним із найбільш перспективних інструментів, поряд із APIStar.
@@ -375,7 +375,7 @@ Hug надихнув частину APIStar і був одним із найбі
Тепер APIStar — це набір інструментів для перевірки специфікацій OpenAPI, а не веб-фреймворк.
-/// info | "Інформація"
+/// info | Інформація
APIStar створив Том Крісті. Той самий хлопець, який створив:
@@ -385,7 +385,7 @@ APIStar створив Том Крісті. Той самий хлопець, я
///
-/// check | "Надихнуло **FastAPI** на"
+/// check | Надихнуло **FastAPI** на
Існувати.
@@ -407,7 +407,7 @@ Pydantic — це бібліотека для визначення переві
Його можна порівняти з Marshmallow. Хоча він швидший за Marshmallow у тестах. Оскільки він базується на тих самих підказках типу Python, підтримка редактора чудова.
-/// check | "**FastAPI** використовує його для"
+/// check | **FastAPI** використовує його для
Виконання перевірки всіх даних, серіалізації даних і автоматичної документацію моделі (на основі схеми JSON).
@@ -442,7 +442,7 @@ Starlette надає всі основні функції веб-мікрофр
Це одна з головних речей, які **FastAPI** додає зверху, все на основі підказок типу Python (з використанням Pydantic). Це, а також система впровадження залежностей, утиліти безпеки, створення схеми OpenAPI тощо.
-/// note | "Технічні деталі"
+/// note | Технічні деталі
ASGI — це новий «стандарт», який розробляється членами основної команди Django. Це ще не «стандарт Python» (PEP), хоча вони в процесі цього.
@@ -450,7 +450,7 @@ ASGI — це новий «стандарт», який розробляєтьс
///
-/// check | "**FastAPI** використовує його для"
+/// check | **FastAPI** використовує його для
Керування всіма основними веб-частинами. Додавання функцій зверху.
@@ -468,7 +468,7 @@ Uvicorn — це блискавичний сервер ASGI, побудован
Це рекомендований сервер для Starlette і **FastAPI**.
-/// check | "**FastAPI** рекомендує це як"
+/// check | **FastAPI** рекомендує це як
Основний веб-сервер для запуску програм **FastAPI**.
diff --git a/docs/uk/docs/index.md b/docs/uk/docs/index.md
index 4c8c54af2..012bac2e2 100644
--- a/docs/uk/docs/index.md
+++ b/docs/uk/docs/index.md
@@ -88,7 +88,7 @@ FastAPI - це сучасний, швидкий (високопродуктив
"_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._"
-
+
---
diff --git a/docs/uk/docs/python-types.md b/docs/uk/docs/python-types.md
index 511a5264a..573b5372c 100644
--- a/docs/uk/docs/python-types.md
+++ b/docs/uk/docs/python-types.md
@@ -23,7 +23,7 @@ Python підтримує додаткові "підказки типу" ("type
Давайте почнемо з простого прикладу:
```Python
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
Виклик цієї програми виводить:
@@ -39,7 +39,7 @@ John Doe
* Конкатенує їх разом із пробілом по середині.
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
### Редагуйте це
@@ -83,7 +83,7 @@ John Doe
Це "type hints":
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
+{!../../docs_src/python_types/tutorial002.py!}
```
Це не те саме, що оголошення значень за замовчуванням, як це було б з:
@@ -113,7 +113,7 @@ John Doe
Перевірте цю функцію, вона вже має анотацію типу:
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
+{!../../docs_src/python_types/tutorial003.py!}
```
Оскільки редактор знає типи змінних, ви не тільки отримаєте автозаповнення, ви також отримаєте перевірку помилок:
@@ -123,7 +123,7 @@ John Doe
Тепер ви знаєте, щоб виправити це, вам потрібно перетворити `age` у строку з допомогою `str(age)`:
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
+{!../../docs_src/python_types/tutorial004.py!}
```
## Оголошення типів
@@ -144,7 +144,7 @@ John Doe
* `bytes`
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
+{!../../docs_src/python_types/tutorial005.py!}
```
### Generic-типи з параметрами типів
@@ -172,7 +172,7 @@ John Doe
З модуля `typing`, імпортуємо `List` (з великої літери `L`):
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial006.py!}
+{!> ../../docs_src/python_types/tutorial006.py!}
```
Оголосимо змінну з тим самим синтаксисом двокрапки (`:`).
@@ -182,7 +182,7 @@ John Doe
Оскільки список є типом, який містить деякі внутрішні типи, ви поміщаєте їх у квадратні дужки:
```Python hl_lines="4"
-{!> ../../../docs_src/python_types/tutorial006.py!}
+{!> ../../docs_src/python_types/tutorial006.py!}
```
////
@@ -196,7 +196,7 @@ John Doe
Оскільки список є типом, який містить деякі внутрішні типи, ви поміщаєте їх у квадратні дужки:
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial006_py39.py!}
+{!> ../../docs_src/python_types/tutorial006_py39.py!}
```
////
@@ -234,7 +234,7 @@ John Doe
//// tab | Python 3.8 і вище
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial007.py!}
+{!> ../../docs_src/python_types/tutorial007.py!}
```
////
@@ -242,7 +242,7 @@ John Doe
//// tab | Python 3.9 і вище
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial007_py39.py!}
+{!> ../../docs_src/python_types/tutorial007_py39.py!}
```
////
@@ -263,7 +263,7 @@ John Doe
//// tab | Python 3.8 і вище
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial008.py!}
+{!> ../../docs_src/python_types/tutorial008.py!}
```
////
@@ -271,7 +271,7 @@ John Doe
//// tab | Python 3.9 і вище
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial008_py39.py!}
+{!> ../../docs_src/python_types/tutorial008_py39.py!}
```
////
@@ -293,7 +293,7 @@ John Doe
//// tab | Python 3.8 і вище
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b.py!}
```
////
@@ -301,7 +301,7 @@ John Doe
//// tab | Python 3.10 і вище
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial008b_py310.py!}
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
////
@@ -315,7 +315,7 @@ John Doe
У Python 3.6 і вище (включаючи Python 3.10) ви можете оголосити його, імпортувавши та використовуючи `Optional` з модуля `typing`.
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009.py!}
```
Використання `Optional[str]` замість просто `str` дозволить редактору допомогти вам виявити помилки, коли ви могли б вважати, що значенням завжди є `str`, хоча насправді воно також може бути `None`.
@@ -327,7 +327,7 @@ John Doe
//// tab | Python 3.8 і вище
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009.py!}
```
////
@@ -335,7 +335,7 @@ John Doe
//// tab | Python 3.8 і вище - альтернатива
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b.py!}
```
////
@@ -343,7 +343,7 @@ John Doe
//// tab | Python 3.10 і вище
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial009_py310.py!}
+{!> ../../docs_src/python_types/tutorial009_py310.py!}
```
////
@@ -407,13 +407,13 @@ John Doe
Скажімо, у вас є клас `Person` з імʼям:
```Python hl_lines="1-3"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
Потім ви можете оголосити змінну типу `Person`:
```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
І знову ж таки, ви отримуєте всю підтримку редактора:
@@ -437,7 +437,7 @@ John Doe
//// tab | Python 3.8 і вище
```Python
-{!> ../../../docs_src/python_types/tutorial011.py!}
+{!> ../../docs_src/python_types/tutorial011.py!}
```
////
@@ -445,7 +445,7 @@ John Doe
//// tab | Python 3.9 і вище
```Python
-{!> ../../../docs_src/python_types/tutorial011_py39.py!}
+{!> ../../docs_src/python_types/tutorial011_py39.py!}
```
////
@@ -453,7 +453,7 @@ John Doe
//// tab | Python 3.10 і вище
```Python
-{!> ../../../docs_src/python_types/tutorial011_py310.py!}
+{!> ../../docs_src/python_types/tutorial011_py310.py!}
```
////
diff --git a/docs/uk/docs/tutorial/body-fields.md b/docs/uk/docs/tutorial/body-fields.md
index e4d5b1fad..c286744a8 100644
--- a/docs/uk/docs/tutorial/body-fields.md
+++ b/docs/uk/docs/tutorial/body-fields.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="4"
-{!> ../../../docs_src/body_fields/tutorial001_an_py310.py!}
+{!> ../../docs_src/body_fields/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="4"
-{!> ../../../docs_src/body_fields/tutorial001_an_py39.py!}
+{!> ../../docs_src/body_fields/tutorial001_an_py39.py!}
```
////
@@ -25,7 +25,7 @@
//// tab | Python 3.8+
```Python hl_lines="4"
-{!> ../../../docs_src/body_fields/tutorial001_an.py!}
+{!> ../../docs_src/body_fields/tutorial001_an.py!}
```
////
@@ -39,7 +39,7 @@
///
```Python hl_lines="2"
-{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
+{!> ../../docs_src/body_fields/tutorial001_py310.py!}
```
////
@@ -53,7 +53,7 @@
///
```Python hl_lines="4"
-{!> ../../../docs_src/body_fields/tutorial001.py!}
+{!> ../../docs_src/body_fields/tutorial001.py!}
```
////
@@ -71,7 +71,7 @@
//// tab | Python 3.10+
```Python hl_lines="11-14"
-{!> ../../../docs_src/body_fields/tutorial001_an_py310.py!}
+{!> ../../docs_src/body_fields/tutorial001_an_py310.py!}
```
////
@@ -79,7 +79,7 @@
//// tab | Python 3.9+
```Python hl_lines="11-14"
-{!> ../../../docs_src/body_fields/tutorial001_an_py39.py!}
+{!> ../../docs_src/body_fields/tutorial001_an_py39.py!}
```
////
@@ -87,7 +87,7 @@
//// tab | Python 3.8+
```Python hl_lines="12-15"
-{!> ../../../docs_src/body_fields/tutorial001_an.py!}
+{!> ../../docs_src/body_fields/tutorial001_an.py!}
```
////
@@ -101,7 +101,7 @@
///
```Python hl_lines="9-12"
-{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
+{!> ../../docs_src/body_fields/tutorial001_py310.py!}
```
////
@@ -115,14 +115,14 @@
///
```Python hl_lines="11-14"
-{!> ../../../docs_src/body_fields/tutorial001.py!}
+{!> ../../docs_src/body_fields/tutorial001.py!}
```
////
`Field` працює так само, як `Query`, `Path` і `Body`, у нього такі самі параметри тощо.
-/// note | "Технічні деталі"
+/// note | Технічні деталі
Насправді, `Query`, `Path` та інші, що ви побачите далі, створюють об'єкти підкласів загального класу `Param`, котрий сам є підкласом класу `FieldInfo` з Pydantic.
diff --git a/docs/uk/docs/tutorial/body.md b/docs/uk/docs/tutorial/body.md
index 50fd76f84..1e4188831 100644
--- a/docs/uk/docs/tutorial/body.md
+++ b/docs/uk/docs/tutorial/body.md
@@ -25,7 +25,7 @@
//// tab | Python 3.8 і вище
```Python hl_lines="4"
-{!> ../../../docs_src/body/tutorial001.py!}
+{!> ../../docs_src/body/tutorial001.py!}
```
////
@@ -33,7 +33,7 @@
//// tab | Python 3.10 і вище
```Python hl_lines="2"
-{!> ../../../docs_src/body/tutorial001_py310.py!}
+{!> ../../docs_src/body/tutorial001_py310.py!}
```
////
@@ -47,7 +47,7 @@
//// tab | Python 3.8 і вище
```Python hl_lines="7-11"
-{!> ../../../docs_src/body/tutorial001.py!}
+{!> ../../docs_src/body/tutorial001.py!}
```
////
@@ -55,7 +55,7 @@
//// tab | Python 3.10 і вище
```Python hl_lines="5-9"
-{!> ../../../docs_src/body/tutorial001_py310.py!}
+{!> ../../docs_src/body/tutorial001_py310.py!}
```
////
@@ -89,7 +89,7 @@
//// tab | Python 3.8 і вище
```Python hl_lines="18"
-{!> ../../../docs_src/body/tutorial001.py!}
+{!> ../../docs_src/body/tutorial001.py!}
```
////
@@ -97,7 +97,7 @@
//// tab | Python 3.10 і вище
```Python hl_lines="16"
-{!> ../../../docs_src/body/tutorial001_py310.py!}
+{!> ../../docs_src/body/tutorial001_py310.py!}
```
////
@@ -170,7 +170,7 @@
//// tab | Python 3.8 і вище
```Python hl_lines="21"
-{!> ../../../docs_src/body/tutorial002.py!}
+{!> ../../docs_src/body/tutorial002.py!}
```
////
@@ -178,7 +178,7 @@
//// tab | Python 3.10 і вище
```Python hl_lines="19"
-{!> ../../../docs_src/body/tutorial002_py310.py!}
+{!> ../../docs_src/body/tutorial002_py310.py!}
```
////
@@ -192,7 +192,7 @@
//// tab | Python 3.8 і вище
```Python hl_lines="17-18"
-{!> ../../../docs_src/body/tutorial003.py!}
+{!> ../../docs_src/body/tutorial003.py!}
```
////
@@ -200,7 +200,7 @@
//// tab | Python 3.10 і вище
```Python hl_lines="15-16"
-{!> ../../../docs_src/body/tutorial003_py310.py!}
+{!> ../../docs_src/body/tutorial003_py310.py!}
```
////
@@ -214,7 +214,7 @@
//// tab | Python 3.8 і вище
```Python hl_lines="18"
-{!> ../../../docs_src/body/tutorial004.py!}
+{!> ../../docs_src/body/tutorial004.py!}
```
////
@@ -222,7 +222,7 @@
//// tab | Python 3.10 і вище
```Python hl_lines="16"
-{!> ../../../docs_src/body/tutorial004_py310.py!}
+{!> ../../docs_src/body/tutorial004_py310.py!}
```
////
diff --git a/docs/uk/docs/tutorial/cookie-params.md b/docs/uk/docs/tutorial/cookie-params.md
index 4720a42ba..229f81b63 100644
--- a/docs/uk/docs/tutorial/cookie-params.md
+++ b/docs/uk/docs/tutorial/cookie-params.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -25,7 +25,7 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
@@ -39,7 +39,7 @@
///
```Python hl_lines="1"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
@@ -53,7 +53,7 @@
///
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
@@ -67,7 +67,7 @@
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -75,7 +75,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -83,7 +83,7 @@
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
@@ -97,7 +97,7 @@
///
```Python hl_lines="7"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
@@ -111,12 +111,12 @@
///
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
-/// note | "Технічні Деталі"
+/// note | Технічні Деталі
`Cookie` це "сестра" класів `Path` і `Query`. Вони наслідуються від одного батьківського класу `Param`.
Але пам'ятайте, що коли ви імпортуєте `Query`, `Path`, `Cookie` та інше з `fastapi`, це фактично функції, що повертають спеціальні класи.
diff --git a/docs/uk/docs/tutorial/encoder.md b/docs/uk/docs/tutorial/encoder.md
index 9ef8d5c5d..77b0baf4d 100644
--- a/docs/uk/docs/tutorial/encoder.md
+++ b/docs/uk/docs/tutorial/encoder.md
@@ -23,7 +23,7 @@
//// tab | Python 3.10+
```Python hl_lines="4 21"
-{!> ../../../docs_src/encoder/tutorial001_py310.py!}
+{!> ../../docs_src/encoder/tutorial001_py310.py!}
```
////
@@ -31,7 +31,7 @@
//// tab | Python 3.8+
```Python hl_lines="5 22"
-{!> ../../../docs_src/encoder/tutorial001.py!}
+{!> ../../docs_src/encoder/tutorial001.py!}
```
////
@@ -42,7 +42,7 @@
Вона не повертає велику строку `str`, яка містить дані у форматі JSON (як строка). Вона повертає стандартну структуру даних Python (наприклад `dict`) із значеннями та підзначеннями, які є сумісними з JSON.
-/// note | "Примітка"
+/// note | Примітка
`jsonable_encoder` фактично використовується **FastAPI** внутрішньо для перетворення даних. Проте вона корисна в багатьох інших сценаріях.
diff --git a/docs/uk/docs/tutorial/extra-data-types.md b/docs/uk/docs/tutorial/extra-data-types.md
index 54cbd4b00..5e6c364e4 100644
--- a/docs/uk/docs/tutorial/extra-data-types.md
+++ b/docs/uk/docs/tutorial/extra-data-types.md
@@ -58,7 +58,7 @@
//// tab | Python 3.10+
```Python hl_lines="1 3 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py310.py!}
```
////
@@ -66,7 +66,7 @@
//// tab | Python 3.9+
```Python hl_lines="1 3 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py39.py!}
```
////
@@ -74,7 +74,7 @@
//// tab | Python 3.8+
```Python hl_lines="1 3 13-17"
-{!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an.py!}
```
////
@@ -88,7 +88,7 @@
///
```Python hl_lines="1 2 11-15"
-{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
```
////
@@ -102,7 +102,7 @@
///
```Python hl_lines="1 2 12-16"
-{!> ../../../docs_src/extra_data_types/tutorial001.py!}
+{!> ../../docs_src/extra_data_types/tutorial001.py!}
```
////
@@ -112,7 +112,7 @@
//// tab | Python 3.10+
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py310.py!}
```
////
@@ -120,7 +120,7 @@
//// tab | Python 3.9+
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an_py39.py!}
```
////
@@ -128,7 +128,7 @@
//// tab | Python 3.8+
```Python hl_lines="19-20"
-{!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_an.py!}
```
////
@@ -142,7 +142,7 @@
///
```Python hl_lines="17-18"
-{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
```
////
@@ -156,7 +156,7 @@
///
```Python hl_lines="18-19"
-{!> ../../../docs_src/extra_data_types/tutorial001.py!}
+{!> ../../docs_src/extra_data_types/tutorial001.py!}
```
////
diff --git a/docs/uk/docs/tutorial/first-steps.md b/docs/uk/docs/tutorial/first-steps.md
index 784da65f5..63fec207d 100644
--- a/docs/uk/docs/tutorial/first-steps.md
+++ b/docs/uk/docs/tutorial/first-steps.md
@@ -3,7 +3,7 @@
Найпростіший файл FastAPI може виглядати так:
```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Скопіюйте це до файлу `main.py`.
@@ -158,12 +158,12 @@ OpenAPI описує схему для вашого API. І ця схема вк
### Крок 1: імпортуємо `FastAPI`
```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` це клас у Python, який надає всю функціональність для API.
-/// note | "Технічні деталі"
+/// note | Технічні деталі
`FastAPI` це клас, який успадковується безпосередньо від `Starlette`.
@@ -174,7 +174,7 @@ OpenAPI описує схему для вашого API. І ця схема вк
### Крок 2: створюємо екземпляр `FastAPI`
```Python hl_lines="3"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Змінна `app` є екземпляром класу `FastAPI`.
@@ -198,7 +198,7 @@ https://example.com/items/foo
/items/foo
```
-/// info | "Додаткова інформація"
+/// info | Додаткова інформація
"Шлях" (path) також зазвичай називають "ендпоінтом" (endpoint) або "маршрутом" (route).
@@ -243,14 +243,14 @@ https://example.com/items/foo
#### Визначте декоратор операції шляху (path operation decorator)
```Python hl_lines="6"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Декоратор `@app.get("/")` вказує **FastAPI**, що функція нижче, відповідає за обробку запитів, які надходять до неї:
* шлях `/`
* використовуючи get операцію
-/// info | "`@decorator` Додаткова інформація"
+/// info | `@decorator` Додаткова інформація
Синтаксис `@something` у Python називається "декоратором".
@@ -277,7 +277,7 @@ https://example.com/items/foo
* `@app.patch()`
* `@app.trace()`
-/// tip | "Порада"
+/// tip | Порада
Ви можете використовувати кожну операцію (HTTP-метод) на свій розсуд.
@@ -298,7 +298,7 @@ https://example.com/items/foo
* **функція**: це функція, яка знаходиться нижче "декоратора" (нижче `@app.get("/")`).
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Це звичайна функція Python.
@@ -312,10 +312,10 @@ FastAPI викликатиме її щоразу, коли отримає зап
Ви також можете визначити її як звичайну функцію замість `async def`:
```Python hl_lines="7"
-{!../../../docs_src/first_steps/tutorial003.py!}
+{!../../docs_src/first_steps/tutorial003.py!}
```
-/// note | "Примітка"
+/// note | Примітка
Якщо не знаєте в чому різниця, подивіться [Конкурентність: *"Поспішаєш?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
@@ -324,7 +324,7 @@ FastAPI викликатиме її щоразу, коли отримає зап
### Крок 5: поверніть результат
```Python hl_lines="8"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Ви можете повернути `dict`, `list`, а також окремі значення `str`, `int`, ітд.
diff --git a/docs/vi/docs/index.md b/docs/vi/docs/index.md
index 09deac6f2..5e346ded8 100644
--- a/docs/vi/docs/index.md
+++ b/docs/vi/docs/index.md
@@ -93,7 +93,7 @@ Những tính năng như:
"_Thành thật, những gì bạn đã xây dựng nhìn siêu chắc chắn và bóng bẩy. Theo nhiều cách, nó là những gì tôi đã muốn Hug trở thành - thật sự truyền cảm hứng để thấy ai đó xây dựng nó._"
-
+
---
diff --git a/docs/vi/docs/python-types.md b/docs/vi/docs/python-types.md
index 99d1d207f..275b0eb39 100644
--- a/docs/vi/docs/python-types.md
+++ b/docs/vi/docs/python-types.md
@@ -23,7 +23,7 @@ Nếu bạn là một chuyên gia về Python, và bạn đã biết mọi thứ
Hãy bắt đầu với một ví dụ đơn giản:
```Python
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
Kết quả khi gọi chương trình này:
@@ -39,7 +39,7 @@ Hàm thực hiện như sau:
* Nối chúng lại với nhau bằng một kí tự trắng ở giữa.
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial001.py!}
+{!../../docs_src/python_types/tutorial001.py!}
```
### Sửa đổi
@@ -83,7 +83,7 @@ Chính là nó.
Những thứ đó là "type hints":
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial002.py!}
+{!../../docs_src/python_types/tutorial002.py!}
```
Đó không giống như khai báo những giá trị mặc định giống như:
@@ -113,7 +113,7 @@ Với cái đó, bạn có thể cuộn, nhìn thấy các lựa chọn, cho đ
Kiểm tra hàm này, nó đã có gợi ý kiểu dữ liệu:
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial003.py!}
+{!../../docs_src/python_types/tutorial003.py!}
```
Bởi vì trình soạn thảo biết kiểu dữ liệu của các biến, bạn không chỉ có được completion, bạn cũng được kiểm tra lỗi:
@@ -123,7 +123,7 @@ Bởi vì trình soạn thảo biết kiểu dữ liệu của các biến, bạ
Bây giờ bạn biết rằng bạn phải sửa nó, chuyển `age` sang một xâu với `str(age)`:
```Python hl_lines="2"
-{!../../../docs_src/python_types/tutorial004.py!}
+{!../../docs_src/python_types/tutorial004.py!}
```
## Khai báo các kiểu dữ liệu
@@ -144,7 +144,7 @@ Bạn có thể sử dụng, ví dụ:
* `bytes`
```Python hl_lines="1"
-{!../../../docs_src/python_types/tutorial005.py!}
+{!../../docs_src/python_types/tutorial005.py!}
```
### Các kiểu dữ liệu tổng quát với tham số kiểu dữ liệu
@@ -182,7 +182,7 @@ Tương tự kiểu dữ liệu `list`.
Như danh sách là một kiểu dữ liệu chứa một vài kiểu dữ liệu có sẵn, bạn đặt chúng trong các dấu ngoặc vuông:
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial006_py39.py!}
+{!> ../../docs_src/python_types/tutorial006_py39.py!}
```
////
@@ -192,7 +192,7 @@ Như danh sách là một kiểu dữ liệu chứa một vài kiểu dữ liệ
Từ `typing`, import `List` (với chữ cái `L` viết hoa):
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial006.py!}
+{!> ../../docs_src/python_types/tutorial006.py!}
```
Khai báo biến với cùng dấu hai chấm (`:`).
@@ -202,7 +202,7 @@ Tương tự như kiểu dữ liệu, `List` bạn import từ `typing`.
Như danh sách là một kiểu dữ liệu chứa các kiểu dữ liệu có sẵn, bạn đặt chúng bên trong dấu ngoặc vuông:
```Python hl_lines="4"
-{!> ../../../docs_src/python_types/tutorial006.py!}
+{!> ../../docs_src/python_types/tutorial006.py!}
```
////
@@ -240,7 +240,7 @@ Bạn sẽ làm điều tương tự để khai báo các `tuple` và các `set
//// tab | Python 3.9+
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial007_py39.py!}
+{!> ../../docs_src/python_types/tutorial007_py39.py!}
```
////
@@ -248,7 +248,7 @@ Bạn sẽ làm điều tương tự để khai báo các `tuple` và các `set
//// tab | Python 3.8+
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial007.py!}
+{!> ../../docs_src/python_types/tutorial007.py!}
```
////
@@ -269,7 +269,7 @@ Tham số kiểu dữ liệu thứ hai dành cho giá trị của `dict`.
//// tab | Python 3.9+
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial008_py39.py!}
+{!> ../../docs_src/python_types/tutorial008_py39.py!}
```
////
@@ -277,7 +277,7 @@ Tham số kiểu dữ liệu thứ hai dành cho giá trị của `dict`.
//// tab | Python 3.8+
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial008.py!}
+{!> ../../docs_src/python_types/tutorial008.py!}
```
////
@@ -302,7 +302,7 @@ Trong Python 3.10 cũng có một **cú pháp mới** mà bạn có thể đặt
//// tab | Python 3.10+
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial008b_py310.py!}
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
////
@@ -310,7 +310,7 @@ Trong Python 3.10 cũng có một **cú pháp mới** mà bạn có thể đặt
//// tab | Python 3.8+
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b.py!}
```
////
@@ -324,7 +324,7 @@ Bạn có thể khai báo một giá trị có thể có một kiểu dữ liệ
Trong Python 3.6 hoặc lớn hơn (bao gồm Python 3.10) bạn có thể khai báo nó bằng các import và sử dụng `Optional` từ mô đun `typing`.
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009.py!}
```
Sử dụng `Optional[str]` thay cho `str` sẽ cho phép trình soạn thảo giúp bạn phát hiện các lỗi mà bạn có thể gặp như một giá trị luôn là một `str`, trong khi thực tế nó rất có thể là `None`.
@@ -336,7 +336,7 @@ Sử dụng `Optional[str]` thay cho `str` sẽ cho phép trình soạn thảo g
//// tab | Python 3.10+
```Python hl_lines="1"
-{!> ../../../docs_src/python_types/tutorial009_py310.py!}
+{!> ../../docs_src/python_types/tutorial009_py310.py!}
```
////
@@ -344,7 +344,7 @@ Sử dụng `Optional[str]` thay cho `str` sẽ cho phép trình soạn thảo g
//// tab | Python 3.8+
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009.py!}
```
////
@@ -352,7 +352,7 @@ Sử dụng `Optional[str]` thay cho `str` sẽ cho phép trình soạn thảo g
//// tab | Python 3.8+ alternative
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b.py!}
```
////
@@ -375,7 +375,7 @@ Nó chỉ là về các từ và tên. Nhưng những từ đó có thể ảnh
Cho một ví dụ, hãy để ý hàm này:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009c.py!}
+{!../../docs_src/python_types/tutorial009c.py!}
```
Tham số `name` được định nghĩa là `Optional[str]`, nhưng nó **không phải là tùy chọn**, bạn không thể gọi hàm mà không có tham số:
@@ -393,7 +393,7 @@ say_hi(name=None) # This works, None is valid 🎉
Tin tốt là, khi bạn sử dụng Python 3.10, bạn sẽ không phải lo lắng về điều đó, bạn sẽ có thể sử dụng `|` để định nghĩa hợp của các kiểu dữ liệu một cách đơn giản:
```Python hl_lines="1 4"
-{!../../../docs_src/python_types/tutorial009c_py310.py!}
+{!../../docs_src/python_types/tutorial009c_py310.py!}
```
Và sau đó, bạn sẽ không phải lo rằng những cái tên như `Optional` và `Union`. 😎
@@ -458,13 +458,13 @@ Bạn cũng có thể khai báo một lớp như là kiểu dữ liệu của m
Hãy nói rằng bạn muốn có một lớp `Person` với một tên:
```Python hl_lines="1-3"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
Sau đó bạn có thể khai báo một biến có kiểu là `Person`:
```Python hl_lines="6"
-{!../../../docs_src/python_types/tutorial010.py!}
+{!../../docs_src/python_types/tutorial010.py!}
```
Và lại một lần nữa, bạn có được tất cả sự hỗ trợ từ trình soạn thảo:
@@ -492,7 +492,7 @@ Một ví dụ từ tài liệu chính thức của Pydantic:
//// tab | Python 3.10+
```Python
-{!> ../../../docs_src/python_types/tutorial011_py310.py!}
+{!> ../../docs_src/python_types/tutorial011_py310.py!}
```
////
@@ -500,7 +500,7 @@ Một ví dụ từ tài liệu chính thức của Pydantic:
//// tab | Python 3.9+
```Python
-{!> ../../../docs_src/python_types/tutorial011_py39.py!}
+{!> ../../docs_src/python_types/tutorial011_py39.py!}
```
////
@@ -508,7 +508,7 @@ Một ví dụ từ tài liệu chính thức của Pydantic:
//// tab | Python 3.8+
```Python
-{!> ../../../docs_src/python_types/tutorial011.py!}
+{!> ../../docs_src/python_types/tutorial011.py!}
```
////
@@ -538,7 +538,7 @@ Python cũng có một tính năng cho phép đặt **metadata bổ sung** trong
Trong Python 3.9, `Annotated` là một phần của thư viện chuẩn, do đó bạn có thể import nó từ `typing`.
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial013_py39.py!}
+{!> ../../docs_src/python_types/tutorial013_py39.py!}
```
////
@@ -550,7 +550,7 @@ Trong Python 3.9, `Annotated` là một phần của thư viện chuẩn, do đ
Nó đã được cài đặt sẵng cùng với **FastAPI**.
```Python hl_lines="1 4"
-{!> ../../../docs_src/python_types/tutorial013.py!}
+{!> ../../docs_src/python_types/tutorial013.py!}
```
////
diff --git a/docs/vi/docs/tutorial/first-steps.md b/docs/vi/docs/tutorial/first-steps.md
index ce808eb91..934527b8e 100644
--- a/docs/vi/docs/tutorial/first-steps.md
+++ b/docs/vi/docs/tutorial/first-steps.md
@@ -3,7 +3,7 @@
Tệp tin FastAPI đơn giản nhất có thể trông như này:
```Python
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
Sao chép sang một tệp tin `main.py`.
@@ -134,12 +134,12 @@ Bạn cũng có thể sử dụng nó để sinh code tự động, với các c
### Bước 1: import `FastAPI`
```Python hl_lines="1"
-{!../../../docs_src/first_steps/tutorial001.py!}
+{!../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` là một Python class cung cấp tất cả chức năng cho API của bạn.
-/// note | "Chi tiết kĩ thuật"
+/// note | Chi tiết kĩ thuật
`FastAPI` là một class kế thừa trực tiếp `Starlette`.
@@ -150,7 +150,7 @@ Bạn cũng có thể sử dụng tất cả Timothy Crosley - Hug creator (ref)
+
---
diff --git a/docs/zh-hant/docs/about/index.md b/docs/zh-hant/docs/about/index.md
new file mode 100644
index 000000000..5dcee68f2
--- /dev/null
+++ b/docs/zh-hant/docs/about/index.md
@@ -0,0 +1,3 @@
+# 關於 FastAPI
+
+關於 FastAPI、其設計、靈感來源等更多資訊。 🤓
diff --git a/docs/zh-hant/docs/deployment/cloud.md b/docs/zh-hant/docs/deployment/cloud.md
new file mode 100644
index 000000000..29ebe3ff5
--- /dev/null
+++ b/docs/zh-hant/docs/deployment/cloud.md
@@ -0,0 +1,17 @@
+# 在雲端部署 FastAPI
+
+你幾乎可以使用**任何雲端供應商**來部署你的 FastAPI 應用程式。
+
+在大多數情況下,主要的雲端供應商都有部署 FastAPI 的指南。
+
+## 雲端供應商 - 贊助商
+
+一些雲端供應商 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這確保了 FastAPI 及其**生態系統**持續健康地**發展**。
+
+這也展現了他們對 FastAPI 和其**社群**(包括你)的真正承諾,他們不僅希望為你提供**優質的服務**,還希望確保你擁有一個**良好且健康的框架**:FastAPI。🙇
+
+你可能會想嘗試他們的服務,以下有他們的指南:
+
+* Platform.sh
+* Porter
+* Coherence
diff --git a/docs/zh-hant/docs/deployment/index.md b/docs/zh-hant/docs/deployment/index.md
new file mode 100644
index 000000000..1726562b4
--- /dev/null
+++ b/docs/zh-hant/docs/deployment/index.md
@@ -0,0 +1,21 @@
+# 部署
+
+部署 **FastAPI** 應用程式相對容易。
+
+## 部署是什麼意思
+
+**部署**應用程式指的是執行一系列必要的步驟,使其能夠**讓使用者存取和使用**。
+
+對於一個 **Web API**,部署通常涉及將其放置在**遠端伺服器**上,並使用性能優良且穩定的**伺服器程式**,確保使用者能夠高效、無中斷地存取應用程式,且不會遇到問題。
+
+這與**開發**階段形成鮮明對比,在**開發**階段,你會不斷更改程式碼、破壞程式碼、修復程式碼,然後停止和重新啟動伺服器等。
+
+## 部署策略
+
+根據你的使用場景和使用工具,有多種方法可以實現此目的。
+
+你可以使用一些工具自行**部署伺服器**,你也可以使用能為你完成部分工作的**雲端服務**,或其他可能的選項。
+
+我將向你展示在部署 **FastAPI** 應用程式時你可能應該記住的一些主要概念(儘管其中大部分適用於任何其他類型的 Web 應用程式)。
+
+在接下來的部分中,你將看到更多需要記住的細節以及一些技巧。 ✨
diff --git a/docs/zh-hant/docs/environment-variables.md b/docs/zh-hant/docs/environment-variables.md
new file mode 100644
index 000000000..a1598fc01
--- /dev/null
+++ b/docs/zh-hant/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# 環境變數
+
+/// tip
+
+如果你已經知道什麼是「環境變數」並且知道如何使用它們,你可以放心跳過這一部分。
+
+///
+
+環境變數(也稱為「**env var**」)是一個獨立於 Python 程式碼**之外**的變數,它存在於**作業系統**中,可以被你的 Python 程式碼(或其他程式)讀取。
+
+環境變數對於處理應用程式**設定**(作為 Python **安裝**的一部分等方面)非常有用。
+
+## 建立和使用環境變數
+
+你在 **shell(終端機)**中就可以**建立**和使用環境變數,並不需要用到 Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
-/// tip | "提示"
+/// tip | 提示
API 文档与所选的服务器进行交互。
@@ -353,7 +353,7 @@ API 文档与所选的服务器进行交互。
如果不想让 **FastAPI** 包含使用 `root_path` 的自动服务器,则要使用参数 `root_path_in_servers=False`:
```Python hl_lines="9"
-{!../../../docs_src/behind_a_proxy/tutorial004.py!}
+{!../../docs_src/behind_a_proxy/tutorial004.py!}
```
这样,就不会在 OpenAPI 概图中包含服务器了。
diff --git a/docs/zh/docs/advanced/custom-response.md b/docs/zh/docs/advanced/custom-response.md
index 9594c72ac..85ca1d06d 100644
--- a/docs/zh/docs/advanced/custom-response.md
+++ b/docs/zh/docs/advanced/custom-response.md
@@ -12,7 +12,7 @@
并且如果该 `Response` 有一个 JSON 媒体类型(`application/json`),比如使用 `JSONResponse` 或者 `UJSONResponse` 的时候,返回的数据将使用你在路径操作装饰器中声明的任何 Pydantic 的 `response_model` 自动转换(和过滤)。
-/// note | "说明"
+/// note | 说明
如果你使用不带有任何媒体类型的响应类,FastAPI 认为你的响应没有任何内容,所以不会在生成的OpenAPI文档中记录响应格式。
@@ -25,10 +25,10 @@
导入你想要使用的 `Response` 类(子类)然后在 *路径操作装饰器* 中声明它。
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001b.py!}
+{!../../docs_src/custom_response/tutorial001b.py!}
```
-/// info | "提示"
+/// info | 提示
参数 `response_class` 也会用来定义响应的「媒体类型」。
@@ -38,7 +38,7 @@
///
-/// tip | "小贴士"
+/// tip | 小贴士
`ORJSONResponse` 目前只在 FastAPI 中可用,而在 Starlette 中不可用。
@@ -52,10 +52,10 @@
* 将 `HTMLResponse` 作为你的 *路径操作* 的 `response_class` 参数传入。
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial002.py!}
+{!../../docs_src/custom_response/tutorial002.py!}
```
-/// info | "提示"
+/// info | 提示
参数 `response_class` 也会用来定义响应的「媒体类型」。
@@ -72,16 +72,16 @@
和上面一样的例子,返回一个 `HTMLResponse` 看起来可能是这样:
```Python hl_lines="2 7 19"
-{!../../../docs_src/custom_response/tutorial003.py!}
+{!../../docs_src/custom_response/tutorial003.py!}
```
-/// warning | "警告"
+/// warning | 警告
*路径操作函数* 直接返回的 `Response` 不会被 OpenAPI 的文档记录(比如,`Content-Type` 不会被文档记录),并且在自动化交互文档中也是不可见的。
///
-/// info | "提示"
+/// info | 提示
当然,实际的 `Content-Type` 头,状态码等等,将来自于你返回的 `Response` 对象。
@@ -98,7 +98,7 @@
比如像这样:
```Python hl_lines="7 23 21"
-{!../../../docs_src/custom_response/tutorial004.py!}
+{!../../docs_src/custom_response/tutorial004.py!}
```
在这个例子中,函数 `generate_html_response()` 已经生成并返回 `Response` 对象而不是在 `str` 中返回 HTML。
@@ -115,7 +115,7 @@
要记得你可以使用 `Response` 来返回任何其他东西,甚至创建一个自定义的子类。
-/// note | "技术细节"
+/// note | 技术细节
你也可以使用 `from starlette.responses import HTMLResponse`。
@@ -140,7 +140,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
+{!../../docs_src/response_directly/tutorial002.py!}
```
### `HTMLResponse`
@@ -152,7 +152,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
接受文本或字节并返回纯文本响应。
```Python hl_lines="2 7 9"
-{!../../../docs_src/custom_response/tutorial005.py!}
+{!../../docs_src/custom_response/tutorial005.py!}
```
### `JSONResponse`
@@ -170,17 +170,17 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
`UJSONResponse` 是一个使用 `ujson` 的可选 JSON 响应。
-/// warning | "警告"
+/// warning | 警告
在处理某些边缘情况时,`ujson` 不如 Python 的内置实现那么谨慎。
///
```Python hl_lines="2 7"
-{!../../../docs_src/custom_response/tutorial001.py!}
+{!../../docs_src/custom_response/tutorial001.py!}
```
-/// tip | "小贴士"
+/// tip | 小贴士
`ORJSONResponse` 可能是一个更快的选择。
@@ -191,7 +191,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。
```Python hl_lines="2 9"
-{!../../../docs_src/custom_response/tutorial006.py!}
+{!../../docs_src/custom_response/tutorial006.py!}
```
### `StreamingResponse`
@@ -199,7 +199,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。
```Python hl_lines="2 14"
-{!../../../docs_src/custom_response/tutorial007.py!}
+{!../../docs_src/custom_response/tutorial007.py!}
```
#### 对类似文件的对象使用 `StreamingResponse`
@@ -209,10 +209,10 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
包括许多与云存储,视频处理等交互的库。
```Python hl_lines="2 10-12 14"
-{!../../../docs_src/custom_response/tutorial008.py!}
+{!../../docs_src/custom_response/tutorial008.py!}
```
-/// tip | "小贴士"
+/// tip | 小贴士
注意在这里,因为我们使用的是不支持 `async` 和 `await` 的标准 `open()`,我们使用普通的 `def` 声明了路径操作。
@@ -232,7 +232,7 @@ FastAPI(实际上是 Starlette)将自动包含 Content-Length 的头。它
文件响应将包含适当的 `Content-Length`,`Last-Modified` 和 `ETag` 的响应头。
```Python hl_lines="2 10"
-{!../../../docs_src/custom_response/tutorial009.py!}
+{!../../docs_src/custom_response/tutorial009.py!}
```
## 额外文档
diff --git a/docs/zh/docs/advanced/dataclasses.md b/docs/zh/docs/advanced/dataclasses.md
index 72567e245..7d977a0c7 100644
--- a/docs/zh/docs/advanced/dataclasses.md
+++ b/docs/zh/docs/advanced/dataclasses.md
@@ -5,7 +5,7 @@ FastAPI 基于 **Pydantic** 构建,前文已经介绍过如何使用 Pydantic
但 FastAPI 还可以使用数据类(`dataclasses`):
```Python hl_lines="1 7-12 19-20"
-{!../../../docs_src/dataclasses/tutorial001.py!}
+{!../../docs_src/dataclasses/tutorial001.py!}
```
这还是借助于 **Pydantic** 及其内置的 `dataclasses`。
@@ -20,7 +20,7 @@ FastAPI 基于 **Pydantic** 构建,前文已经介绍过如何使用 Pydantic
数据类的和运作方式与 Pydantic 模型相同。实际上,它的底层使用的也是 Pydantic。
-/// info | "说明"
+/// info | 说明
注意,数据类不支持 Pydantic 模型的所有功能。
@@ -35,7 +35,7 @@ FastAPI 基于 **Pydantic** 构建,前文已经介绍过如何使用 Pydantic
在 `response_model` 参数中使用 `dataclasses`:
```Python hl_lines="1 7-13 19"
-{!../../../docs_src/dataclasses/tutorial002.py!}
+{!../../docs_src/dataclasses/tutorial002.py!}
```
本例把数据类自动转换为 Pydantic 数据类。
@@ -53,7 +53,7 @@ API 文档中也会显示相关概图:
本例把标准的 `dataclasses` 直接替换为 `pydantic.dataclasses`:
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
-{!../../../docs_src/dataclasses/tutorial003.py!}
+{!../../docs_src/dataclasses/tutorial003.py!}
```
1. 本例依然要从标准的 `dataclasses` 中导入 `field`;
diff --git a/docs/zh/docs/advanced/events.md b/docs/zh/docs/advanced/events.md
index c9389f533..a34c03f3f 100644
--- a/docs/zh/docs/advanced/events.md
+++ b/docs/zh/docs/advanced/events.md
@@ -4,7 +4,7 @@
事件函数既可以声明为异步函数(`async def`),也可以声明为普通函数(`def`)。
-/// warning | "警告"
+/// warning | 警告
**FastAPI** 只执行主应用中的事件处理器,不执行[子应用 - 挂载](sub-applications.md){.internal-link target=_blank}中的事件处理器。
@@ -15,7 +15,7 @@
使用 `startup` 事件声明 `app` 启动前运行的函数:
```Python hl_lines="8"
-{!../../../docs_src/events/tutorial001.py!}
+{!../../docs_src/events/tutorial001.py!}
```
本例中,`startup` 事件处理器函数为项目数据库(只是**字典**)提供了一些初始值。
@@ -29,18 +29,18 @@
使用 `shutdown` 事件声明 `app` 关闭时运行的函数:
```Python hl_lines="6"
-{!../../../docs_src/events/tutorial002.py!}
+{!../../docs_src/events/tutorial002.py!}
```
此处,`shutdown` 事件处理器函数在 `log.txt` 中写入一行文本 `Application shutdown`。
-/// info | "说明"
+/// info | 说明
`open()` 函数中,`mode="a"` 指的是**追加**。因此这行文本会添加在文件已有内容之后,不会覆盖之前的内容。
///
-/// tip | "提示"
+/// tip | 提示
注意,本例使用 Python `open()` 标准函数与文件交互。
@@ -52,7 +52,7 @@
///
-/// info | "说明"
+/// info | 说明
有关事件处理器的详情,请参阅 Starlette 官档 - 事件。
diff --git a/docs/zh/docs/advanced/generate-clients.md b/docs/zh/docs/advanced/generate-clients.md
index 56aad3bd2..baf131361 100644
--- a/docs/zh/docs/advanced/generate-clients.md
+++ b/docs/zh/docs/advanced/generate-clients.md
@@ -19,7 +19,7 @@
//// tab | Python 3.9+
```Python hl_lines="7-9 12-13 16-17 21"
-{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial001_py39.py!}
```
////
@@ -27,7 +27,7 @@
//// tab | Python 3.8+
```Python hl_lines="9-11 14-15 18 19 23"
-{!> ../../../docs_src/generate_clients/tutorial001.py!}
+{!> ../../docs_src/generate_clients/tutorial001.py!}
```
////
@@ -138,7 +138,7 @@ frontend-app@1.0.0 generate-client /home/user/code/frontend-app
//// tab | Python 3.9+
```Python hl_lines="21 26 34"
-{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial002_py39.py!}
```
////
@@ -146,7 +146,7 @@ frontend-app@1.0.0 generate-client /home/user/code/frontend-app
//// tab | Python 3.8+
```Python hl_lines="23 28 36"
-{!> ../../../docs_src/generate_clients/tutorial002.py!}
+{!> ../../docs_src/generate_clients/tutorial002.py!}
```
////
@@ -199,7 +199,7 @@ FastAPI为每个*路径操作*使用一个**唯一ID**,它用于**操作ID**
//// tab | Python 3.9+
```Python hl_lines="6-7 10"
-{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
+{!> ../../docs_src/generate_clients/tutorial003_py39.py!}
```
////
@@ -207,7 +207,7 @@ FastAPI为每个*路径操作*使用一个**唯一ID**,它用于**操作ID**
//// tab | Python 3.8+
```Python hl_lines="8-9 12"
-{!> ../../../docs_src/generate_clients/tutorial003.py!}
+{!> ../../docs_src/generate_clients/tutorial003.py!}
```
////
@@ -233,7 +233,7 @@ FastAPI为每个*路径操作*使用一个**唯一ID**,它用于**操作ID**
我们可以将 OpenAPI JSON 下载到一个名为`openapi.json`的文件中,然后使用以下脚本**删除此前缀的标签**:
```Python
-{!../../../docs_src/generate_clients/tutorial004.py!}
+{!../../docs_src/generate_clients/tutorial004.py!}
```
通过这样做,操作ID将从类似于 `items-get_items` 的名称重命名为 `get_items` ,这样客户端生成器就可以生成更简洁的方法名称。
diff --git a/docs/zh/docs/advanced/middleware.md b/docs/zh/docs/advanced/middleware.md
index 926082b94..78a7d559c 100644
--- a/docs/zh/docs/advanced/middleware.md
+++ b/docs/zh/docs/advanced/middleware.md
@@ -43,7 +43,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
**FastAPI** 为常见用例提供了一些中间件,下面介绍怎么使用这些中间件。
-/// note | "技术细节"
+/// note | 技术细节
以下几个示例中也可以使用 `from starlette.middleware.something import SomethingMiddleware`。
@@ -58,7 +58,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
任何传向 `http` 或 `ws` 的请求都会被重定向至安全方案。
```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial001.py!}
+{!../../docs_src/advanced_middleware/tutorial001.py!}
```
## `TrustedHostMiddleware`
@@ -66,7 +66,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
强制所有传入请求都必须正确设置 `Host` 请求头,以防 HTTP 主机头攻击。
```Python hl_lines="2 6-8"
-{!../../../docs_src/advanced_middleware/tutorial002.py!}
+{!../../docs_src/advanced_middleware/tutorial002.py!}
```
支持以下参数:
@@ -82,7 +82,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
中间件会处理标准响应与流响应。
```Python hl_lines="2 6"
-{!../../../docs_src/advanced_middleware/tutorial003.py!}
+{!../../docs_src/advanced_middleware/tutorial003.py!}
```
支持以下参数:
diff --git a/docs/zh/docs/advanced/openapi-callbacks.md b/docs/zh/docs/advanced/openapi-callbacks.md
index 7c7323cb5..601cbdb5d 100644
--- a/docs/zh/docs/advanced/openapi-callbacks.md
+++ b/docs/zh/docs/advanced/openapi-callbacks.md
@@ -32,10 +32,10 @@ API 的用户 (外部开发者)要在您的 API 内使用 POST 请求创建
这部分代码很常规,您对绝大多数代码应该都比较熟悉了:
```Python hl_lines="10-14 37-54"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
-/// tip | "提示"
+/// tip | 提示
`callback_url` 查询参数使用 Pydantic 的 URL 类型。
@@ -64,7 +64,7 @@ requests.post(callback_url, json={"description": "Invoice paid", "paid": True})
本例没有实现回调本身(只是一行代码),只有文档部分。
-/// tip | "提示"
+/// tip | 提示
实际的回调只是 HTTP 请求。
@@ -80,7 +80,7 @@ requests.post(callback_url, json={"description": "Invoice paid", "paid": True})
我们要使用与存档*外部 API* 相同的知识……通过创建外部 API 要实现的*路径操作*(您的 API 要调用的)。
-/// tip | "提示"
+/// tip | 提示
编写存档回调的代码时,假设您是*外部开发者*可能会用的上。并且您当前正在实现的是*外部 API*,不是*您自己的 API*。
@@ -93,7 +93,7 @@ requests.post(callback_url, json={"description": "Invoice paid", "paid": True})
首先,新建包含一些用于回调的 `APIRouter`。
```Python hl_lines="5 26"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
### 创建回调*路径操作*
@@ -106,7 +106,7 @@ requests.post(callback_url, json={"description": "Invoice paid", "paid": True})
* 还要声明要返回的响应,例如,`response_model=InvoiceEventReceived`
```Python hl_lines="17-19 22-23 29-33"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
回调*路径操作*与常规*路径操作*有两点主要区别:
@@ -163,7 +163,7 @@ JSON 请求体包含如下内容:
}
```
-/// tip | "提示"
+/// tip | 提示
注意,回调 URL包含 `callback_url` (`https://www.external.org/events`)中的查询参数,还有 JSON 请求体内部的发票 ID(`2expen51ve`)。
@@ -176,10 +176,10 @@ JSON 请求体包含如下内容:
现在使用 API *路径操作装饰器*的参数 `callbacks`,从回调路由传递属性 `.routes`(实际上只是路由/路径操作的**列表**):
```Python hl_lines="36"
-{!../../../docs_src/openapi_callbacks/tutorial001.py!}
+{!../../docs_src/openapi_callbacks/tutorial001.py!}
```
-/// tip | "提示"
+/// tip | 提示
注意,不能把路由本身(`invoices_callback_router`)传递给 `callback=`,要传递 `invoices_callback_router.routes` 中的 `.routes` 属性。
diff --git a/docs/zh/docs/advanced/path-operation-advanced-configuration.md b/docs/zh/docs/advanced/path-operation-advanced-configuration.md
index c37846916..0d77dd69e 100644
--- a/docs/zh/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/zh/docs/advanced/path-operation-advanced-configuration.md
@@ -13,7 +13,7 @@
务必确保每个操作路径的 `operation_id` 都是唯一的。
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### 使用 *路径操作函数* 的函数名作为 operationId
@@ -23,7 +23,7 @@
你应该在添加了所有 *路径操作* 之后执行此操作。
```Python hl_lines="2 12 13 14 15 16 17 18 19 20 21 24"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
/// tip
@@ -45,7 +45,7 @@
使用参数 `include_in_schema` 并将其设置为 `False` ,来从生成的 OpenAPI 方案中排除一个 *路径操作*(这样一来,就从自动化文档系统中排除掉了)。
```Python hl_lines="6"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## docstring 的高级描述
@@ -58,5 +58,5 @@
```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
-{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
+{!../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```
diff --git a/docs/zh/docs/advanced/response-change-status-code.md b/docs/zh/docs/advanced/response-change-status-code.md
index a289cf201..c38f80f1f 100644
--- a/docs/zh/docs/advanced/response-change-status-code.md
+++ b/docs/zh/docs/advanced/response-change-status-code.md
@@ -21,7 +21,7 @@
然后你可以在这个*临时*响应对象中设置`status_code`。
```Python hl_lines="1 9 12"
-{!../../../docs_src/response_change_status_code/tutorial001.py!}
+{!../../docs_src/response_change_status_code/tutorial001.py!}
```
然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。
diff --git a/docs/zh/docs/advanced/response-cookies.md b/docs/zh/docs/advanced/response-cookies.md
index dd942a981..2d56c6e9b 100644
--- a/docs/zh/docs/advanced/response-cookies.md
+++ b/docs/zh/docs/advanced/response-cookies.md
@@ -5,7 +5,7 @@
你可以在 *路径函数* 中定义一个类型为 `Response`的参数,这样你就可以在这个临时响应对象中设置cookie了。
```Python hl_lines="1 8-9"
-{!../../../docs_src/response_cookies/tutorial002.py!}
+{!../../docs_src/response_cookies/tutorial002.py!}
```
而且你还可以根据你的需要响应不同的对象,比如常用的 `dict`,数据库model等。
@@ -25,7 +25,7 @@
然后设置Cookies,并返回:
```Python hl_lines="10-12"
-{!../../../docs_src/response_cookies/tutorial001.py!}
+{!../../docs_src/response_cookies/tutorial001.py!}
```
/// tip
@@ -40,7 +40,7 @@
### 更多信息
-/// note | "技术细节"
+/// note | 技术细节
你也可以使用`from starlette.responses import Response` 或者 `from starlette.responses import JSONResponse`。
diff --git a/docs/zh/docs/advanced/response-directly.md b/docs/zh/docs/advanced/response-directly.md
index b2c7de8fd..934f60ef6 100644
--- a/docs/zh/docs/advanced/response-directly.md
+++ b/docs/zh/docs/advanced/response-directly.md
@@ -14,7 +14,7 @@
事实上,你可以返回任意 `Response` 或者任意 `Response` 的子类。
-/// tip | "小贴士"
+/// tip | 小贴士
`JSONResponse` 本身是一个 `Response` 的子类。
@@ -36,10 +36,10 @@
```Python hl_lines="4 6 20 21"
-{!../../../docs_src/response_directly/tutorial001.py!}
+{!../../docs_src/response_directly/tutorial001.py!}
```
-/// note | "技术细节"
+/// note | 技术细节
你也可以使用 `from starlette.responses import JSONResponse`。
@@ -58,7 +58,7 @@
你可以把你的 XML 内容放到一个字符串中,放到一个 `Response` 中,然后返回。
```Python hl_lines="1 18"
-{!../../../docs_src/response_directly/tutorial002.py!}
+{!../../docs_src/response_directly/tutorial002.py!}
```
## 说明
diff --git a/docs/zh/docs/advanced/response-headers.md b/docs/zh/docs/advanced/response-headers.md
index e18d1620d..e7861ad0c 100644
--- a/docs/zh/docs/advanced/response-headers.md
+++ b/docs/zh/docs/advanced/response-headers.md
@@ -6,7 +6,7 @@
然后你可以在这个*临时*响应对象中设置头部。
```Python hl_lines="1 7-8"
-{!../../../docs_src/response_headers/tutorial002.py!}
+{!../../docs_src/response_headers/tutorial002.py!}
```
然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。
@@ -21,11 +21,11 @@
按照[直接返回响应](response-directly.md){.internal-link target=_blank}中所述创建响应,并将头部作为附加参数传递:
```Python hl_lines="10-12"
-{!../../../docs_src/response_headers/tutorial001.py!}
+{!../../docs_src/response_headers/tutorial001.py!}
```
-/// note | "技术细节"
+/// note | 技术细节
你也可以使用`from starlette.responses import Response`或`from starlette.responses import JSONResponse`。
diff --git a/docs/zh/docs/advanced/security/http-basic-auth.md b/docs/zh/docs/advanced/security/http-basic-auth.md
index a76353186..06c6dbbab 100644
--- a/docs/zh/docs/advanced/security/http-basic-auth.md
+++ b/docs/zh/docs/advanced/security/http-basic-auth.md
@@ -23,7 +23,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。
//// tab | Python 3.9+
```Python hl_lines="4 8 12"
-{!> ../../../docs_src/security/tutorial006_an_py39.py!}
+{!> ../../docs_src/security/tutorial006_an_py39.py!}
```
////
@@ -31,7 +31,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。
//// tab | Python 3.8+
```Python hl_lines="2 7 11"
-{!> ../../../docs_src/security/tutorial006_an.py!}
+{!> ../../docs_src/security/tutorial006_an.py!}
```
////
@@ -45,7 +45,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。
///
```Python hl_lines="2 6 10"
-{!> ../../../docs_src/security/tutorial006.py!}
+{!> ../../docs_src/security/tutorial006.py!}
```
////
@@ -71,7 +71,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。
//// tab | Python 3.9+
```Python hl_lines="1 12-24"
-{!> ../../../docs_src/security/tutorial007_an_py39.py!}
+{!> ../../docs_src/security/tutorial007_an_py39.py!}
```
////
@@ -79,7 +79,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。
//// tab | Python 3.8+
```Python hl_lines="1 12-24"
-{!> ../../../docs_src/security/tutorial007_an.py!}
+{!> ../../docs_src/security/tutorial007_an.py!}
```
////
@@ -93,7 +93,7 @@ HTTP 基础授权让浏览器显示内置的用户名与密码提示。
///
```Python hl_lines="1 11-21"
-{!> ../../../docs_src/security/tutorial007.py!}
+{!> ../../docs_src/security/tutorial007.py!}
```
////
@@ -163,7 +163,7 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
//// tab | Python 3.9+
```Python hl_lines="26-30"
-{!> ../../../docs_src/security/tutorial007_an_py39.py!}
+{!> ../../docs_src/security/tutorial007_an_py39.py!}
```
////
@@ -171,7 +171,7 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
//// tab | Python 3.8+
```Python hl_lines="26-30"
-{!> ../../../docs_src/security/tutorial007_an.py!}
+{!> ../../docs_src/security/tutorial007_an.py!}
```
////
@@ -185,7 +185,7 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
///
```Python hl_lines="23-27"
-{!> ../../../docs_src/security/tutorial007.py!}
+{!> ../../docs_src/security/tutorial007.py!}
```
////
diff --git a/docs/zh/docs/advanced/security/index.md b/docs/zh/docs/advanced/security/index.md
index 836086ae2..267e7ced7 100644
--- a/docs/zh/docs/advanced/security/index.md
+++ b/docs/zh/docs/advanced/security/index.md
@@ -4,7 +4,7 @@
除 [教程 - 用户指南: 安全性](../../tutorial/security/index.md){.internal-link target=_blank} 中涵盖的功能之外,还有一些额外的功能来处理安全性.
-/// tip | "小贴士"
+/// tip | 小贴士
接下来的章节 **并不一定是 "高级的"**.
diff --git a/docs/zh/docs/advanced/security/oauth2-scopes.md b/docs/zh/docs/advanced/security/oauth2-scopes.md
index b75ae11a4..b26522113 100644
--- a/docs/zh/docs/advanced/security/oauth2-scopes.md
+++ b/docs/zh/docs/advanced/security/oauth2-scopes.md
@@ -10,7 +10,7 @@ OAuth2 也是脸书、谷歌、GitHub、微软、推特等第三方身份验证
本章介绍如何在 **FastAPI** 应用中使用 OAuth2 作用域管理验证与授权。
-/// warning | "警告"
+/// warning | 警告
本章内容较难,刚接触 FastAPI 的新手可以跳过。
@@ -46,7 +46,7 @@ OpenAPI 中(例如 API 文档)可以定义**安全方案**。
* 脸书和 Instagram 使用 `instagram_basic`
* 谷歌使用 `https://www.googleapis.com/auth/drive`
-/// info | "说明"
+/// info | 说明
OAuth2 中,**作用域**只是声明特定权限的字符串。
@@ -63,7 +63,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
首先,快速浏览一下以下代码与**用户指南**中 [OAuth2 实现密码哈希与 Bearer JWT 令牌验证](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}一章中代码的区别。以下代码使用 OAuth2 作用域:
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 153"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
下面,我们逐步说明修改的代码内容。
@@ -75,7 +75,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
`scopes` 参数接收**字典**,键是作用域、值是作用域的描述:
```Python hl_lines="62-65"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
因为声明了作用域,所以登录或授权时会在 API 文档中显示。
@@ -94,7 +94,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
这样,返回的 JWT 令牌中就包含了作用域。
-/// danger | "危险"
+/// danger | 危险
为了简明起见,本例把接收的作用域直接添加到了令牌里。
@@ -103,7 +103,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
///
```Python hl_lines="153"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 在*路径操作*与依赖项中声明作用域
@@ -122,7 +122,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
本例要求使用作用域 `me`(还可以使用更多作用域)。
-/// note | "笔记"
+/// note | 笔记
不必在不同位置添加不同的作用域。
@@ -131,10 +131,10 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
///
```Python hl_lines="4 139 166"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
-/// info | "技术细节"
+/// info | 技术细节
`Security` 实际上是 `Depends` 的子类,而且只比 `Depends` 多一个参数。
@@ -159,7 +159,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
`SecuriScopes` 类与 `Request` 类似(`Request` 用于直接提取请求对象)。
```Python hl_lines="8 105"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 使用 `scopes`
@@ -175,7 +175,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
该异常包含了作用域所需的(如有),以空格分割的字符串(使用 `scope_str`)。该字符串要放到包含作用域的 `WWW-Authenticate` 请求头中(这也是规范的要求)。
```Python hl_lines="105 107-115"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 校验 `username` 与数据形状
@@ -193,7 +193,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
还可以使用用户名验证用户,如果没有用户,也会触发之前创建的异常。
```Python hl_lines="46 116-127"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 校验 `scopes`
@@ -203,7 +203,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
为此,要使用包含所有作用域**字符串列表**的 `security_scopes.scopes`, 。
```Python hl_lines="128-134"
-{!../../../docs_src/security/tutorial005.py!}
+{!../../docs_src/security/tutorial005.py!}
```
## 依赖项树与作用域
@@ -231,7 +231,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
* `security_scopes.scopes` 包含*路径操作* `read_users_me` 的 `["me"]`,因为它在依赖项里被声明
* `security_scopes.scopes` 包含用于*路径操作* `read_system_status` 的 `[]`(空列表),并且它的依赖项 `get_current_user` 也没有声明任何 `scope`
-/// tip | "提示"
+/// tip | 提示
此处重要且**神奇**的事情是,`get_current_user` 检查每个*路径操作*时可以使用不同的 `scopes` 列表。
@@ -275,7 +275,7 @@ OAuth2 中,**作用域**只是声明特定权限的字符串。
最安全的是代码流,但实现起来更复杂,而且需要更多步骤。因为它更复杂,很多第三方身份验证应用最终建议使用隐式流。
-/// note | "笔记"
+/// note | 笔记
每个身份验证应用都会采用不同方式会命名流,以便融合入自己的品牌。
diff --git a/docs/zh/docs/advanced/settings.md b/docs/zh/docs/advanced/settings.md
index 37a2d98d3..4d35731cb 100644
--- a/docs/zh/docs/advanced/settings.md
+++ b/docs/zh/docs/advanced/settings.md
@@ -151,7 +151,7 @@ Hello World from Python
您可以使用与 Pydantic 模型相同的验证功能和工具,比如不同的数据类型和使用 `Field()` 进行附加验证。
```Python hl_lines="2 5-8 11"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
/// tip
@@ -169,7 +169,7 @@ Hello World from Python
然后,您可以在应用程序中使用新的 `settings` 对象:
```Python hl_lines="18-20"
-{!../../../docs_src/settings/tutorial001.py!}
+{!../../docs_src/settings/tutorial001.py!}
```
### 运行服务器
@@ -205,13 +205,13 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
例如,您可以创建一个名为 `config.py` 的文件,其中包含以下内容:
```Python
-{!../../../docs_src/settings/app01/config.py!}
+{!../../docs_src/settings/app01/config.py!}
```
然后在一个名为 `main.py` 的文件中使用它:
```Python hl_lines="3 11-13"
-{!../../../docs_src/settings/app01/main.py!}
+{!../../docs_src/settings/app01/main.py!}
```
/// tip
@@ -231,7 +231,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
根据前面的示例,您的 `config.py` 文件可能如下所示:
```Python hl_lines="10"
-{!../../../docs_src/settings/app02/config.py!}
+{!../../docs_src/settings/app02/config.py!}
```
请注意,现在我们不创建默认实例 `settings = Settings()`。
@@ -243,7 +243,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
//// tab | Python 3.9+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -251,7 +251,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
//// tab | Python 3.8+
```Python hl_lines="6 12-13"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
@@ -265,7 +265,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
///
```Python hl_lines="5 11-12"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -283,7 +283,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
//// tab | Python 3.9+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an_py39/main.py!}
+{!> ../../docs_src/settings/app02_an_py39/main.py!}
```
////
@@ -291,7 +291,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
//// tab | Python 3.8+
```Python hl_lines="17 19-21"
-{!> ../../../docs_src/settings/app02_an/main.py!}
+{!> ../../docs_src/settings/app02_an/main.py!}
```
////
@@ -305,7 +305,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
///
```Python hl_lines="16 18-20"
-{!> ../../../docs_src/settings/app02/main.py!}
+{!> ../../docs_src/settings/app02/main.py!}
```
////
@@ -315,7 +315,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
然后,在测试期间,通过创建 `get_settings` 的依赖项覆盖,很容易提供一个不同的设置对象:
```Python hl_lines="9-10 13 21"
-{!../../../docs_src/settings/app02/test_main.py!}
+{!../../docs_src/settings/app02/test_main.py!}
```
在依赖项覆盖中,我们在创建新的 `Settings` 对象时为 `admin_email` 设置了一个新值,然后返回该新对象。
@@ -358,7 +358,7 @@ APP_NAME="ChimichangApp"
然后,您可以使用以下方式更新您的 `config.py`:
```Python hl_lines="9-10"
-{!../../../docs_src/settings/app03/config.py!}
+{!../../docs_src/settings/app03/config.py!}
```
在这里,我们在 Pydantic 的 `Settings` 类中创建了一个名为 `Config` 的类,并将 `env_file` 设置为我们想要使用的 dotenv 文件的文件名。
@@ -395,7 +395,7 @@ def get_settings():
//// tab | Python 3.9+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an_py39/main.py!}
+{!> ../../docs_src/settings/app03_an_py39/main.py!}
```
////
@@ -403,7 +403,7 @@ def get_settings():
//// tab | Python 3.8+
```Python hl_lines="1 11"
-{!> ../../../docs_src/settings/app03_an/main.py!}
+{!> ../../docs_src/settings/app03_an/main.py!}
```
////
@@ -417,7 +417,7 @@ def get_settings():
///
```Python hl_lines="1 10"
-{!> ../../../docs_src/settings/app03/main.py!}
+{!> ../../docs_src/settings/app03/main.py!}
```
////
diff --git a/docs/zh/docs/advanced/sub-applications.md b/docs/zh/docs/advanced/sub-applications.md
index a26301b50..f93ab1d24 100644
--- a/docs/zh/docs/advanced/sub-applications.md
+++ b/docs/zh/docs/advanced/sub-applications.md
@@ -11,7 +11,7 @@
首先,创建主(顶层)**FastAPI** 应用及其*路径操作*:
```Python hl_lines="3 6-8"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### 子应用
@@ -21,7 +21,7 @@
子应用只是另一个标准 FastAPI 应用,但这个应用是被**挂载**的应用:
```Python hl_lines="11 14-16"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### 挂载子应用
@@ -31,7 +31,7 @@
本例的子应用挂载在 `/subapi` 路径下:
```Python hl_lines="11 19"
-{!../../../docs_src/sub_applications/tutorial001.py!}
+{!../../docs_src/sub_applications/tutorial001.py!}
```
### 查看文档
diff --git a/docs/zh/docs/advanced/templates.md b/docs/zh/docs/advanced/templates.md
index b09644e39..7692aa47b 100644
--- a/docs/zh/docs/advanced/templates.md
+++ b/docs/zh/docs/advanced/templates.md
@@ -28,23 +28,23 @@ $ pip install jinja2
* 使用 `templates` 渲染并返回 `TemplateResponse`, 传递模板的名称、request对象以及一个包含多个键值对(用于Jinja2模板)的"context"字典,
```Python hl_lines="4 11 15-16"
-{!../../../docs_src/templates/tutorial001.py!}
+{!../../docs_src/templates/tutorial001.py!}
```
-/// note | "笔记"
+/// note | 笔记
在FastAPI 0.108.0,Starlette 0.29.0之前,`name`是第一个参数。
并且,在此之前,`request`对象是作为context的一部分以键值对的形式传递的。
///
-/// tip | "提示"
+/// tip | 提示
通过声明 `response_class=HTMLResponse`,API 文档就能识别响应的对象是 HTML。
///
-/// note | "技术细节"
+/// note | 技术细节
您还可以使用 `from starlette.templating import Jinja2Templates`。
@@ -57,7 +57,7 @@ $ pip install jinja2
编写模板 `templates/item.html`,代码如下:
```jinja hl_lines="7"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
### 模板上下文
@@ -111,13 +111,13 @@ Item ID: 42
你还可以在模板内部将 `url_for()`用于静态文件,例如你挂载的 `name="static"`的 `StaticFiles`。
```jinja hl_lines="4"
-{!../../../docs_src/templates/templates/item.html!}
+{!../../docs_src/templates/templates/item.html!}
```
本例中,它将链接到 `static/styles.css`中的CSS文件:
```CSS hl_lines="4"
-{!../../../docs_src/templates/static/styles.css!}
+{!../../docs_src/templates/static/styles.css!}
```
因为使用了 `StaticFiles`, **FastAPI** 应用会自动提供位于 URL `/static/styles.css`的 CSS 文件。
diff --git a/docs/zh/docs/advanced/testing-database.md b/docs/zh/docs/advanced/testing-database.md
deleted file mode 100644
index 58bf9af8c..000000000
--- a/docs/zh/docs/advanced/testing-database.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# 测试数据库
-
-您还可以使用[测试依赖项](testing-dependencies.md){.internal-link target=_blank}中的覆盖依赖项方法变更测试的数据库。
-
-实现设置其它测试数据库、在测试后回滚数据、或预填测试数据等操作。
-
-本章的主要思路与上一章完全相同。
-
-## 为 SQL 应用添加测试
-
-为了使用测试数据库,我们要升级 [SQL 关系型数据库](../tutorial/sql-databases.md){.internal-link target=_blank} 一章中的示例。
-
-应用的所有代码都一样,直接查看那一章的示例代码即可。
-
-本章只是新添加了测试文件。
-
-正常的依赖项 `get_db()` 返回数据库会话。
-
-测试时使用覆盖依赖项返回自定义数据库会话代替正常的依赖项。
-
-本例中,要创建仅用于测试的临时数据库。
-
-## 文件架构
-
-创建新文件 `sql_app/tests/test_sql_app.py`。
-
-因此,新的文件架构如下:
-
-``` hl_lines="9-11"
-.
-└── sql_app
- ├── __init__.py
- ├── crud.py
- ├── database.py
- ├── main.py
- ├── models.py
- ├── schemas.py
- └── tests
- ├── __init__.py
- └── test_sql_app.py
-```
-
-## 创建新的数据库会话
-
-首先,为新建数据库创建新的数据库会话。
-
-测试时,使用 `test.db` 替代 `sql_app.db`。
-
-但其余的会话代码基本上都是一样的,只要复制就可以了。
-
-```Python hl_lines="8-13"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-/// tip | "提示"
-
-为减少代码重复,最好把这段代码写成函数,在 `database.py` 与 `tests/test_sql_app.py`中使用。
-
-为了把注意力集中在测试代码上,本例只是复制了这段代码。
-
-///
-
-## 创建数据库
-
-因为现在是想在新文件中使用新数据库,所以要使用以下代码创建数据库:
-
-```Python
-Base.metadata.create_all(bind=engine)
-```
-
-一般是在 `main.py` 中调用这行代码,但在 `main.py` 里,这行代码用于创建 `sql_app.db`,但是现在要为测试创建 `test.db`。
-
-因此,要在测试代码中添加这行代码创建新的数据库文件。
-
-```Python hl_lines="16"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-## 覆盖依赖项
-
-接下来,创建覆盖依赖项,并为应用添加覆盖内容。
-
-```Python hl_lines="19-24 27"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-/// tip | "提示"
-
-`overrider_get_db()` 与 `get_db` 的代码几乎完全一样,只是 `overrider_get_db` 中使用测试数据库的 `TestingSessionLocal`。
-
-///
-
-## 测试应用
-
-然后,就可以正常测试了。
-
-```Python hl_lines="32-47"
-{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
-```
-
-测试期间,所有在数据库中所做的修改都在 `test.db` 里,不会影响主应用的 `sql_app.db`。
diff --git a/docs/zh/docs/advanced/testing-dependencies.md b/docs/zh/docs/advanced/testing-dependencies.md
index cc9a38200..b4b5b32df 100644
--- a/docs/zh/docs/advanced/testing-dependencies.md
+++ b/docs/zh/docs/advanced/testing-dependencies.md
@@ -29,10 +29,10 @@
这样一来,**FastAPI** 就会调用覆盖依赖项,不再调用原依赖项。
```Python hl_lines="26-27 30"
-{!../../../docs_src/dependency_testing/tutorial001.py!}
+{!../../docs_src/dependency_testing/tutorial001.py!}
```
-/// tip | "提示"
+/// tip | 提示
**FastAPI** 应用中的任何位置都可以实现覆盖依赖项。
@@ -48,7 +48,7 @@ FastAPI 可以覆盖这些位置的依赖项。
app.dependency_overrides = {}
```
-/// tip | "提示"
+/// tip | 提示
如果只在某些测试时覆盖依赖项,您可以在测试开始时(在测试函数内)设置覆盖依赖项,并在结束时(在测试函数结尾)重置覆盖依赖项。
diff --git a/docs/zh/docs/advanced/testing-events.md b/docs/zh/docs/advanced/testing-events.md
index 222a67c8c..00e661cd2 100644
--- a/docs/zh/docs/advanced/testing-events.md
+++ b/docs/zh/docs/advanced/testing-events.md
@@ -3,5 +3,5 @@
使用 `TestClient` 和 `with` 语句,在测试中运行事件处理器(`startup` 与 `shutdown`)。
```Python hl_lines="9-12 20-24"
-{!../../../docs_src/app_testing/tutorial003.py!}
+{!../../docs_src/app_testing/tutorial003.py!}
```
diff --git a/docs/zh/docs/advanced/testing-websockets.md b/docs/zh/docs/advanced/testing-websockets.md
index 795b73945..b30939b97 100644
--- a/docs/zh/docs/advanced/testing-websockets.md
+++ b/docs/zh/docs/advanced/testing-websockets.md
@@ -5,10 +5,10 @@
为此,要在 `with` 语句中使用 `TestClient` 连接 WebSocket。
```Python hl_lines="27-31"
-{!../../../docs_src/app_testing/tutorial002.py!}
+{!../../docs_src/app_testing/tutorial002.py!}
```
-/// note | "笔记"
+/// note | 笔记
更多细节详见 Starlette 官档 - 测试 WebSockets。
diff --git a/docs/zh/docs/advanced/using-request-directly.md b/docs/zh/docs/advanced/using-request-directly.md
index bc9e898d9..f01644de6 100644
--- a/docs/zh/docs/advanced/using-request-directly.md
+++ b/docs/zh/docs/advanced/using-request-directly.md
@@ -30,12 +30,12 @@
此时,需要直接访问请求。
```Python hl_lines="1 7-8"
-{!../../../docs_src/using_request_directly/tutorial001.py!}
+{!../../docs_src/using_request_directly/tutorial001.py!}
```
把*路径操作函数*的参数类型声明为 `Request`,**FastAPI** 就能把 `Request` 传递到参数里。
-/// tip | "提示"
+/// tip | 提示
注意,本例除了声明请求参数之外,还声明了路径参数。
@@ -49,7 +49,7 @@
更多细节详见 Starlette 官档 - `Request` 对象。
-/// note | "技术细节"
+/// note | 技术细节
您也可以使用 `from starlette.requests import Request`。
diff --git a/docs/zh/docs/advanced/websockets.md b/docs/zh/docs/advanced/websockets.md
index 3fcc36dfe..dcd4cd5a9 100644
--- a/docs/zh/docs/advanced/websockets.md
+++ b/docs/zh/docs/advanced/websockets.md
@@ -35,7 +35,7 @@ $ pip install websockets
但这是一种专注于 WebSockets 的服务器端并提供一个工作示例的最简单方式:
```Python hl_lines="2 6-38 41-43"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
## 创建 `websocket`
@@ -43,10 +43,10 @@ $ pip install websockets
在您的 **FastAPI** 应用程序中,创建一个 `websocket`:
```Python hl_lines="1 46-47"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
-/// note | "技术细节"
+/// note | 技术细节
您也可以使用 `from starlette.websockets import WebSocket`。
@@ -59,7 +59,7 @@ $ pip install websockets
在您的 WebSocket 路由中,您可以使用 `await` 等待消息并发送消息。
```Python hl_lines="48-52"
-{!../../../docs_src/websockets/tutorial001.py!}
+{!../../docs_src/websockets/tutorial001.py!}
```
您可以接收和发送二进制、文本和 JSON 数据。
@@ -112,7 +112,7 @@ $ uvicorn main:app --reload
//// tab | Python 3.10+
```Python hl_lines="68-69 82"
-{!> ../../../docs_src/websockets/tutorial002_an_py310.py!}
+{!> ../../docs_src/websockets/tutorial002_an_py310.py!}
```
////
@@ -120,7 +120,7 @@ $ uvicorn main:app --reload
//// tab | Python 3.9+
```Python hl_lines="68-69 82"
-{!> ../../../docs_src/websockets/tutorial002_an_py39.py!}
+{!> ../../docs_src/websockets/tutorial002_an_py39.py!}
```
////
@@ -128,7 +128,7 @@ $ uvicorn main:app --reload
//// tab | Python 3.8+
```Python hl_lines="69-70 83"
-{!> ../../../docs_src/websockets/tutorial002_an.py!}
+{!> ../../docs_src/websockets/tutorial002_an.py!}
```
////
@@ -142,7 +142,7 @@ $ uvicorn main:app --reload
///
```Python hl_lines="66-67 79"
-{!> ../../../docs_src/websockets/tutorial002_py310.py!}
+{!> ../../docs_src/websockets/tutorial002_py310.py!}
```
////
@@ -156,7 +156,7 @@ $ uvicorn main:app --reload
///
```Python hl_lines="68-69 81"
-{!> ../../../docs_src/websockets/tutorial002.py!}
+{!> ../../docs_src/websockets/tutorial002.py!}
```
////
@@ -203,7 +203,7 @@ $ uvicorn main:app --reload
//// tab | Python 3.9+
```Python hl_lines="79-81"
-{!> ../../../docs_src/websockets/tutorial003_py39.py!}
+{!> ../../docs_src/websockets/tutorial003_py39.py!}
```
////
@@ -211,7 +211,7 @@ $ uvicorn main:app --reload
//// tab | Python 3.8+
```Python hl_lines="81-83"
-{!> ../../../docs_src/websockets/tutorial003.py!}
+{!> ../../docs_src/websockets/tutorial003.py!}
```
////
diff --git a/docs/zh/docs/advanced/wsgi.md b/docs/zh/docs/advanced/wsgi.md
index 179ec88aa..92bd998d0 100644
--- a/docs/zh/docs/advanced/wsgi.md
+++ b/docs/zh/docs/advanced/wsgi.md
@@ -13,7 +13,7 @@
之后将其挂载到某一个路径下。
```Python hl_lines="2-3 22"
-{!../../../docs_src/wsgi/tutorial001.py!}
+{!../../docs_src/wsgi/tutorial001.py!}
```
## 检查
diff --git a/docs/zh/docs/contributing.md b/docs/zh/docs/contributing.md
index 85b341a8d..cad093c2a 100644
--- a/docs/zh/docs/contributing.md
+++ b/docs/zh/docs/contributing.md
@@ -138,7 +138,7 @@ $ pip install -r requirements.txt
这样,你不必再去重新"安装"你的本地版本即可测试所有更改。
-/// note | "技术细节"
+/// note | 技术细节
仅当你使用此项目中的 `requirements.txt` 安装而不是直接使用 `pip install fastapi` 安装时,才会发生这种情况。
diff --git a/docs/zh/docs/environment-variables.md b/docs/zh/docs/environment-variables.md
new file mode 100644
index 000000000..812278051
--- /dev/null
+++ b/docs/zh/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# 环境变量
+
+/// tip
+
+如果你已经知道什么是“环境变量”并且知道如何使用它们,你可以放心跳过这一部分。
+
+///
+
+环境变量(也称为“**env var**”)是一个独立于 Python 代码**之外**的变量,它存在于**操作系统**中,可以被你的 Python 代码(或其他程序)读取。
+
+环境变量对于处理应用程序**设置**、作为 Python **安装**的一部分等方面非常有用。
+
+## 创建和使用环境变量
+
+你在 **shell(终端)**中就可以**创建**和使用环境变量,并不需要用到 Python:
+
+//// tab | Linux, macOS, Windows Bash
+
+
-/// tip | "提示"
+/// tip | 提示
使用 PyCharm 编辑器时,推荐安装 Pydantic PyCharm 插件。
@@ -170,7 +170,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
//// tab | Python 3.10+
```Python hl_lines="19"
-{!> ../../../docs_src/body/tutorial002_py310.py!}
+{!> ../../docs_src/body/tutorial002_py310.py!}
```
////
@@ -178,7 +178,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
//// tab | Python 3.8+
```Python hl_lines="21"
-{!> ../../../docs_src/body/tutorial002.py!}
+{!> ../../docs_src/body/tutorial002.py!}
```
////
@@ -192,7 +192,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
//// tab | Python 3.10+
```Python hl_lines="15-16"
-{!> ../../../docs_src/body/tutorial003_py310.py!}
+{!> ../../docs_src/body/tutorial003_py310.py!}
```
////
@@ -200,7 +200,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
//// tab | Python 3.8+
```Python hl_lines="17-18"
-{!> ../../../docs_src/body/tutorial003.py!}
+{!> ../../docs_src/body/tutorial003.py!}
```
////
@@ -214,7 +214,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
//// tab | Python 3.10+
```Python hl_lines="16"
-{!> ../../../docs_src/body/tutorial004_py310.py!}
+{!> ../../docs_src/body/tutorial004_py310.py!}
```
////
@@ -222,7 +222,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
//// tab | Python 3.8+
```Python hl_lines="18"
-{!> ../../../docs_src/body/tutorial004.py!}
+{!> ../../docs_src/body/tutorial004.py!}
```
////
@@ -233,7 +233,7 @@ Pydantic 模型的 JSON 概图是 OpenAPI 生成的概图部件,可在 API 文
- 类型是(`int`、`float`、`str`、`bool` 等)**单类型**的参数,是**查询**参数
- 类型是 **Pydantic 模型**的参数,是**请求体**
-/// note | "笔记"
+/// note | 笔记
因为默认值是 `None`, FastAPI 会把 `q` 当作可选参数。
diff --git a/docs/zh/docs/tutorial/cookie-params.md b/docs/zh/docs/tutorial/cookie-params.md
index 7ca77696e..762dca766 100644
--- a/docs/zh/docs/tutorial/cookie-params.md
+++ b/docs/zh/docs/tutorial/cookie-params.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.9+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -25,7 +25,7 @@
//// tab | Python 3.8+
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
@@ -39,7 +39,7 @@
///
```Python hl_lines="1"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
@@ -53,7 +53,7 @@
///
```Python hl_lines="3"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
@@ -68,7 +68,7 @@
//// tab | Python 3.10+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
////
@@ -76,7 +76,7 @@
//// tab | Python 3.9+
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
////
@@ -84,7 +84,7 @@
//// tab | Python 3.8+
```Python hl_lines="10"
-{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+{!> ../../docs_src/cookie_params/tutorial001_an.py!}
```
////
@@ -98,7 +98,7 @@
///
```Python hl_lines="7"
-{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
```
////
@@ -112,12 +112,12 @@
///
```Python hl_lines="9"
-{!> ../../../docs_src/cookie_params/tutorial001.py!}
+{!> ../../docs_src/cookie_params/tutorial001.py!}
```
////
-/// note | "技术细节"
+/// note | 技术细节
`Cookie` 、`Path` 、`Query` 是**兄弟类**,都继承自共用的 `Param` 类。
@@ -125,7 +125,7 @@
///
-/// info | "说明"
+/// info | 说明
必须使用 `Cookie` 声明 cookie 参数,否则该参数会被解释为查询参数。
diff --git a/docs/zh/docs/tutorial/cors.md b/docs/zh/docs/tutorial/cors.md
index de880f347..84c435c97 100644
--- a/docs/zh/docs/tutorial/cors.md
+++ b/docs/zh/docs/tutorial/cors.md
@@ -47,7 +47,7 @@
* 特定的 HTTP headers 或者使用通配符 `"*"` 允许所有 headers。
```Python hl_lines="2 6-11 13-19"
-{!../../../docs_src/cors/tutorial001.py!}
+{!../../docs_src/cors/tutorial001.py!}
```
默认情况下,这个 `CORSMiddleware` 实现所使用的默认参数较为保守,所以你需要显式地启用特定的源、方法或者 headers,以便浏览器能够在跨域上下文中使用它们。
@@ -78,7 +78,7 @@
更多关于 CORS 的信息,请查看 Mozilla CORS 文档。
-/// note | "技术细节"
+/// note | 技术细节
你也可以使用 `from starlette.middleware.cors import CORSMiddleware`。
diff --git a/docs/zh/docs/tutorial/debugging.md b/docs/zh/docs/tutorial/debugging.md
index 945094207..a5afa1aaa 100644
--- a/docs/zh/docs/tutorial/debugging.md
+++ b/docs/zh/docs/tutorial/debugging.md
@@ -7,7 +7,7 @@
在你的 FastAPI 应用中直接导入 `uvicorn` 并运行:
```Python hl_lines="1 15"
-{!../../../docs_src/debugging/tutorial001.py!}
+{!../../docs_src/debugging/tutorial001.py!}
```
### 关于 `__name__ == "__main__"`
diff --git a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
index 9932f90fc..917459d1d 100644
--- a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -9,7 +9,7 @@
//// tab | Python 3.10+
```Python hl_lines="7"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
@@ -17,7 +17,7 @@
//// tab | Python 3.8+
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -86,7 +86,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="9-13"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
@@ -94,7 +94,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.8+
```Python hl_lines="11-15"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -104,7 +104,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="10"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
@@ -112,7 +112,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="12"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -122,7 +122,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="6"
-{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
+{!> ../../docs_src/dependencies/tutorial001_py310.py!}
```
////
@@ -130,7 +130,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="9"
-{!> ../../../docs_src/dependencies/tutorial001.py!}
+{!> ../../docs_src/dependencies/tutorial001.py!}
```
////
@@ -152,7 +152,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.10+
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
+{!> ../../docs_src/dependencies/tutorial002_py310.py!}
```
////
@@ -160,7 +160,7 @@ fluffy = Cat(name="Mr Fluffy")
//// tab | Python 3.6+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial002.py!}
+{!> ../../docs_src/dependencies/tutorial002.py!}
```
////
@@ -206,7 +206,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.10+
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
+{!> ../../docs_src/dependencies/tutorial003_py310.py!}
```
////
@@ -214,7 +214,7 @@ commons = Depends(CommonQueryParams)
//// tab | Python 3.6+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial003.py!}
+{!> ../../docs_src/dependencies/tutorial003.py!}
```
////
@@ -254,7 +254,7 @@ commons: CommonQueryParams = Depends()
//// tab | Python 3.10+
```Python hl_lines="17"
-{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
+{!> ../../docs_src/dependencies/tutorial004_py310.py!}
```
////
@@ -262,7 +262,7 @@ commons: CommonQueryParams = Depends()
//// tab | Python 3.6+
```Python hl_lines="19"
-{!> ../../../docs_src/dependencies/tutorial004.py!}
+{!> ../../docs_src/dependencies/tutorial004.py!}
```
////
diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
index e6bbd47c1..c202c977b 100644
--- a/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
+++ b/docs/zh/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -15,12 +15,12 @@
该参数的值是由 `Depends()` 组成的 `list`:
```Python hl_lines="17"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
路径操作装饰器依赖项(以下简称为**“路径装饰器依赖项”**)的执行或解析方式和普通依赖项一样,但就算这些依赖项会返回值,它们的值也不会传递给*路径操作函数*。
-/// tip | "提示"
+/// tip | 提示
有些编辑器会检查代码中没使用过的函数参数,并显示错误提示。
@@ -30,7 +30,7 @@
///
-/// info | "说明"
+/// info | 说明
本例中,使用的是自定义响应头 `X-Key` 和 `X-Token`。
@@ -47,7 +47,7 @@
路径装饰器依赖项可以声明请求的需求项(比如响应头)或其他子依赖项:
```Python hl_lines="6 11"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
### 触发异常
@@ -55,7 +55,7 @@
路径装饰器依赖项与正常的依赖项一样,可以 `raise` 异常:
```Python hl_lines="8 13"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
### 返回值
@@ -65,7 +65,7 @@
因此,可以复用在其他位置使用过的、(能返回值的)普通依赖项,即使没有使用这个值,也会执行该依赖项:
```Python hl_lines="9 14"
-{!../../../docs_src/dependencies/tutorial006.py!}
+{!../../docs_src/dependencies/tutorial006.py!}
```
## 为一组路径操作定义依赖项
diff --git a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md
index 6058f7878..792b6784d 100644
--- a/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md
+++ b/docs/zh/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -10,7 +10,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial008_an_py39.py!}
```
////
@@ -85,7 +85,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008.py!}
+{!> ../../docs_src/dependencies/tutorial008.py!}
```
////
@@ -113,7 +113,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008_an.py!}
+{!> ../../docs_src/dependencies/tutorial008_an.py!}
```
////
@@ -135,7 +135,7 @@ FastAPI支持在完成后执行一些上下文管理器完成的。
@@ -173,7 +173,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008b_an.py!}
+{!> ../../docs_src/dependencies/tutorial008b_an.py!}
```
////
@@ -195,7 +195,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008c_an_py39.py!}
+{!> ../../docs_src/dependencies/tutorial008c_an_py39.py!}
```
////
@@ -217,7 +217,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008c.py!}
+{!> ../../docs_src/dependencies/tutorial008c.py!}
```
////
@@ -247,7 +247,7 @@ FastAPI支持在完成后执行一些 ../../../docs_src/dependencies/tutorial008d_an.py!}
+{!> ../../docs_src/dependencies/tutorial008d_an.py!}
```
////
@@ -269,7 +269,7 @@ FastAPI支持在完成后执行一些 Tuple[Dict[str, Any], List[Dict[str, Any]]]:
+def _should_embed_body_fields(fields: List[ModelField]) -> bool:
+ if not fields:
+ return False
+ # More than one dependency could have the same field, it would show up as multiple
+ # fields but it's the same one, so count them by name
+ body_param_names_set = {field.name for field in fields}
+ # A top level field has to be a single field, not multiple
+ if len(body_param_names_set) > 1:
+ return True
+ first_field = fields[0]
+ # If it explicitly specifies it is embedded, it has to be embedded
+ if getattr(first_field.field_info, "embed", None):
+ return True
+ # If it's a Form (or File) field, it has to be a BaseModel to be top level
+ # otherwise it has to be embedded, so that the key value pair can be extracted
+ if isinstance(first_field.field_info, params.Form) and not lenient_issubclass(
+ first_field.type_, BaseModel
+ ):
+ return True
+ return False
+
+
+async def _extract_form_body(
+ body_fields: List[ModelField],
+ 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)
+ if (
+ isinstance(first_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 value_is_sequence(value)
+ ):
+ # For types
+ assert isinstance(value, sequence_types) # type: ignore[arg-type]
+ results: List[Union[bytes, str]] = []
+
+ async def process_fn(
+ fn: Callable[[], Coroutine[Any, Any, Any]],
+ ) -> None:
+ result = await fn()
+ results.append(result) # noqa: B023
+
+ async with anyio.create_task_group() as tg:
+ for sub_value in value:
+ tg.start_soon(process_fn, sub_value.read)
+ value = serialize_sequence_value(field=field, value=results)
+ if value is not None:
+ values[field.alias] = value
+ for key, value in received_body.items():
+ if key not in values:
+ values[key] = value
+ return values
+
+
+async def request_body_to_args(
+ body_fields: List[ModelField],
+ received_body: Optional[Union[Dict[str, Any], FormData]],
+ embed_body_fields: bool,
+) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
+ values: Dict[str, Any] = {}
errors: List[Dict[str, Any]] = []
- if required_params:
- field = required_params[0]
- field_info = field.field_info
- embed = getattr(field_info, "embed", None)
- field_alias_omitted = len(required_params) == 1 and not embed
- if field_alias_omitted:
- received_body = {field.alias: received_body}
+ assert body_fields, "request_body_to_args() should be called with fields"
+ single_not_embedded_field = len(body_fields) == 1 and not embed_body_fields
+ first_field = body_fields[0]
+ body_to_process = received_body
- for field in required_params:
- loc: Tuple[str, ...]
- if field_alias_omitted:
- loc = ("body",)
- else:
- loc = ("body", field.alias)
+ fields_to_extract: List[ModelField] = body_fields
- value: Optional[Any] = None
- if received_body is not None:
- if (is_sequence_field(field)) and isinstance(received_body, FormData):
- value = received_body.getlist(field.alias)
- else:
- try:
- value = received_body.get(field.alias)
- except AttributeError:
- errors.append(get_missing_field_error(loc))
- continue
- if (
- value is None
- or (isinstance(field_info, params.Form) and value == "")
- or (
- isinstance(field_info, params.Form)
- and is_sequence_field(field)
- and len(value) == 0
- )
- ):
- if field.required:
- errors.append(get_missing_field_error(loc))
- else:
- values[field.name] = deepcopy(field.default)
+ if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel):
+ fields_to_extract = get_cached_model_fields(first_field.type_)
+
+ if isinstance(received_body, FormData):
+ body_to_process = await _extract_form_body(fields_to_extract, received_body)
+
+ if single_not_embedded_field:
+ loc: Tuple[str, ...] = ("body",)
+ v_, errors_ = _validate_value_with_model_field(
+ field=first_field, value=body_to_process, values=values, loc=loc
+ )
+ return {first_field.name: v_}, errors_
+ for field in body_fields:
+ loc = ("body", field.alias)
+ value: Optional[Any] = None
+ if body_to_process is not None:
+ try:
+ value = body_to_process.get(field.alias)
+ # If the received body is a list, not a dict
+ except AttributeError:
+ errors.append(get_missing_field_error(loc))
continue
- if (
- 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(field_info, params.File)
- and value_is_sequence(value)
- ):
- # For types
- assert isinstance(value, sequence_types) # type: ignore[arg-type]
- results: List[Union[bytes, str]] = []
-
- async def process_fn(
- fn: Callable[[], Coroutine[Any, Any, Any]],
- ) -> None:
- result = await fn()
- results.append(result) # noqa: B023
-
- async with anyio.create_task_group() as tg:
- for sub_value in value:
- tg.start_soon(process_fn, sub_value.read)
- value = serialize_sequence_value(field=field, value=results)
-
- v_, errors_ = field.validate(value, values, loc=loc)
-
- if isinstance(errors_, list):
- errors.extend(errors_)
- elif errors_:
- errors.append(errors_)
- else:
- values[field.name] = v_
+ v_, errors_ = _validate_value_with_model_field(
+ field=field, value=value, values=values, loc=loc
+ )
+ if errors_:
+ errors.extend(errors_)
+ else:
+ values[field.name] = v_
return values, errors
-def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]:
- flat_dependant = get_flat_dependant(dependant)
+def get_body_field(
+ *, flat_dependant: Dependant, name: str, embed_body_fields: bool
+) -> Optional[ModelField]:
+ """
+ Get a ModelField representing the request body for a path operation, combining
+ all body parameters into a single field if necessary.
+
+ Used to check if it's form data (with `isinstance(body_field, params.Form)`)
+ or JSON and to generate the JSON Schema for a request body.
+
+ This is **not** used to validate/parse the request body, that's done with each
+ individual body parameter.
+ """
if not flat_dependant.body_params:
return None
first_param = flat_dependant.body_params[0]
- field_info = first_param.field_info
- embed = getattr(field_info, "embed", None)
- body_param_names_set = {param.name for param in flat_dependant.body_params}
- if len(body_param_names_set) == 1 and not embed:
+ if not embed_body_fields:
return first_param
- # If one field requires to embed, all have to be embedded
- # in case a sub-dependency is evaluated with a single unique body field
- # That is combined (embedded) with other body fields
- for param in flat_dependant.body_params:
- setattr(param.field_info, "embed", True) # noqa: B010
model_name = "Body_" + name
BodyModel = create_body_model(
fields=flat_dependant.body_params, model_name=model_name
diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py
index 79ad9f83f..947eca948 100644
--- a/fastapi/openapi/utils.py
+++ b/fastapi/openapi/utils.py
@@ -16,11 +16,15 @@ from fastapi._compat import (
)
from fastapi.datastructures import DefaultPlaceholder
from fastapi.dependencies.models import Dependant
-from fastapi.dependencies.utils import get_flat_dependant, get_flat_params
+from fastapi.dependencies.utils import (
+ _get_flat_fields_from_params,
+ get_flat_dependant,
+ get_flat_params,
+)
from fastapi.encoders import jsonable_encoder
from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE
from fastapi.openapi.models import OpenAPI
-from fastapi.params import Body, Param
+from fastapi.params import Body, ParamTypes
from fastapi.responses import Response
from fastapi.types import ModelNameMap
from fastapi.utils import (
@@ -87,9 +91,9 @@ def get_openapi_security_definitions(
return security_definitions, operation_security
-def get_openapi_operation_parameters(
+def _get_openapi_operation_parameters(
*,
- all_route_params: Sequence[ModelField],
+ dependant: Dependant,
schema_generator: GenerateJsonSchema,
model_name_map: ModelNameMap,
field_mapping: Dict[
@@ -98,33 +102,47 @@ def get_openapi_operation_parameters(
separate_input_output_schemas: bool = True,
) -> List[Dict[str, Any]]:
parameters = []
- for param in all_route_params:
- field_info = param.field_info
- field_info = cast(Param, field_info)
- if not field_info.include_in_schema:
- continue
- param_schema = get_schema_from_model_field(
- field=param,
- schema_generator=schema_generator,
- model_name_map=model_name_map,
- field_mapping=field_mapping,
- separate_input_output_schemas=separate_input_output_schemas,
- )
- parameter = {
- "name": param.alias,
- "in": field_info.in_.value,
- "required": param.required,
- "schema": param_schema,
- }
- if field_info.description:
- parameter["description"] = field_info.description
- if field_info.openapi_examples:
- parameter["examples"] = jsonable_encoder(field_info.openapi_examples)
- elif field_info.example != Undefined:
- parameter["example"] = jsonable_encoder(field_info.example)
- if field_info.deprecated:
- parameter["deprecated"] = True
- parameters.append(parameter)
+ flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
+ parameter_groups = [
+ (ParamTypes.path, path_params),
+ (ParamTypes.query, query_params),
+ (ParamTypes.header, header_params),
+ (ParamTypes.cookie, cookie_params),
+ ]
+ for param_type, param_group in parameter_groups:
+ for param in param_group:
+ field_info = param.field_info
+ # field_info = cast(Param, field_info)
+ if not getattr(field_info, "include_in_schema", True):
+ continue
+ param_schema = get_schema_from_model_field(
+ field=param,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ parameter = {
+ "name": param.alias,
+ "in": param_type.value,
+ "required": param.required,
+ "schema": param_schema,
+ }
+ if field_info.description:
+ parameter["description"] = field_info.description
+ openapi_examples = getattr(field_info, "openapi_examples", None)
+ example = getattr(field_info, "example", None)
+ if openapi_examples:
+ parameter["examples"] = jsonable_encoder(openapi_examples)
+ elif example != Undefined:
+ parameter["example"] = jsonable_encoder(example)
+ if getattr(field_info, "deprecated", None):
+ parameter["deprecated"] = True
+ parameters.append(parameter)
return parameters
@@ -247,9 +265,8 @@ def get_openapi_path(
operation.setdefault("security", []).extend(operation_security)
if security_definitions:
security_schemes.update(security_definitions)
- all_route_params = get_flat_params(route.dependant)
- operation_parameters = get_openapi_operation_parameters(
- all_route_params=all_route_params,
+ operation_parameters = _get_openapi_operation_parameters(
+ dependant=route.dependant,
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
@@ -379,6 +396,7 @@ def get_openapi_path(
deep_dict_update(openapi_response, process_response)
openapi_response["description"] = description
http422 = str(HTTP_422_UNPROCESSABLE_ENTITY)
+ all_route_params = get_flat_params(route.dependant)
if (all_route_params or route.body_field) and not any(
status in operation["responses"]
for status in [http422, "4XX", "default"]
diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py
index 0d5f27af4..b3621626c 100644
--- a/fastapi/param_functions.py
+++ b/fastapi/param_functions.py
@@ -1282,7 +1282,7 @@ def Body( # noqa: N802
),
] = _Unset,
embed: Annotated[
- bool,
+ Union[bool, None],
Doc(
"""
When `embed` is `True`, the parameter will be expected in a JSON body as a
@@ -1294,7 +1294,7 @@ def Body( # noqa: N802
[FastAPI docs for Body - Multiple Parameters](https://fastapi.tiangolo.com/tutorial/body-multiple-params/#embed-a-single-body-parameter).
"""
),
- ] = False,
+ ] = None,
media_type: Annotated[
str,
Doc(
@@ -2298,7 +2298,7 @@ def Security( # noqa: N802
dependency.
The term "scope" comes from the OAuth2 specification, it seems to be
- intentionaly vague and interpretable. It normally refers to permissions,
+ intentionally vague and interpretable. It normally refers to permissions,
in cases to roles.
These scopes are integrated with OpenAPI (and the API docs at `/docs`).
diff --git a/fastapi/params.py b/fastapi/params.py
index cc2a5c13c..90ca7cb01 100644
--- a/fastapi/params.py
+++ b/fastapi/params.py
@@ -479,7 +479,7 @@ class Body(FieldInfo):
*,
default_factory: Union[Callable[[], Any], None] = _Unset,
annotation: Optional[Any] = None,
- embed: bool = False,
+ embed: Union[bool, None] = None,
media_type: str = "application/json",
alias: Optional[str] = None,
alias_priority: Union[int, None] = _Unset,
@@ -556,7 +556,7 @@ class Body(FieldInfo):
kwargs["examples"] = examples
if regex is not None:
warnings.warn(
- "`regex` has been depreacated, please use `pattern` instead",
+ "`regex` has been deprecated, please use `pattern` instead",
category=DeprecationWarning,
stacklevel=4,
)
@@ -642,7 +642,6 @@ class Form(Body):
default=default,
default_factory=default_factory,
annotation=annotation,
- embed=True,
media_type=media_type,
alias=alias,
alias_priority=alias_priority,
diff --git a/fastapi/routing.py b/fastapi/routing.py
index 8f1327236..68407a326 100644
--- a/fastapi/routing.py
+++ b/fastapi/routing.py
@@ -33,8 +33,10 @@ from fastapi._compat import (
from fastapi.datastructures import Default, DefaultPlaceholder
from fastapi.dependencies.models import Dependant
from fastapi.dependencies.utils import (
+ _should_embed_body_fields,
get_body_field,
get_dependant,
+ get_flat_dependant,
get_parameterless_sub_dependant,
get_typed_return_annotation,
solve_dependencies,
@@ -225,6 +227,7 @@ def get_request_handler(
response_model_exclude_defaults: bool = False,
response_model_exclude_none: bool = False,
dependency_overrides_provider: Optional[Any] = None,
+ 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)
@@ -291,6 +294,7 @@ def get_request_handler(
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:
@@ -354,7 +358,9 @@ def get_request_handler(
def get_websocket_app(
- dependant: Dependant, dependency_overrides_provider: Optional[Any] = None
+ dependant: Dependant,
+ dependency_overrides_provider: Optional[Any] = None,
+ embed_body_fields: bool = False,
) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:
async def app(websocket: WebSocket) -> None:
async with AsyncExitStack() as async_exit_stack:
@@ -367,6 +373,7 @@ def get_websocket_app(
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(
@@ -399,11 +406,15 @@ class APIWebSocketRoute(routing.WebSocketRoute):
0,
get_parameterless_sub_dependant(depends=depends, path=self.path_format),
)
-
+ self._flat_dependant = get_flat_dependant(self.dependant)
+ self._embed_body_fields = _should_embed_body_fields(
+ self._flat_dependant.body_params
+ )
self.app = websocket_session(
get_websocket_app(
dependant=self.dependant,
dependency_overrides_provider=dependency_overrides_provider,
+ embed_body_fields=self._embed_body_fields,
)
)
@@ -530,7 +541,9 @@ class APIRoute(routing.Route):
additional_status_code
), f"Status code {additional_status_code} must not have a response body"
response_name = f"Response_{additional_status_code}_{self.unique_id}"
- response_field = create_model_field(name=response_name, type_=model)
+ response_field = create_model_field(
+ name=response_name, type_=model, mode="serialization"
+ )
response_fields[additional_status_code] = response_field
if response_fields:
self.response_fields: Dict[Union[int, str], ModelField] = response_fields
@@ -544,7 +557,15 @@ class APIRoute(routing.Route):
0,
get_parameterless_sub_dependant(depends=depends, path=self.path_format),
)
- self.body_field = get_body_field(dependant=self.dependant, name=self.unique_id)
+ self._flat_dependant = get_flat_dependant(self.dependant)
+ self._embed_body_fields = _should_embed_body_fields(
+ self._flat_dependant.body_params
+ )
+ self.body_field = get_body_field(
+ flat_dependant=self._flat_dependant,
+ name=self.unique_id,
+ embed_body_fields=self._embed_body_fields,
+ )
self.app = request_response(self.get_route_handler())
def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]:
@@ -561,6 +582,7 @@ class APIRoute(routing.Route):
response_model_exclude_defaults=self.response_model_exclude_defaults,
response_model_exclude_none=self.response_model_exclude_none,
dependency_overrides_provider=self.dependency_overrides_provider,
+ embed_body_fields=self._embed_body_fields,
)
def matches(self, scope: Scope) -> Tuple[Match, Scope]:
diff --git a/fastapi/security/http.py b/fastapi/security/http.py
index a142b135d..e06f3d66d 100644
--- a/fastapi/security/http.py
+++ b/fastapi/security/http.py
@@ -277,7 +277,7 @@ class HTTPBearer(HTTPBase):
bool,
Doc(
"""
- By default, if the HTTP Bearer token not provided (in an
+ By default, if the HTTP Bearer token is not provided (in an
`Authorization` header), `HTTPBearer` will automatically cancel the
request and send the client an error.
@@ -380,7 +380,7 @@ class HTTPDigest(HTTPBase):
bool,
Doc(
"""
- By default, if the HTTP Digest not provided, `HTTPDigest` will
+ By default, if the HTTP Digest is not provided, `HTTPDigest` will
automatically cancel the request and send the client an error.
If `auto_error` is set to `False`, when the HTTP Digest is not
diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py
index 9720cace0..6adc55bfe 100644
--- a/fastapi/security/oauth2.py
+++ b/fastapi/security/oauth2.py
@@ -52,7 +52,7 @@ class OAuth2PasswordRequestForm:
```
Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
- You could have custom internal logic to separate it by colon caracters (`:`) or
+ You could have custom internal logic to separate it by colon characters (`:`) or
similar, and get the two parts `items` and `read`. Many applications do that to
group and organize permissions, you could do it as well in your application, just
know that that it is application specific, it's not part of the specification.
@@ -194,7 +194,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
```
Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
- You could have custom internal logic to separate it by colon caracters (`:`) or
+ You could have custom internal logic to separate it by colon characters (`:`) or
similar, and get the two parts `items` and `read`. Many applications do that to
group and organize permissions, you could do it as well in your application, just
know that that it is application specific, it's not part of the specification.
diff --git a/pyproject.toml b/pyproject.toml
index bb87be470..edfa81522 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -41,7 +41,7 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP",
]
dependencies = [
- "starlette>=0.37.2,<0.39.0",
+ "starlette>=0.40.0,<0.42.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",
]
@@ -241,3 +241,7 @@ known-third-party = ["fastapi", "pydantic", "starlette"]
[tool.ruff.lint.pyupgrade]
# Preserve types, even if a file imports `from __future__ import annotations`.
keep-runtime-typing = true
+
+[tool.inline-snapshot]
+# default-flags=["fix"]
+# default-flags=["create"]
diff --git a/requirements-docs-tests.txt b/requirements-docs-tests.txt
index b82df4933..331d2a5b3 100644
--- a/requirements-docs-tests.txt
+++ b/requirements-docs-tests.txt
@@ -1,2 +1,4 @@
# For mkdocstrings and tests
-httpx >=0.23.0,<0.25.0
+httpx >=0.23.0,<0.28.0
+# For linting and generating docs versions
+ruff ==0.6.4
diff --git a/requirements-docs.txt b/requirements-docs.txt
index 332fd1857..9754eaa4a 100644
--- a/requirements-docs.txt
+++ b/requirements-docs.txt
@@ -3,16 +3,17 @@
mkdocs-material==9.5.18
mdx-include >=1.4.1,<2.0.0
mkdocs-redirects>=1.2.1,<1.3.0
-typer == 0.12.3
+typer == 0.12.5
pyyaml >=5.3.1,<7.0.0
# For Material for MkDocs, Chinese search
jieba==0.42.1
# For image processing by Material for MkDocs
-pillow==10.4.0
+pillow==11.0.0
# For image processing by Material for MkDocs
cairosvg==2.7.1
-mkdocstrings[python]==0.25.1
-griffe-typingdoc==0.2.6
+mkdocstrings[python]==0.26.1
+griffe-typingdoc==0.2.7
# For griffe, it formats with black
black==24.3.0
mkdocs-macros-plugin==1.0.5
+markdown-include-variants==0.0.3
diff --git a/requirements-github-actions.txt b/requirements-github-actions.txt
index 559dc06fb..a6dace544 100644
--- a/requirements-github-actions.txt
+++ b/requirements-github-actions.txt
@@ -2,3 +2,4 @@ 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
+smokeshow
diff --git a/requirements-tests.txt b/requirements-tests.txt
index 08561d23a..95ec09884 100644
--- a/requirements-tests.txt
+++ b/requirements-tests.txt
@@ -1,20 +1,16 @@
-e .[all]
-r requirements-docs-tests.txt
-pytest >=7.1.3,<8.0.0
+pytest >=7.1.3,<9.0.0
coverage[toml] >= 6.5.0,< 8.0
mypy ==1.8.0
-ruff ==0.6.1
dirty-equals ==0.6.0
-# TODO: once removing databases from tutorial, upgrade SQLAlchemy
-# probably when including SQLModel
-sqlalchemy >=1.3.18,<2.0.33
-databases[sqlite] >=0.3.2,<0.7.0
-flask >=1.1.2,<3.0.0
+sqlmodel==0.0.22
+flask >=1.1.2,<4.0.0
anyio[trio] >=3.2.1,<4.0.0
PyJWT==2.8.0
pyyaml >=5.3.1,<7.0.0
passlib[bcrypt] >=1.7.2,<2.0.0
-
+inline-snapshot==0.13.0
# types
types-ujson ==5.7.0.1
types-orjson ==3.6.2
diff --git a/requirements.txt b/requirements.txt
index 8e1fef341..9180bf1be 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
-e .[all]
-r requirements-tests.txt
-r requirements-docs.txt
-pre-commit >=2.17.0,<4.0.0
+pre-commit >=2.17.0,<5.0.0
# For generating screenshots
playwright
diff --git a/scripts/deploy_docs_status.py b/scripts/deploy_docs_status.py
index 19dffbcb9..c652cdb6e 100644
--- a/scripts/deploy_docs_status.py
+++ b/scripts/deploy_docs_status.py
@@ -2,7 +2,7 @@ import logging
import re
from github import Github
-from pydantic import SecretStr
+from pydantic import BaseModel, SecretStr
from pydantic_settings import BaseSettings
@@ -15,7 +15,13 @@ class Settings(BaseSettings):
is_done: bool = False
-def main():
+class LinkData(BaseModel):
+ previous_link: str
+ preview_link: str
+ en_link: str | None = None
+
+
+def main() -> None:
logging.basicConfig(level=logging.INFO)
settings = Settings()
@@ -60,7 +66,7 @@ def main():
docs_files = [f for f in files if f.filename.startswith("docs/")]
deploy_url = settings.deploy_url.rstrip("/")
- lang_links: dict[str, list[str]] = {}
+ lang_links: dict[str, list[LinkData]] = {}
for f in docs_files:
match = re.match(r"docs/([^/]+)/docs/(.*)", f.filename)
if not match:
@@ -71,15 +77,22 @@ def main():
path = path.replace("index.md", "")
else:
path = path.replace(".md", "/")
+ en_path = path
if lang == "en":
- link = f"{deploy_url}/{path}"
+ use_path = en_path
else:
- link = f"{deploy_url}/{lang}/{path}"
+ use_path = f"{lang}/{path}"
+ link = LinkData(
+ previous_link=f"https://fastapi.tiangolo.com/{use_path}",
+ preview_link=f"{deploy_url}/{use_path}",
+ )
+ if lang != "en":
+ link.en_link = f"https://fastapi.tiangolo.com/{en_path}"
lang_links.setdefault(lang, []).append(link)
- links: list[str] = []
+ links: list[LinkData] = []
en_links = lang_links.get("en", [])
- en_links.sort()
+ en_links.sort(key=lambda x: x.preview_link)
links.extend(en_links)
langs = list(lang_links.keys())
@@ -88,14 +101,19 @@ def main():
if lang == "en":
continue
current_lang_links = lang_links[lang]
- current_lang_links.sort()
+ 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}"
if links:
message += "\n\n### Modified Pages\n\n"
- message += "\n".join([f"* {link}" for link in links])
+ for link in links:
+ message += f"* {link.preview_link}"
+ message += f" - ([before]({link.previous_link}))"
+ if link.en_link:
+ message += f" - ([English]({link.en_link}))"
+ message += "\n"
print(message)
use_pr.as_issue().create_comment(message)
diff --git a/scripts/docs.py b/scripts/docs.py
index f0c51f7a6..f26f96d85 100644
--- a/scripts/docs.py
+++ b/scripts/docs.py
@@ -15,6 +15,7 @@ import mkdocs.utils
import typer
import yaml
from jinja2 import Template
+from ruff.__main__ import find_ruff_bin
logging.basicConfig(level=logging.INFO)
@@ -23,7 +24,7 @@ app = typer.Typer()
mkdocs_name = "mkdocs.yml"
missing_translation_snippet = """
-{!../../../docs/missing-translation.md!}
+{!../../docs/missing-translation.md!}
"""
non_translated_sections = [
@@ -382,5 +383,41 @@ def langs_json():
print(json.dumps(langs))
+@app.command()
+def generate_docs_src_versions_for_file(file_path: Path) -> None:
+ target_versions = ["py39", "py310"]
+ base_content = file_path.read_text(encoding="utf-8")
+ previous_content = {base_content}
+ for target_version in target_versions:
+ version_result = subprocess.run(
+ [
+ find_ruff_bin(),
+ "check",
+ "--target-version",
+ target_version,
+ "--fix",
+ "--unsafe-fixes",
+ "-",
+ ],
+ input=base_content.encode("utf-8"),
+ capture_output=True,
+ )
+ content_target = version_result.stdout.decode("utf-8")
+ format_result = subprocess.run(
+ [find_ruff_bin(), "format", "-"],
+ input=content_target.encode("utf-8"),
+ capture_output=True,
+ )
+ content_format = format_result.stdout.decode("utf-8")
+ if content_format in previous_content:
+ continue
+ previous_content.add(content_format)
+ version_file = file_path.with_name(
+ file_path.name.replace(".py", f"_{target_version}.py")
+ )
+ logging.info(f"Writing to {version_file}")
+ version_file.write_text(content_format, encoding="utf-8")
+
+
if __name__ == "__main__":
app()
diff --git a/scripts/label_approved.py b/scripts/label_approved.py
new file mode 100644
index 000000000..271444504
--- /dev/null
+++ b/scripts/label_approved.py
@@ -0,0 +1,60 @@
+import logging
+from typing import Literal
+
+from github import Github
+from github.PullRequestReview import PullRequestReview
+from pydantic import BaseModel, SecretStr
+from pydantic_settings import BaseSettings
+
+
+class LabelSettings(BaseModel):
+ await_label: str | None = None
+ number: int
+
+
+default_config = {"approved-2": LabelSettings(await_label="awaiting-review", number=2)}
+
+
+class Settings(BaseSettings):
+ github_repository: str
+ token: SecretStr
+ debug: bool | None = False
+ config: dict[str, LabelSettings] | Literal[""] = default_config
+
+
+settings = Settings()
+if settings.debug:
+ logging.basicConfig(level=logging.DEBUG)
+else:
+ logging.basicConfig(level=logging.INFO)
+logging.debug(f"Using config: {settings.json()}")
+g = Github(settings.token.get_secret_value())
+repo = g.get_repo(settings.github_repository)
+for pr in repo.get_pulls(state="open"):
+ logging.info(f"Checking PR: #{pr.number}")
+ pr_labels = list(pr.get_labels())
+ pr_label_by_name = {label.name: label for label in pr_labels}
+ reviews = list(pr.get_reviews())
+ review_by_user: dict[str, PullRequestReview] = {}
+ for review in reviews:
+ if review.user.login in review_by_user:
+ stored_review = review_by_user[review.user.login]
+ if review.submitted_at >= stored_review.submitted_at:
+ review_by_user[review.user.login] = review
+ else:
+ review_by_user[review.user.login] = review
+ approved_reviews = [
+ review for review in review_by_user.values() if review.state == "APPROVED"
+ ]
+ config = settings.config or default_config
+ for approved_label, conf in config.items():
+ logging.debug(f"Processing config: {conf.json()}")
+ if conf.await_label is None or (conf.await_label in pr_label_by_name):
+ logging.debug(f"Processable PR: {pr.number}")
+ if len(approved_reviews) >= conf.number:
+ logging.info(f"Adding label to PR: {pr.number}")
+ pr.add_to_labels(approved_label)
+ if conf.await_label:
+ logging.info(f"Removing label from PR: {pr.number}")
+ pr.remove_from_labels(conf.await_label)
+logging.info("Finished")
diff --git a/scripts/playwright/cookie_param_models/image01.py b/scripts/playwright/cookie_param_models/image01.py
new file mode 100644
index 000000000..77c91bfe2
--- /dev/null
+++ b/scripts/playwright/cookie_param_models/image01.py
@@ -0,0 +1,39 @@
+import subprocess
+import time
+
+import httpx
+from playwright.sync_api import Playwright, sync_playwright
+
+
+# Run playwright codegen to generate the code below, copy paste the sections in run()
+def run(playwright: Playwright) -> None:
+ browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
+ context = browser.new_context(viewport={"width": 960, "height": 1080})
+ browser = playwright.chromium.launch(headless=False)
+ context = browser.new_context()
+ page = context.new_page()
+ page.goto("http://localhost:8000/docs")
+ page.get_by_role("link", name="/items/").click()
+ # Manually add the screenshot
+ page.screenshot(path="docs/en/docs/img/tutorial/cookie-param-models/image01.png")
+
+ # ---------------------
+ context.close()
+ browser.close()
+
+
+process = subprocess.Popen(
+ ["fastapi", "run", "docs_src/cookie_param_models/tutorial001.py"]
+)
+try:
+ for _ in range(3):
+ try:
+ response = httpx.get("http://localhost:8000/docs")
+ except httpx.ConnectError:
+ time.sleep(1)
+ break
+ with sync_playwright() as playwright:
+ run(playwright)
+finally:
+ process.terminate()
diff --git a/scripts/playwright/header_param_models/image01.py b/scripts/playwright/header_param_models/image01.py
new file mode 100644
index 000000000..53914251e
--- /dev/null
+++ b/scripts/playwright/header_param_models/image01.py
@@ -0,0 +1,38 @@
+import subprocess
+import time
+
+import httpx
+from playwright.sync_api import Playwright, sync_playwright
+
+
+# Run playwright codegen to generate the code below, copy paste the sections in run()
+def run(playwright: Playwright) -> None:
+ browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
+ context = browser.new_context(viewport={"width": 960, "height": 1080})
+ page = context.new_page()
+ page.goto("http://localhost:8000/docs")
+ page.get_by_role("button", name="GET /items/ Read Items").click()
+ page.get_by_role("button", name="Try it out").click()
+ # Manually add the screenshot
+ page.screenshot(path="docs/en/docs/img/tutorial/header-param-models/image01.png")
+
+ # ---------------------
+ context.close()
+ browser.close()
+
+
+process = subprocess.Popen(
+ ["fastapi", "run", "docs_src/header_param_models/tutorial001.py"]
+)
+try:
+ for _ in range(3):
+ try:
+ response = httpx.get("http://localhost:8000/docs")
+ except httpx.ConnectError:
+ time.sleep(1)
+ break
+ with sync_playwright() as playwright:
+ run(playwright)
+finally:
+ process.terminate()
diff --git a/scripts/playwright/query_param_models/image01.py b/scripts/playwright/query_param_models/image01.py
new file mode 100644
index 000000000..0ea1d0df4
--- /dev/null
+++ b/scripts/playwright/query_param_models/image01.py
@@ -0,0 +1,41 @@
+import subprocess
+import time
+
+import httpx
+from playwright.sync_api import Playwright, sync_playwright
+
+
+# Run playwright codegen to generate the code below, copy paste the sections in run()
+def run(playwright: Playwright) -> None:
+ browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
+ context = browser.new_context(viewport={"width": 960, "height": 1080})
+ browser = playwright.chromium.launch(headless=False)
+ context = browser.new_context()
+ page = context.new_page()
+ page.goto("http://localhost:8000/docs")
+ page.get_by_role("button", name="GET /items/ Read Items").click()
+ page.get_by_role("button", name="Try it out").click()
+ page.get_by_role("heading", name="Servers").click()
+ # Manually add the screenshot
+ page.screenshot(path="docs/en/docs/img/tutorial/query-param-models/image01.png")
+
+ # ---------------------
+ context.close()
+ browser.close()
+
+
+process = subprocess.Popen(
+ ["fastapi", "run", "docs_src/query_param_models/tutorial001.py"]
+)
+try:
+ for _ in range(3):
+ try:
+ response = httpx.get("http://localhost:8000/docs")
+ except httpx.ConnectError:
+ time.sleep(1)
+ break
+ with sync_playwright() as playwright:
+ run(playwright)
+finally:
+ process.terminate()
diff --git a/scripts/playwright/request_form_models/image01.py b/scripts/playwright/request_form_models/image01.py
new file mode 100644
index 000000000..fe4da32fc
--- /dev/null
+++ b/scripts/playwright/request_form_models/image01.py
@@ -0,0 +1,38 @@
+import subprocess
+import time
+
+import httpx
+from playwright.sync_api import Playwright, sync_playwright
+
+
+# Run playwright codegen to generate the code below, copy paste the sections in run()
+def run(playwright: Playwright) -> None:
+ browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
+ context = browser.new_context(viewport={"width": 960, "height": 1080})
+ page = context.new_page()
+ page.goto("http://localhost:8000/docs")
+ page.get_by_role("button", name="POST /login/ Login").click()
+ page.get_by_role("button", name="Try it out").click()
+ # Manually add the screenshot
+ page.screenshot(path="docs/en/docs/img/tutorial/request-form-models/image01.png")
+
+ # ---------------------
+ context.close()
+ browser.close()
+
+
+process = subprocess.Popen(
+ ["fastapi", "run", "docs_src/request_form_models/tutorial001.py"]
+)
+try:
+ for _ in range(3):
+ try:
+ response = httpx.get("http://localhost:8000/docs")
+ except httpx.ConnectError:
+ time.sleep(1)
+ break
+ with sync_playwright() as playwright:
+ run(playwright)
+finally:
+ process.terminate()
diff --git a/scripts/playwright/separate_openapi_schemas/image01.py b/scripts/playwright/separate_openapi_schemas/image01.py
index 0b40f3bbc..0eb55fb73 100644
--- a/scripts/playwright/separate_openapi_schemas/image01.py
+++ b/scripts/playwright/separate_openapi_schemas/image01.py
@@ -3,13 +3,16 @@ import subprocess
from playwright.sync_api import Playwright, sync_playwright
+# Run playwright codegen to generate the code below, copy paste the sections in run()
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
context = browser.new_context(viewport={"width": 960, "height": 1080})
page = context.new_page()
page.goto("http://localhost:8000/docs")
page.get_by_text("POST/items/Create Item").click()
page.get_by_role("tab", name="Schema").first.click()
+ # Manually add the screenshot
page.screenshot(
path="docs/en/docs/img/tutorial/separate-openapi-schemas/image01.png"
)
diff --git a/scripts/playwright/separate_openapi_schemas/image02.py b/scripts/playwright/separate_openapi_schemas/image02.py
index f76af7ee2..0eb6c3c79 100644
--- a/scripts/playwright/separate_openapi_schemas/image02.py
+++ b/scripts/playwright/separate_openapi_schemas/image02.py
@@ -3,14 +3,17 @@ import subprocess
from playwright.sync_api import Playwright, sync_playwright
+# Run playwright codegen to generate the code below, copy paste the sections in run()
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
context = browser.new_context(viewport={"width": 960, "height": 1080})
page = context.new_page()
page.goto("http://localhost:8000/docs")
page.get_by_text("GET/items/Read Items").click()
page.get_by_role("button", name="Try it out").click()
page.get_by_role("button", name="Execute").click()
+ # Manually add the screenshot
page.screenshot(
path="docs/en/docs/img/tutorial/separate-openapi-schemas/image02.png"
)
diff --git a/scripts/playwright/separate_openapi_schemas/image03.py b/scripts/playwright/separate_openapi_schemas/image03.py
index 127f5c428..b68e9d7db 100644
--- a/scripts/playwright/separate_openapi_schemas/image03.py
+++ b/scripts/playwright/separate_openapi_schemas/image03.py
@@ -3,14 +3,17 @@ import subprocess
from playwright.sync_api import Playwright, sync_playwright
+# Run playwright codegen to generate the code below, copy paste the sections in run()
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
context = browser.new_context(viewport={"width": 960, "height": 1080})
page = context.new_page()
page.goto("http://localhost:8000/docs")
page.get_by_text("GET/items/Read Items").click()
page.get_by_role("tab", name="Schema").click()
page.get_by_label("Schema").get_by_role("button", name="Expand all").click()
+ # Manually add the screenshot
page.screenshot(
path="docs/en/docs/img/tutorial/separate-openapi-schemas/image03.png"
)
diff --git a/scripts/playwright/separate_openapi_schemas/image04.py b/scripts/playwright/separate_openapi_schemas/image04.py
index 208eaf8a0..a36c2f6b2 100644
--- a/scripts/playwright/separate_openapi_schemas/image04.py
+++ b/scripts/playwright/separate_openapi_schemas/image04.py
@@ -3,14 +3,17 @@ import subprocess
from playwright.sync_api import Playwright, sync_playwright
+# Run playwright codegen to generate the code below, copy paste the sections in run()
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
context = browser.new_context(viewport={"width": 960, "height": 1080})
page = context.new_page()
page.goto("http://localhost:8000/docs")
page.get_by_role("button", name="Item-Input").click()
page.get_by_role("button", name="Item-Output").click()
page.set_viewport_size({"width": 960, "height": 820})
+ # Manually add the screenshot
page.screenshot(
path="docs/en/docs/img/tutorial/separate-openapi-schemas/image04.png"
)
diff --git a/scripts/playwright/separate_openapi_schemas/image05.py b/scripts/playwright/separate_openapi_schemas/image05.py
index 83966b449..0da5db0cf 100644
--- a/scripts/playwright/separate_openapi_schemas/image05.py
+++ b/scripts/playwright/separate_openapi_schemas/image05.py
@@ -3,13 +3,16 @@ import subprocess
from playwright.sync_api import Playwright, sync_playwright
+# Run playwright codegen to generate the code below, copy paste the sections in run()
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
context = browser.new_context(viewport={"width": 960, "height": 1080})
page = context.new_page()
page.goto("http://localhost:8000/docs")
page.get_by_role("button", name="Item", exact=True).click()
page.set_viewport_size({"width": 960, "height": 700})
+ # Manually add the screenshot
page.screenshot(
path="docs/en/docs/img/tutorial/separate-openapi-schemas/image05.png"
)
diff --git a/scripts/playwright/sql_databases/image01.py b/scripts/playwright/sql_databases/image01.py
new file mode 100644
index 000000000..0dd6f2514
--- /dev/null
+++ b/scripts/playwright/sql_databases/image01.py
@@ -0,0 +1,37 @@
+import subprocess
+import time
+
+import httpx
+from playwright.sync_api import Playwright, sync_playwright
+
+
+# Run playwright codegen to generate the code below, copy paste the sections in run()
+def run(playwright: Playwright) -> None:
+ browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
+ context = browser.new_context(viewport={"width": 960, "height": 1080})
+ page = context.new_page()
+ page.goto("http://localhost:8000/docs")
+ page.get_by_label("post /heroes/").click()
+ # Manually add the screenshot
+ page.screenshot(path="docs/en/docs/img/tutorial/sql-databases/image01.png")
+
+ # ---------------------
+ context.close()
+ browser.close()
+
+
+process = subprocess.Popen(
+ ["fastapi", "run", "docs_src/sql_databases/tutorial001.py"],
+)
+try:
+ for _ in range(3):
+ try:
+ response = httpx.get("http://localhost:8000/docs")
+ except httpx.ConnectError:
+ time.sleep(1)
+ break
+ with sync_playwright() as playwright:
+ run(playwright)
+finally:
+ process.terminate()
diff --git a/scripts/playwright/sql_databases/image02.py b/scripts/playwright/sql_databases/image02.py
new file mode 100644
index 000000000..6c4f685e8
--- /dev/null
+++ b/scripts/playwright/sql_databases/image02.py
@@ -0,0 +1,37 @@
+import subprocess
+import time
+
+import httpx
+from playwright.sync_api import Playwright, sync_playwright
+
+
+# Run playwright codegen to generate the code below, copy paste the sections in run()
+def run(playwright: Playwright) -> None:
+ browser = playwright.chromium.launch(headless=False)
+ # Update the viewport manually
+ context = browser.new_context(viewport={"width": 960, "height": 1080})
+ page = context.new_page()
+ page.goto("http://localhost:8000/docs")
+ page.get_by_label("post /heroes/").click()
+ # Manually add the screenshot
+ page.screenshot(path="docs/en/docs/img/tutorial/sql-databases/image02.png")
+
+ # ---------------------
+ context.close()
+ browser.close()
+
+
+process = subprocess.Popen(
+ ["fastapi", "run", "docs_src/sql_databases/tutorial002.py"],
+)
+try:
+ for _ in range(3):
+ try:
+ response = httpx.get("http://localhost:8000/docs")
+ except httpx.ConnectError:
+ time.sleep(1)
+ break
+ with sync_playwright() as playwright:
+ run(playwright)
+finally:
+ process.terminate()
diff --git a/tests/test_compat.py b/tests/test_compat.py
index bf268b860..f4a3093c5 100644
--- a/tests/test_compat.py
+++ b/tests/test_compat.py
@@ -1,11 +1,14 @@
-from typing import List, Union
+from typing import Any, Dict, List, Union
from fastapi import FastAPI, UploadFile
from fastapi._compat import (
ModelField,
Undefined,
_get_model_config,
+ get_cached_model_fields,
+ get_model_fields,
is_bytes_sequence_annotation,
+ is_scalar_field,
is_uploadfile_sequence_annotation,
)
from fastapi.testclient import TestClient
@@ -91,3 +94,27 @@ def test_is_uploadfile_sequence_annotation():
# and other types, but I'm not even sure it's a good idea to support it as a first
# class "feature"
assert is_uploadfile_sequence_annotation(Union[List[str], List[UploadFile]])
+
+
+def test_is_pv1_scalar_field():
+ # For coverage
+ class Model(BaseModel):
+ foo: Union[str, Dict[str, Any]]
+
+ fields = get_model_fields(Model)
+ assert not is_scalar_field(fields[0])
+
+
+def test_get_model_fields_cached():
+ class Model(BaseModel):
+ foo: str
+
+ non_cached_fields = get_model_fields(Model)
+ non_cached_fields2 = get_model_fields(Model)
+ cached_fields = get_cached_model_fields(Model)
+ cached_fields2 = get_cached_model_fields(Model)
+ for f1, f2 in zip(cached_fields, cached_fields2):
+ assert f1 is f2
+
+ assert non_cached_fields is not non_cached_fields2
+ assert cached_fields is cached_fields2
diff --git a/tests/test_computed_fields.py b/tests/test_computed_fields.py
index 5286507b2..a1b412168 100644
--- a/tests/test_computed_fields.py
+++ b/tests/test_computed_fields.py
@@ -24,13 +24,18 @@ def get_client():
def read_root() -> Rectangle:
return Rectangle(width=3, length=4)
+ @app.get("/responses", responses={200: {"model": Rectangle}})
+ def read_responses() -> Rectangle:
+ return Rectangle(width=3, length=4)
+
client = TestClient(app)
return client
+@pytest.mark.parametrize("path", ["/", "/responses"])
@needs_pydanticv2
-def test_get(client: TestClient):
- response = client.get("/")
+def test_get(client: TestClient, path: str):
+ response = client.get(path)
assert response.status_code == 200, response.text
assert response.json() == {"width": 3, "length": 4, "area": 12}
@@ -58,7 +63,23 @@ def test_openapi_schema(client: TestClient):
}
},
}
- }
+ },
+ "/responses": {
+ "get": {
+ "summary": "Read Responses",
+ "operationId": "read_responses_responses_get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Rectangle"}
+ }
+ },
+ }
+ },
+ }
+ },
},
"components": {
"schemas": {
diff --git a/tests/test_forms_single_model.py b/tests/test_forms_single_model.py
new file mode 100644
index 000000000..880ab3820
--- /dev/null
+++ b/tests/test_forms_single_model.py
@@ -0,0 +1,133 @@
+from typing import List, Optional
+
+from dirty_equals import IsDict
+from fastapi import FastAPI, Form
+from fastapi.testclient import TestClient
+from pydantic import BaseModel, Field
+from typing_extensions import Annotated
+
+app = FastAPI()
+
+
+class FormModel(BaseModel):
+ username: str
+ lastname: str
+ age: Optional[int] = None
+ tags: List[str] = ["foo", "bar"]
+ alias_with: str = Field(alias="with", default="nothing")
+
+
+@app.post("/form/")
+def post_form(user: Annotated[FormModel, Form()]):
+ return user
+
+
+client = TestClient(app)
+
+
+def test_send_all_data():
+ response = client.post(
+ "/form/",
+ data={
+ "username": "Rick",
+ "lastname": "Sanchez",
+ "age": "70",
+ "tags": ["plumbus", "citadel"],
+ "with": "something",
+ },
+ )
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "username": "Rick",
+ "lastname": "Sanchez",
+ "age": 70,
+ "tags": ["plumbus", "citadel"],
+ "with": "something",
+ }
+
+
+def test_defaults():
+ response = client.post("/form/", data={"username": "Rick", "lastname": "Sanchez"})
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "username": "Rick",
+ "lastname": "Sanchez",
+ "age": None,
+ "tags": ["foo", "bar"],
+ "with": "nothing",
+ }
+
+
+def test_invalid_data():
+ response = client.post(
+ "/form/",
+ data={
+ "username": "Rick",
+ "lastname": "Sanchez",
+ "age": "seventy",
+ "tags": ["plumbus", "citadel"],
+ },
+ )
+ assert response.status_code == 422, response.text
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "int_parsing",
+ "loc": ["body", "age"],
+ "msg": "Input should be a valid integer, unable to parse string as an integer",
+ "input": "seventy",
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "age"],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer",
+ }
+ ]
+ }
+ )
+
+
+def test_no_data():
+ response = client.post("/form/")
+ assert response.status_code == 422, response.text
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"tags": ["foo", "bar"], "with": "nothing"},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "lastname"],
+ "msg": "Field required",
+ "input": {"tags": ["foo", "bar"], "with": "nothing"},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "lastname"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
diff --git a/tests/test_forms_single_param.py b/tests/test_forms_single_param.py
new file mode 100644
index 000000000..3bb951441
--- /dev/null
+++ b/tests/test_forms_single_param.py
@@ -0,0 +1,99 @@
+from fastapi import FastAPI, Form
+from fastapi.testclient import TestClient
+from typing_extensions import Annotated
+
+app = FastAPI()
+
+
+@app.post("/form/")
+def post_form(username: Annotated[str, Form()]):
+ return username
+
+
+client = TestClient(app)
+
+
+def test_single_form_field():
+ response = client.post("/form/", data={"username": "Rick"})
+ assert response.status_code == 200, response.text
+ assert response.json() == "Rick"
+
+
+def test_openapi_schema():
+ 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": {
+ "/form/": {
+ "post": {
+ "summary": "Post Form",
+ "operationId": "post_form_form__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {
+ "$ref": "#/components/schemas/Body_post_form_form__post"
+ }
+ }
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Body_post_form_form__post": {
+ "properties": {"username": {"type": "string", "title": "Username"}},
+ "type": "object",
+ "required": ["username"],
+ "title": "Body_post_form_form__post",
+ },
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
diff --git a/tests/test_multipart_installation.py b/tests/test_multipart_installation.py
index 788d9ef5a..9c3e47c49 100644
--- a/tests/test_multipart_installation.py
+++ b/tests/test_multipart_installation.py
@@ -1,3 +1,5 @@
+import warnings
+
import pytest
from fastapi import FastAPI, File, Form, UploadFile
from fastapi.dependencies.utils import (
@@ -7,7 +9,10 @@ from fastapi.dependencies.utils import (
def test_incorrect_multipart_installed_form(monkeypatch):
- monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
app = FastAPI()
@@ -17,7 +22,10 @@ def test_incorrect_multipart_installed_form(monkeypatch):
def test_incorrect_multipart_installed_file_upload(monkeypatch):
- monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
app = FastAPI()
@@ -27,7 +35,10 @@ def test_incorrect_multipart_installed_file_upload(monkeypatch):
def test_incorrect_multipart_installed_file_bytes(monkeypatch):
- monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
app = FastAPI()
@@ -37,7 +48,10 @@ def test_incorrect_multipart_installed_file_bytes(monkeypatch):
def test_incorrect_multipart_installed_multi_form(monkeypatch):
- monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
app = FastAPI()
@@ -47,7 +61,10 @@ def test_incorrect_multipart_installed_multi_form(monkeypatch):
def test_incorrect_multipart_installed_form_file(monkeypatch):
- monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.multipart.parse_options_header", raising=False)
with pytest.raises(RuntimeError, match=multipart_incorrect_install_error):
app = FastAPI()
@@ -57,50 +74,76 @@ def test_incorrect_multipart_installed_form_file(monkeypatch):
def test_no_multipart_installed(monkeypatch):
- monkeypatch.delattr("multipart.__version__", raising=False)
- with pytest.raises(RuntimeError, match=multipart_not_installed_error):
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.__version__", raising=False)
+ with pytest.raises(RuntimeError, match=multipart_not_installed_error):
+ app = FastAPI()
+
+ @app.post("/")
+ async def root(username: str = Form()):
+ return username # pragma: nocover
+
+
+def test_no_multipart_installed_file(monkeypatch):
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.__version__", raising=False)
+ with pytest.raises(RuntimeError, match=multipart_not_installed_error):
+ app = FastAPI()
+
+ @app.post("/")
+ async def root(f: UploadFile = File()):
+ return f # pragma: nocover
+
+
+def test_no_multipart_installed_file_bytes(monkeypatch):
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.__version__", raising=False)
+ with pytest.raises(RuntimeError, match=multipart_not_installed_error):
+ app = FastAPI()
+
+ @app.post("/")
+ async def root(f: bytes = File()):
+ return f # pragma: nocover
+
+
+def test_no_multipart_installed_multi_form(monkeypatch):
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.__version__", raising=False)
+ with pytest.raises(RuntimeError, match=multipart_not_installed_error):
+ app = FastAPI()
+
+ @app.post("/")
+ async def root(username: str = Form(), password: str = Form()):
+ return username # pragma: nocover
+
+
+def test_no_multipart_installed_form_file(monkeypatch):
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ monkeypatch.delattr("multipart.__version__", raising=False)
+ with pytest.raises(RuntimeError, match=multipart_not_installed_error):
+ app = FastAPI()
+
+ @app.post("/")
+ async def root(username: str = Form(), f: UploadFile = File()):
+ return username # pragma: nocover
+
+
+def test_old_multipart_installed(monkeypatch):
+ monkeypatch.setattr("python_multipart.__version__", "0.0.12")
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
app = FastAPI()
@app.post("/")
async def root(username: str = Form()):
return username # pragma: nocover
-
-
-def test_no_multipart_installed_file(monkeypatch):
- monkeypatch.delattr("multipart.__version__", raising=False)
- with pytest.raises(RuntimeError, match=multipart_not_installed_error):
- app = FastAPI()
-
- @app.post("/")
- async def root(f: UploadFile = File()):
- return f # pragma: nocover
-
-
-def test_no_multipart_installed_file_bytes(monkeypatch):
- monkeypatch.delattr("multipart.__version__", raising=False)
- with pytest.raises(RuntimeError, match=multipart_not_installed_error):
- app = FastAPI()
-
- @app.post("/")
- async def root(f: bytes = File()):
- return f # pragma: nocover
-
-
-def test_no_multipart_installed_multi_form(monkeypatch):
- monkeypatch.delattr("multipart.__version__", raising=False)
- with pytest.raises(RuntimeError, match=multipart_not_installed_error):
- app = FastAPI()
-
- @app.post("/")
- async def root(username: str = Form(), password: str = Form()):
- return username # pragma: nocover
-
-
-def test_no_multipart_installed_form_file(monkeypatch):
- monkeypatch.delattr("multipart.__version__", raising=False)
- with pytest.raises(RuntimeError, match=multipart_not_installed_error):
- app = FastAPI()
-
- @app.post("/")
- async def root(username: str = Form(), f: UploadFile = File()):
- return username # pragma: nocover
diff --git a/tests/test_openapi_examples.py b/tests/test_openapi_examples.py
index 6597e5058..b3f83ae23 100644
--- a/tests/test_openapi_examples.py
+++ b/tests/test_openapi_examples.py
@@ -155,13 +155,26 @@ def test_openapi_schema():
"requestBody": {
"content": {
"application/json": {
- "schema": {
- "allOf": [{"$ref": "#/components/schemas/Item"}],
- "title": "Item",
- "examples": [
- {"data": "Data in Body examples, example1"}
- ],
- },
+ "schema": IsDict(
+ {
+ "$ref": "#/components/schemas/Item",
+ "examples": [
+ {"data": "Data in Body examples, example1"}
+ ],
+ }
+ )
+ | IsDict(
+ {
+ # TODO: remove when deprecating Pydantic v1
+ "allOf": [
+ {"$ref": "#/components/schemas/Item"}
+ ],
+ "title": "Item",
+ "examples": [
+ {"data": "Data in Body examples, example1"}
+ ],
+ }
+ ),
"examples": {
"Example One": {
"summary": "Example One Summary",
diff --git a/tests/test_openapi_separate_input_output_schemas.py b/tests/test_openapi_separate_input_output_schemas.py
index aeb85f735..f7e045259 100644
--- a/tests/test_openapi_separate_input_output_schemas.py
+++ b/tests/test_openapi_separate_input_output_schemas.py
@@ -26,8 +26,8 @@ class Item(BaseModel):
def get_app_client(separate_input_output_schemas: bool = True) -> TestClient:
app = FastAPI(separate_input_output_schemas=separate_input_output_schemas)
- @app.post("/items/")
- def create_item(item: Item):
+ @app.post("/items/", responses={402: {"model": Item}})
+ def create_item(item: Item) -> Item:
return item
@app.post("/items-list/")
@@ -174,7 +174,23 @@ def test_openapi_schema():
"responses": {
"200": {
"description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Item-Output"
+ }
+ }
+ },
+ },
+ "402": {
+ "description": "Payment Required",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Item-Output"
+ }
+ }
+ },
},
"422": {
"description": "Validation Error",
@@ -374,7 +390,19 @@ def test_openapi_schema_no_separate():
"responses": {
"200": {
"description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"}
+ }
+ },
+ },
+ "402": {
+ "description": "Payment Required",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"}
+ }
+ },
},
"422": {
"description": "Validation Error",
diff --git a/tests/test_tutorial/test_async_sql_databases/__init__.py b/tests/test_tutorial/test_async_sql_databases/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/tests/test_tutorial/test_async_sql_databases/test_tutorial001.py b/tests/test_tutorial/test_async_sql_databases/test_tutorial001.py
deleted file mode 100644
index 13568a532..000000000
--- a/tests/test_tutorial/test_async_sql_databases/test_tutorial001.py
+++ /dev/null
@@ -1,146 +0,0 @@
-import pytest
-from fastapi import FastAPI
-from fastapi.testclient import TestClient
-
-from ...utils import needs_pydanticv1
-
-
-@pytest.fixture(name="app", scope="module")
-def get_app():
- with pytest.warns(DeprecationWarning):
- from docs_src.async_sql_databases.tutorial001 import app
- yield app
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_read(app: FastAPI):
- with TestClient(app) as client:
- note = {"text": "Foo bar", "completed": False}
- response = client.post("/notes/", json=note)
- assert response.status_code == 200, response.text
- data = response.json()
- assert data["text"] == note["text"]
- assert data["completed"] == note["completed"]
- assert "id" in data
- response = client.get("/notes/")
- assert response.status_code == 200, response.text
- assert data in response.json()
-
-
-def test_openapi_schema(app: FastAPI):
- with TestClient(app) as client:
- 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": {
- "/notes/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Notes Notes Get",
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Note"
- },
- }
- }
- },
- }
- },
- "summary": "Read Notes",
- "operationId": "read_notes_notes__get",
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Note"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Note",
- "operationId": "create_note_notes__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/NoteIn"}
- }
- },
- "required": True,
- },
- },
- }
- },
- "components": {
- "schemas": {
- "NoteIn": {
- "title": "NoteIn",
- "required": ["text", "completed"],
- "type": "object",
- "properties": {
- "text": {"title": "Text", "type": "string"},
- "completed": {"title": "Completed", "type": "boolean"},
- },
- },
- "Note": {
- "title": "Note",
- "required": ["id", "text", "completed"],
- "type": "object",
- "properties": {
- "id": {"title": "Id", "type": "integer"},
- "text": {"title": "Text", "type": "string"},
- "completed": {"title": "Completed", "type": "boolean"},
- },
- },
- "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/docs_src/sql_databases/sql_app/__init__.py b/tests/test_tutorial/test_cookie_param_models/__init__.py
similarity index 100%
rename from docs_src/sql_databases/sql_app/__init__.py
rename to tests/test_tutorial/test_cookie_param_models/__init__.py
diff --git a/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py b/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py
new file mode 100644
index 000000000..60643185a
--- /dev/null
+++ b/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py
@@ -0,0 +1,205 @@
+import importlib
+
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+from tests.utils import needs_py39, needs_py310
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial001",
+ pytest.param("tutorial001_py310", marks=needs_py310),
+ "tutorial001_an",
+ pytest.param("tutorial001_an_py39", marks=needs_py39),
+ pytest.param("tutorial001_an_py310", marks=needs_py310),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.cookie_param_models.{request.param}")
+
+ client = TestClient(mod.app)
+ return client
+
+
+def test_cookie_param_model(client: TestClient):
+ with client as c:
+ c.cookies.set("session_id", "123")
+ c.cookies.set("fatebook_tracker", "456")
+ c.cookies.set("googall_tracker", "789")
+ response = c.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == {
+ "session_id": "123",
+ "fatebook_tracker": "456",
+ "googall_tracker": "789",
+ }
+
+
+def test_cookie_param_model_defaults(client: TestClient):
+ with client as c:
+ c.cookies.set("session_id", "123")
+ response = c.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == {
+ "session_id": "123",
+ "fatebook_tracker": None,
+ "googall_tracker": None,
+ }
+
+
+def test_cookie_param_model_invalid(client: TestClient):
+ response = client.get("/items/")
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["cookie", "session_id"],
+ "msg": "Field required",
+ "input": {},
+ }
+ ]
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["cookie", "session_id"],
+ "msg": "field required",
+ }
+ ]
+ }
+ )
+ )
+
+
+def test_cookie_param_model_extra(client: TestClient):
+ with client as c:
+ c.cookies.set("session_id", "123")
+ c.cookies.set("extra", "track-me-here-too")
+ response = c.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == snapshot(
+ {"session_id": "123", "fatebook_tracker": None, "googall_tracker": None}
+ )
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "parameters": [
+ {
+ "name": "session_id",
+ "in": "cookie",
+ "required": True,
+ "schema": {"type": "string", "title": "Session Id"},
+ },
+ {
+ "name": "fatebook_tracker",
+ "in": "cookie",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Fatebook Tracker",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Fatebook Tracker",
+ }
+ ),
+ },
+ {
+ "name": "googall_tracker",
+ "in": "cookie",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Googall Tracker",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Googall Tracker",
+ }
+ ),
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py b/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py
new file mode 100644
index 000000000..30adadc8a
--- /dev/null
+++ b/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py
@@ -0,0 +1,233 @@
+import importlib
+
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ pytest.param("tutorial002", marks=needs_pydanticv2),
+ pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
+ pytest.param("tutorial002_an", marks=needs_pydanticv2),
+ pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
+ pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
+ pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.cookie_param_models.{request.param}")
+
+ client = TestClient(mod.app)
+ return client
+
+
+def test_cookie_param_model(client: TestClient):
+ with client as c:
+ c.cookies.set("session_id", "123")
+ c.cookies.set("fatebook_tracker", "456")
+ c.cookies.set("googall_tracker", "789")
+ response = c.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == {
+ "session_id": "123",
+ "fatebook_tracker": "456",
+ "googall_tracker": "789",
+ }
+
+
+def test_cookie_param_model_defaults(client: TestClient):
+ with client as c:
+ c.cookies.set("session_id", "123")
+ response = c.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == {
+ "session_id": "123",
+ "fatebook_tracker": None,
+ "googall_tracker": None,
+ }
+
+
+def test_cookie_param_model_invalid(client: TestClient):
+ response = client.get("/items/")
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["cookie", "session_id"],
+ "msg": "Field required",
+ "input": {},
+ }
+ ]
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["cookie", "session_id"],
+ "msg": "field required",
+ }
+ ]
+ }
+ )
+ )
+
+
+def test_cookie_param_model_extra(client: TestClient):
+ with client as c:
+ c.cookies.set("session_id", "123")
+ c.cookies.set("extra", "track-me-here-too")
+ response = c.get("/items/")
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ IsDict(
+ {
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["cookie", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "track-me-here-too",
+ }
+ ]
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "type": "value_error.extra",
+ "loc": ["cookie", "extra"],
+ "msg": "extra fields not permitted",
+ }
+ ]
+ }
+ )
+ )
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "parameters": [
+ {
+ "name": "session_id",
+ "in": "cookie",
+ "required": True,
+ "schema": {"type": "string", "title": "Session Id"},
+ },
+ {
+ "name": "fatebook_tracker",
+ "in": "cookie",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Fatebook Tracker",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Fatebook Tracker",
+ }
+ ),
+ },
+ {
+ "name": "googall_tracker",
+ "in": "cookie",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Googall Tracker",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Googall Tracker",
+ }
+ ),
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/docs_src/sql_databases/sql_app/tests/__init__.py b/tests/test_tutorial/test_header_param_models/__init__.py
similarity index 100%
rename from docs_src/sql_databases/sql_app/tests/__init__.py
rename to tests/test_tutorial/test_header_param_models/__init__.py
diff --git a/tests/test_tutorial/test_header_param_models/test_tutorial001.py b/tests/test_tutorial/test_header_param_models/test_tutorial001.py
new file mode 100644
index 000000000..06b2404cf
--- /dev/null
+++ b/tests/test_tutorial/test_header_param_models/test_tutorial001.py
@@ -0,0 +1,238 @@
+import importlib
+
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+from tests.utils import needs_py39, needs_py310
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial001",
+ pytest.param("tutorial001_py39", marks=needs_py39),
+ pytest.param("tutorial001_py310", marks=needs_py310),
+ "tutorial001_an",
+ pytest.param("tutorial001_an_py39", marks=needs_py39),
+ pytest.param("tutorial001_an_py310", marks=needs_py310),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.header_param_models.{request.param}")
+
+ client = TestClient(mod.app)
+ return client
+
+
+def test_header_param_model(client: TestClient):
+ response = client.get(
+ "/items/",
+ headers=[
+ ("save-data", "true"),
+ ("if-modified-since", "yesterday"),
+ ("traceparent", "123"),
+ ("x-tag", "one"),
+ ("x-tag", "two"),
+ ],
+ )
+ assert response.status_code == 200
+ assert response.json() == {
+ "host": "testserver",
+ "save_data": True,
+ "if_modified_since": "yesterday",
+ "traceparent": "123",
+ "x_tag": ["one", "two"],
+ }
+
+
+def test_header_param_model_defaults(client: TestClient):
+ response = client.get("/items/", headers=[("save-data", "true")])
+ assert response.status_code == 200
+ assert response.json() == {
+ "host": "testserver",
+ "save_data": True,
+ "if_modified_since": None,
+ "traceparent": None,
+ "x_tag": [],
+ }
+
+
+def test_header_param_model_invalid(client: TestClient):
+ response = client.get("/items/")
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ {
+ "detail": [
+ IsDict(
+ {
+ "type": "missing",
+ "loc": ["header", "save_data"],
+ "msg": "Field required",
+ "input": {
+ "x_tag": [],
+ "host": "testserver",
+ "accept": "*/*",
+ "accept-encoding": "gzip, deflate",
+ "connection": "keep-alive",
+ "user-agent": "testclient",
+ },
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "value_error.missing",
+ "loc": ["header", "save_data"],
+ "msg": "field required",
+ }
+ )
+ ]
+ }
+ )
+
+
+def test_header_param_model_extra(client: TestClient):
+ response = client.get(
+ "/items/", headers=[("save-data", "true"), ("tool", "plumbus")]
+ )
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "host": "testserver",
+ "save_data": True,
+ "if_modified_since": None,
+ "traceparent": None,
+ "x_tag": [],
+ }
+ )
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "parameters": [
+ {
+ "name": "host",
+ "in": "header",
+ "required": True,
+ "schema": {"type": "string", "title": "Host"},
+ },
+ {
+ "name": "save_data",
+ "in": "header",
+ "required": True,
+ "schema": {"type": "boolean", "title": "Save Data"},
+ },
+ {
+ "name": "if_modified_since",
+ "in": "header",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "If Modified Since",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "If Modified Since",
+ }
+ ),
+ },
+ {
+ "name": "traceparent",
+ "in": "header",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Traceparent",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Traceparent",
+ }
+ ),
+ },
+ {
+ "name": "x_tag",
+ "in": "header",
+ "required": False,
+ "schema": {
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ "title": "X Tag",
+ },
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/tests/test_tutorial/test_header_param_models/test_tutorial002.py b/tests/test_tutorial/test_header_param_models/test_tutorial002.py
new file mode 100644
index 000000000..e07655a0c
--- /dev/null
+++ b/tests/test_tutorial/test_header_param_models/test_tutorial002.py
@@ -0,0 +1,249 @@
+import importlib
+
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ pytest.param("tutorial002", marks=needs_pydanticv2),
+ pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
+ pytest.param("tutorial002_an", marks=needs_pydanticv2),
+ pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
+ pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
+ pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.header_param_models.{request.param}")
+
+ client = TestClient(mod.app)
+ client.headers.clear()
+ return client
+
+
+def test_header_param_model(client: TestClient):
+ response = client.get(
+ "/items/",
+ headers=[
+ ("save-data", "true"),
+ ("if-modified-since", "yesterday"),
+ ("traceparent", "123"),
+ ("x-tag", "one"),
+ ("x-tag", "two"),
+ ],
+ )
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "host": "testserver",
+ "save_data": True,
+ "if_modified_since": "yesterday",
+ "traceparent": "123",
+ "x_tag": ["one", "two"],
+ }
+
+
+def test_header_param_model_defaults(client: TestClient):
+ response = client.get("/items/", headers=[("save-data", "true")])
+ assert response.status_code == 200
+ assert response.json() == {
+ "host": "testserver",
+ "save_data": True,
+ "if_modified_since": None,
+ "traceparent": None,
+ "x_tag": [],
+ }
+
+
+def test_header_param_model_invalid(client: TestClient):
+ response = client.get("/items/")
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ {
+ "detail": [
+ IsDict(
+ {
+ "type": "missing",
+ "loc": ["header", "save_data"],
+ "msg": "Field required",
+ "input": {"x_tag": [], "host": "testserver"},
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "value_error.missing",
+ "loc": ["header", "save_data"],
+ "msg": "field required",
+ }
+ )
+ ]
+ }
+ )
+
+
+def test_header_param_model_extra(client: TestClient):
+ response = client.get(
+ "/items/", headers=[("save-data", "true"), ("tool", "plumbus")]
+ )
+ assert response.status_code == 422, response.text
+ assert response.json() == snapshot(
+ {
+ "detail": [
+ IsDict(
+ {
+ "type": "extra_forbidden",
+ "loc": ["header", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "value_error.extra",
+ "loc": ["header", "tool"],
+ "msg": "extra fields not permitted",
+ }
+ )
+ ]
+ }
+ )
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "parameters": [
+ {
+ "name": "host",
+ "in": "header",
+ "required": True,
+ "schema": {"type": "string", "title": "Host"},
+ },
+ {
+ "name": "save_data",
+ "in": "header",
+ "required": True,
+ "schema": {"type": "boolean", "title": "Save Data"},
+ },
+ {
+ "name": "if_modified_since",
+ "in": "header",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "If Modified Since",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "If Modified Since",
+ }
+ ),
+ },
+ {
+ "name": "traceparent",
+ "in": "header",
+ "required": False,
+ "schema": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Traceparent",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Traceparent",
+ }
+ ),
+ },
+ {
+ "name": "x_tag",
+ "in": "header",
+ "required": False,
+ "schema": {
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ "title": "X Tag",
+ },
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/docs_src/sql_databases/sql_app_py310/__init__.py b/tests/test_tutorial/test_query_param_models/__init__.py
similarity index 100%
rename from docs_src/sql_databases/sql_app_py310/__init__.py
rename to tests/test_tutorial/test_query_param_models/__init__.py
diff --git a/tests/test_tutorial/test_query_param_models/test_tutorial001.py b/tests/test_tutorial/test_query_param_models/test_tutorial001.py
new file mode 100644
index 000000000..5b7bc7b42
--- /dev/null
+++ b/tests/test_tutorial/test_query_param_models/test_tutorial001.py
@@ -0,0 +1,260 @@
+import importlib
+
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+from tests.utils import needs_py39, needs_py310
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial001",
+ pytest.param("tutorial001_py39", marks=needs_py39),
+ pytest.param("tutorial001_py310", marks=needs_py310),
+ "tutorial001_an",
+ pytest.param("tutorial001_an_py39", marks=needs_py39),
+ pytest.param("tutorial001_an_py310", marks=needs_py310),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.query_param_models.{request.param}")
+
+ client = TestClient(mod.app)
+ return client
+
+
+def test_query_param_model(client: TestClient):
+ response = client.get(
+ "/items/",
+ params={
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ },
+ )
+ assert response.status_code == 200
+ assert response.json() == {
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ }
+
+
+def test_query_param_model_defaults(client: TestClient):
+ response = client.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == {
+ "limit": 100,
+ "offset": 0,
+ "order_by": "created_at",
+ "tags": [],
+ }
+
+
+def test_query_param_model_invalid(client: TestClient):
+ response = client.get(
+ "/items/",
+ params={
+ "limit": 150,
+ "offset": -1,
+ "order_by": "invalid",
+ },
+ )
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ IsDict(
+ {
+ "detail": [
+ {
+ "type": "less_than_equal",
+ "loc": ["query", "limit"],
+ "msg": "Input should be less than or equal to 100",
+ "input": "150",
+ "ctx": {"le": 100},
+ },
+ {
+ "type": "greater_than_equal",
+ "loc": ["query", "offset"],
+ "msg": "Input should be greater than or equal to 0",
+ "input": "-1",
+ "ctx": {"ge": 0},
+ },
+ {
+ "type": "literal_error",
+ "loc": ["query", "order_by"],
+ "msg": "Input should be 'created_at' or 'updated_at'",
+ "input": "invalid",
+ "ctx": {"expected": "'created_at' or 'updated_at'"},
+ },
+ ]
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "type": "value_error.number.not_le",
+ "loc": ["query", "limit"],
+ "msg": "ensure this value is less than or equal to 100",
+ "ctx": {"limit_value": 100},
+ },
+ {
+ "type": "value_error.number.not_ge",
+ "loc": ["query", "offset"],
+ "msg": "ensure this value is greater than or equal to 0",
+ "ctx": {"limit_value": 0},
+ },
+ {
+ "type": "value_error.const",
+ "loc": ["query", "order_by"],
+ "msg": "unexpected value; permitted: 'created_at', 'updated_at'",
+ "ctx": {
+ "given": "invalid",
+ "permitted": ["created_at", "updated_at"],
+ },
+ },
+ ]
+ }
+ )
+ )
+
+
+def test_query_param_model_extra(client: TestClient):
+ response = client.get(
+ "/items/",
+ params={
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ "tool": "plumbus",
+ },
+ )
+ assert response.status_code == 200
+ assert response.json() == {
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ }
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "maximum": 100,
+ "exclusiveMinimum": 0,
+ "default": 100,
+ "title": "Limit",
+ },
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "title": "Offset",
+ },
+ },
+ {
+ "name": "order_by",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "enum": ["created_at", "updated_at"],
+ "type": "string",
+ "default": "created_at",
+ "title": "Order By",
+ },
+ },
+ {
+ "name": "tags",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ "title": "Tags",
+ },
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/tests/test_tutorial/test_query_param_models/test_tutorial002.py b/tests/test_tutorial/test_query_param_models/test_tutorial002.py
new file mode 100644
index 000000000..4432c9d8a
--- /dev/null
+++ b/tests/test_tutorial/test_query_param_models/test_tutorial002.py
@@ -0,0 +1,282 @@
+import importlib
+
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ pytest.param("tutorial002", marks=needs_pydanticv2),
+ pytest.param("tutorial002_py39", marks=[needs_py39, needs_pydanticv2]),
+ pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
+ pytest.param("tutorial002_an", marks=needs_pydanticv2),
+ pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
+ pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
+ pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_py39", marks=[needs_py39, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
+ pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.query_param_models.{request.param}")
+
+ client = TestClient(mod.app)
+ return client
+
+
+def test_query_param_model(client: TestClient):
+ response = client.get(
+ "/items/",
+ params={
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ },
+ )
+ assert response.status_code == 200
+ assert response.json() == {
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ }
+
+
+def test_query_param_model_defaults(client: TestClient):
+ response = client.get("/items/")
+ assert response.status_code == 200
+ assert response.json() == {
+ "limit": 100,
+ "offset": 0,
+ "order_by": "created_at",
+ "tags": [],
+ }
+
+
+def test_query_param_model_invalid(client: TestClient):
+ response = client.get(
+ "/items/",
+ params={
+ "limit": 150,
+ "offset": -1,
+ "order_by": "invalid",
+ },
+ )
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ IsDict(
+ {
+ "detail": [
+ {
+ "type": "less_than_equal",
+ "loc": ["query", "limit"],
+ "msg": "Input should be less than or equal to 100",
+ "input": "150",
+ "ctx": {"le": 100},
+ },
+ {
+ "type": "greater_than_equal",
+ "loc": ["query", "offset"],
+ "msg": "Input should be greater than or equal to 0",
+ "input": "-1",
+ "ctx": {"ge": 0},
+ },
+ {
+ "type": "literal_error",
+ "loc": ["query", "order_by"],
+ "msg": "Input should be 'created_at' or 'updated_at'",
+ "input": "invalid",
+ "ctx": {"expected": "'created_at' or 'updated_at'"},
+ },
+ ]
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "type": "value_error.number.not_le",
+ "loc": ["query", "limit"],
+ "msg": "ensure this value is less than or equal to 100",
+ "ctx": {"limit_value": 100},
+ },
+ {
+ "type": "value_error.number.not_ge",
+ "loc": ["query", "offset"],
+ "msg": "ensure this value is greater than or equal to 0",
+ "ctx": {"limit_value": 0},
+ },
+ {
+ "type": "value_error.const",
+ "loc": ["query", "order_by"],
+ "msg": "unexpected value; permitted: 'created_at', 'updated_at'",
+ "ctx": {
+ "given": "invalid",
+ "permitted": ["created_at", "updated_at"],
+ },
+ },
+ ]
+ }
+ )
+ )
+
+
+def test_query_param_model_extra(client: TestClient):
+ response = client.get(
+ "/items/",
+ params={
+ "limit": 10,
+ "offset": 5,
+ "order_by": "updated_at",
+ "tags": ["tag1", "tag2"],
+ "tool": "plumbus",
+ },
+ )
+ assert response.status_code == 422
+ assert response.json() == snapshot(
+ {
+ "detail": [
+ IsDict(
+ {
+ "type": "extra_forbidden",
+ "loc": ["query", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "value_error.extra",
+ "loc": ["query", "tool"],
+ "msg": "extra fields not permitted",
+ }
+ )
+ ]
+ }
+ )
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "maximum": 100,
+ "exclusiveMinimum": 0,
+ "default": 100,
+ "title": "Limit",
+ },
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0,
+ "title": "Offset",
+ },
+ },
+ {
+ "name": "order_by",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "enum": ["created_at", "updated_at"],
+ "type": "string",
+ "default": "created_at",
+ "title": "Order By",
+ },
+ },
+ {
+ "name": "tags",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ "title": "Tags",
+ },
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/docs_src/sql_databases/sql_app_py310/tests/__init__.py b/tests/test_tutorial/test_request_form_models/__init__.py
similarity index 100%
rename from docs_src/sql_databases/sql_app_py310/tests/__init__.py
rename to tests/test_tutorial/test_request_form_models/__init__.py
diff --git a/tests/test_tutorial/test_request_form_models/test_tutorial001.py b/tests/test_tutorial/test_request_form_models/test_tutorial001.py
new file mode 100644
index 000000000..46c130ee8
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial001.py
@@ -0,0 +1,232 @@
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial001 import app
+
+ client = TestClient(app)
+ return client
+
+
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {"username": "Foo"},
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ }
+ ]
+ }
+ )
+
+
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"password": "secret"},
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ }
+ ]
+ }
+ )
+
+
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
+
+
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
+
+
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial001_an.py b/tests/test_tutorial/test_request_form_models/test_tutorial001_an.py
new file mode 100644
index 000000000..4e14d89c8
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial001_an.py
@@ -0,0 +1,232 @@
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial001_an import app
+
+ client = TestClient(app)
+ return client
+
+
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {"username": "Foo"},
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ }
+ ]
+ }
+ )
+
+
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"password": "secret"},
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ }
+ ]
+ }
+ )
+
+
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
+
+
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
+
+
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial001_an_py39.py b/tests/test_tutorial/test_request_form_models/test_tutorial001_an_py39.py
new file mode 100644
index 000000000..2e6426aa7
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial001_an_py39.py
@@ -0,0 +1,240 @@
+import pytest
+from dirty_equals import IsDict
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_py39
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial001_an_py39 import app
+
+ client = TestClient(app)
+ return client
+
+
+@needs_py39
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+@needs_py39
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {"username": "Foo"},
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ }
+ ]
+ }
+ )
+
+
+@needs_py39
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"password": "secret"},
+ }
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ }
+ ]
+ }
+ )
+
+
+@needs_py39
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
+
+
+@needs_py39
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == IsDict(
+ {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+ ) | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "detail": [
+ {
+ "loc": ["body", "username"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ {
+ "loc": ["body", "password"],
+ "msg": "field required",
+ "type": "value_error.missing",
+ },
+ ]
+ }
+ )
+
+
+@needs_py39
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial002.py b/tests/test_tutorial/test_request_form_models/test_tutorial002.py
new file mode 100644
index 000000000..76f480001
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial002.py
@@ -0,0 +1,196 @@
+import pytest
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_pydanticv2
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial002 import app
+
+ client = TestClient(app)
+ return client
+
+
+@needs_pydanticv2
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+@needs_pydanticv2
+def test_post_body_extra_form(client: TestClient):
+ response = client.post(
+ "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
+ )
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "extra",
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {"username": "Foo"},
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"password": "secret"},
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+
+
+@needs_pydanticv2
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "additionalProperties": False,
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial002_an.py b/tests/test_tutorial/test_request_form_models/test_tutorial002_an.py
new file mode 100644
index 000000000..179b2977d
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial002_an.py
@@ -0,0 +1,196 @@
+import pytest
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_pydanticv2
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial002_an import app
+
+ client = TestClient(app)
+ return client
+
+
+@needs_pydanticv2
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+@needs_pydanticv2
+def test_post_body_extra_form(client: TestClient):
+ response = client.post(
+ "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
+ )
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "extra",
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {"username": "Foo"},
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"password": "secret"},
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+
+
+@needs_pydanticv2
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+
+
+@needs_pydanticv2
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "additionalProperties": False,
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial002_an_py39.py b/tests/test_tutorial/test_request_form_models/test_tutorial002_an_py39.py
new file mode 100644
index 000000000..510ad9d7c
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial002_an_py39.py
@@ -0,0 +1,203 @@
+import pytest
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_py39, needs_pydanticv2
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial002_an_py39 import app
+
+ client = TestClient(app)
+ return client
+
+
+@needs_pydanticv2
+@needs_py39
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+@needs_pydanticv2
+@needs_py39
+def test_post_body_extra_form(client: TestClient):
+ response = client.post(
+ "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
+ )
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "extra",
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+@needs_py39
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {"username": "Foo"},
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+@needs_py39
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {"password": "secret"},
+ }
+ ]
+ }
+
+
+@needs_pydanticv2
+@needs_py39
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+
+
+@needs_pydanticv2
+@needs_py39
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "missing",
+ "loc": ["body", "username"],
+ "msg": "Field required",
+ "input": {},
+ },
+ {
+ "type": "missing",
+ "loc": ["body", "password"],
+ "msg": "Field required",
+ "input": {},
+ },
+ ]
+ }
+
+
+@needs_pydanticv2
+@needs_py39
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "additionalProperties": False,
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial002_pv1.py b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py
new file mode 100644
index 000000000..249b9379d
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py
@@ -0,0 +1,189 @@
+import pytest
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_pydanticv1
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial002_pv1 import app
+
+ client = TestClient(app)
+ return client
+
+
+@needs_pydanticv1
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+@needs_pydanticv1
+def test_post_body_extra_form(client: TestClient):
+ response = client.post(
+ "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
+ )
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.extra",
+ "loc": ["body", "extra"],
+ "msg": "extra fields not permitted",
+ }
+ ]
+ }
+
+
+@needs_pydanticv1
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ }
+ ]
+ }
+
+
+@needs_pydanticv1
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ }
+ ]
+ }
+
+
+@needs_pydanticv1
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ },
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ },
+ ]
+ }
+
+
+@needs_pydanticv1
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ },
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ },
+ ]
+ }
+
+
+@needs_pydanticv1
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "additionalProperties": False,
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial002_pv1_an.py b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1_an.py
new file mode 100644
index 000000000..44cb3c32b
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1_an.py
@@ -0,0 +1,196 @@
+import pytest
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_pydanticv1
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial002_pv1_an import app
+
+ client = TestClient(app)
+ return client
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_post_body_extra_form(client: TestClient):
+ response = client.post(
+ "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
+ )
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.extra",
+ "loc": ["body", "extra"],
+ "msg": "extra fields not permitted",
+ }
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ }
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ }
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ },
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ },
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ },
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ },
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "additionalProperties": False,
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_request_form_models/test_tutorial002_pv1_an_p39.py b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1_an_p39.py
new file mode 100644
index 000000000..899549e40
--- /dev/null
+++ b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1_an_p39.py
@@ -0,0 +1,203 @@
+import pytest
+from fastapi.testclient import TestClient
+
+from tests.utils import needs_py39, needs_pydanticv1
+
+
+@pytest.fixture(name="client")
+def get_client():
+ from docs_src.request_form_models.tutorial002_pv1_an_py39 import app
+
+ client = TestClient(app)
+ return client
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+def test_post_body_form(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo", "password": "secret"})
+ assert response.status_code == 200
+ assert response.json() == {"username": "Foo", "password": "secret"}
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+def test_post_body_extra_form(client: TestClient):
+ response = client.post(
+ "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
+ )
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.extra",
+ "loc": ["body", "extra"],
+ "msg": "extra fields not permitted",
+ }
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+def test_post_body_form_no_password(client: TestClient):
+ response = client.post("/login/", data={"username": "Foo"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ }
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+def test_post_body_form_no_username(client: TestClient):
+ response = client.post("/login/", data={"password": "secret"})
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ }
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+def test_post_body_form_no_data(client: TestClient):
+ response = client.post("/login/")
+ assert response.status_code == 422
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ },
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ },
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+def test_post_body_json(client: TestClient):
+ response = client.post("/login/", json={"username": "Foo", "password": "secret"})
+ assert response.status_code == 422, response.text
+ assert response.json() == {
+ "detail": [
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "username"],
+ "msg": "field required",
+ },
+ {
+ "type": "value_error.missing",
+ "loc": ["body", "password"],
+ "msg": "field required",
+ },
+ ]
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+@needs_py39
+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": {
+ "/login/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Login",
+ "operationId": "login_login__post",
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {"$ref": "#/components/schemas/FormData"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "FormData": {
+ "properties": {
+ "username": {"type": "string", "title": "Username"},
+ "password": {"type": "string", "title": "Password"},
+ },
+ "additionalProperties": False,
+ "type": "object",
+ "required": ["username", "password"],
+ "title": "FormData",
+ },
+ "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_schema_extra_example/test_tutorial001_py310_pv1.py b/tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1_py310.py
similarity index 98%
rename from tests/test_tutorial/test_schema_extra_example/test_tutorial001_py310_pv1.py
rename to tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1_py310.py
index e036d6b68..b2a4d15b1 100644
--- a/tests/test_tutorial/test_schema_extra_example/test_tutorial001_py310_pv1.py
+++ b/tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1_py310.py
@@ -6,7 +6,7 @@ from ...utils import needs_py310, needs_pydanticv1
@pytest.fixture(name="client")
def get_client():
- from docs_src.schema_extra_example.tutorial001_py310_pv1 import app
+ from docs_src.schema_extra_example.tutorial001_pv1_py310 import app
client = TestClient(app)
return client
diff --git a/tests/test_tutorial/test_sql_databases/test_sql_databases.py b/tests/test_tutorial/test_sql_databases/test_sql_databases.py
deleted file mode 100644
index e3e2b36a8..000000000
--- a/tests/test_tutorial/test_sql_databases/test_sql_databases.py
+++ /dev/null
@@ -1,419 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_pydanticv1
-
-
-@pytest.fixture(scope="module")
-def client(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./sql_app.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app import main
-
- # Ensure import side effects are re-executed
- importlib.reload(main)
- with TestClient(main.app) as c:
- yield c
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_nonexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-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": {
- "/users/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- }
- },
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- }
- },
- },
- "components": {
- "schemas": {
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"},
- ),
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "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_sql_databases/test_sql_databases_middleware.py b/tests/test_tutorial/test_sql_databases/test_sql_databases_middleware.py
deleted file mode 100644
index 73b97e09d..000000000
--- a/tests/test_tutorial/test_sql_databases/test_sql_databases_middleware.py
+++ /dev/null
@@ -1,421 +0,0 @@
-import importlib
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_pydanticv1
-
-
-@pytest.fixture(scope="module")
-def client():
- test_db = Path("./sql_app.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app import alt_main
-
- # Ensure import side effects are re-executed
- importlib.reload(alt_main)
-
- with TestClient(alt_main.app) as c:
- yield c
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_nonexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-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": {
- "/users/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- }
- },
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- }
- },
- },
- "components": {
- "schemas": {
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"},
- ),
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "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_sql_databases/test_sql_databases_middleware_py310.py b/tests/test_tutorial/test_sql_databases/test_sql_databases_middleware_py310.py
deleted file mode 100644
index a078f012a..000000000
--- a/tests/test_tutorial/test_sql_databases/test_sql_databases_middleware_py310.py
+++ /dev/null
@@ -1,433 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310, needs_pydanticv1
-
-
-@pytest.fixture(scope="module")
-def client(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./sql_app.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app_py310 import alt_main
-
- # Ensure import side effects are re-executed
- importlib.reload(alt_main)
-
- with TestClient(alt_main.app) as c:
- yield c
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_nonexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-@needs_py310
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-@needs_py310
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-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": {
- "/users/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- }
- },
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- }
- },
- },
- "components": {
- "schemas": {
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"},
- ),
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "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_sql_databases/test_sql_databases_middleware_py39.py b/tests/test_tutorial/test_sql_databases/test_sql_databases_middleware_py39.py
deleted file mode 100644
index a5da07ac6..000000000
--- a/tests/test_tutorial/test_sql_databases/test_sql_databases_middleware_py39.py
+++ /dev/null
@@ -1,433 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39, needs_pydanticv1
-
-
-@pytest.fixture(scope="module")
-def client(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./sql_app.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app_py39 import alt_main
-
- # Ensure import side effects are re-executed
- importlib.reload(alt_main)
-
- with TestClient(alt_main.app) as c:
- yield c
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_nonexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-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": {
- "/users/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- }
- },
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- }
- },
- },
- "components": {
- "schemas": {
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"},
- ),
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "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_sql_databases/test_sql_databases_py310.py b/tests/test_tutorial/test_sql_databases/test_sql_databases_py310.py
deleted file mode 100644
index 5a9106598..000000000
--- a/tests/test_tutorial/test_sql_databases/test_sql_databases_py310.py
+++ /dev/null
@@ -1,432 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310, needs_pydanticv1
-
-
-@pytest.fixture(scope="module", name="client")
-def get_client(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./sql_app.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app_py310 import main
-
- # Ensure import side effects are re-executed
- importlib.reload(main)
- with TestClient(main.app) as c:
- yield c
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_nonexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-@needs_py310
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-@needs_py310
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-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": {
- "/users/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- }
- },
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- }
- },
- },
- "components": {
- "schemas": {
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"},
- ),
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "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_sql_databases/test_sql_databases_py39.py b/tests/test_tutorial/test_sql_databases/test_sql_databases_py39.py
deleted file mode 100644
index a354ba905..000000000
--- a/tests/test_tutorial/test_sql_databases/test_sql_databases_py39.py
+++ /dev/null
@@ -1,432 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39, needs_pydanticv1
-
-
-@pytest.fixture(scope="module", name="client")
-def get_client(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./sql_app.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app_py39 import main
-
- # Ensure import side effects are re-executed
- importlib.reload(main)
- with TestClient(main.app) as c:
- yield c
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_nonexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-@needs_py39
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-@needs_py39
-# TODO: pv2 add Pydantic v2 version
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-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": {
- "/users/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- },
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- }
- },
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- }
- },
- },
- "components": {
- "schemas": {
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"},
- ),
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "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_sql_databases/test_testing_databases.py b/tests/test_tutorial/test_sql_databases/test_testing_databases.py
deleted file mode 100644
index ce6ce230c..000000000
--- a/tests/test_tutorial/test_sql_databases/test_testing_databases.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-
-from ...utils import needs_pydanticv1
-
-
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_testing_dbs(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./test.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app.tests import test_sql_app
-
- # Ensure import side effects are re-executed
- importlib.reload(test_sql_app)
- test_sql_app.test_create_user()
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
diff --git a/tests/test_tutorial/test_sql_databases/test_testing_databases_py310.py b/tests/test_tutorial/test_sql_databases/test_testing_databases_py310.py
deleted file mode 100644
index 545d63c2a..000000000
--- a/tests/test_tutorial/test_sql_databases/test_testing_databases_py310.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-
-from ...utils import needs_py310, needs_pydanticv1
-
-
-@needs_py310
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_testing_dbs_py39(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./test.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app_py310.tests import test_sql_app
-
- # Ensure import side effects are re-executed
- importlib.reload(test_sql_app)
- test_sql_app.test_create_user()
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
diff --git a/tests/test_tutorial/test_sql_databases/test_testing_databases_py39.py b/tests/test_tutorial/test_sql_databases/test_testing_databases_py39.py
deleted file mode 100644
index 99bfd3fa8..000000000
--- a/tests/test_tutorial/test_sql_databases/test_testing_databases_py39.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import importlib
-import os
-from pathlib import Path
-
-import pytest
-
-from ...utils import needs_py39, needs_pydanticv1
-
-
-@needs_py39
-# TODO: pv2 add version with Pydantic v2
-@needs_pydanticv1
-def test_testing_dbs_py39(tmp_path_factory: pytest.TempPathFactory):
- tmp_path = tmp_path_factory.mktemp("data")
- cwd = os.getcwd()
- os.chdir(tmp_path)
- test_db = Path("./test.db")
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases.sql_app_py39.tests import test_sql_app
-
- # Ensure import side effects are re-executed
- importlib.reload(test_sql_app)
- test_sql_app.test_create_user()
- if test_db.is_file(): # pragma: nocover
- test_db.unlink()
- os.chdir(cwd)
diff --git a/tests/test_tutorial/test_sql_databases/test_tutorial001.py b/tests/test_tutorial/test_sql_databases/test_tutorial001.py
new file mode 100644
index 000000000..cc7e590df
--- /dev/null
+++ b/tests/test_tutorial/test_sql_databases/test_tutorial001.py
@@ -0,0 +1,373 @@
+import importlib
+import warnings
+
+import pytest
+from dirty_equals import IsDict, IsInt
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+from sqlalchemy import StaticPool
+from sqlmodel import SQLModel, create_engine
+from sqlmodel.main import default_registry
+
+from tests.utils import needs_py39, needs_py310
+
+
+def clear_sqlmodel():
+ # Clear the tables in the metadata for the default base model
+ SQLModel.metadata.clear()
+ # Clear the Models associated with the registry, to avoid warnings
+ default_registry.dispose()
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial001",
+ pytest.param("tutorial001_py39", marks=needs_py39),
+ pytest.param("tutorial001_py310", marks=needs_py310),
+ "tutorial001_an",
+ pytest.param("tutorial001_an_py39", marks=needs_py39),
+ pytest.param("tutorial001_an_py310", marks=needs_py310),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ clear_sqlmodel()
+ # TODO: remove when updating SQL tutorial to use new lifespan API
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ mod = importlib.import_module(f"docs_src.sql_databases.{request.param}")
+ clear_sqlmodel()
+ importlib.reload(mod)
+ mod.sqlite_url = "sqlite://"
+ mod.engine = create_engine(
+ mod.sqlite_url, connect_args={"check_same_thread": False}, poolclass=StaticPool
+ )
+
+ with TestClient(mod.app) as c:
+ yield c
+
+
+def test_crud_app(client: TestClient):
+ # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor
+ # this if using obj.model_validate becomes independent of Pydantic v2
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ # No heroes before creating
+ response = client.get("heroes/")
+ assert response.status_code == 200, response.text
+ assert response.json() == []
+
+ # Create a hero
+ response = client.post(
+ "/heroes/",
+ json={
+ "id": 999,
+ "name": "Dead Pond",
+ "age": 30,
+ "secret_name": "Dive Wilson",
+ },
+ )
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {"age": 30, "secret_name": "Dive Wilson", "id": 999, "name": "Dead Pond"}
+ )
+
+ # Read a hero
+ hero_id = response.json()["id"]
+ response = client.get(f"/heroes/{hero_id}")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {"name": "Dead Pond", "age": 30, "id": 999, "secret_name": "Dive Wilson"}
+ )
+
+ # Read all heroes
+ # Create more heroes first
+ response = client.post(
+ "/heroes/",
+ json={"name": "Spider-Boy", "age": 18, "secret_name": "Pedro Parqueador"},
+ )
+ assert response.status_code == 200, response.text
+ response = client.post(
+ "/heroes/", json={"name": "Rusty-Man", "secret_name": "Tommy Sharp"}
+ )
+ assert response.status_code == 200, response.text
+
+ response = client.get("/heroes/")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ [
+ {
+ "name": "Dead Pond",
+ "age": 30,
+ "id": IsInt(),
+ "secret_name": "Dive Wilson",
+ },
+ {
+ "name": "Spider-Boy",
+ "age": 18,
+ "id": IsInt(),
+ "secret_name": "Pedro Parqueador",
+ },
+ {
+ "name": "Rusty-Man",
+ "age": None,
+ "id": IsInt(),
+ "secret_name": "Tommy Sharp",
+ },
+ ]
+ )
+
+ response = client.get("/heroes/?offset=1&limit=1")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ [
+ {
+ "name": "Spider-Boy",
+ "age": 18,
+ "id": IsInt(),
+ "secret_name": "Pedro Parqueador",
+ }
+ ]
+ )
+
+ # Delete a hero
+ response = client.delete(f"/heroes/{hero_id}")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot({"ok": True})
+
+ response = client.get(f"/heroes/{hero_id}")
+ assert response.status_code == 404, response.text
+
+ response = client.delete(f"/heroes/{hero_id}")
+ assert response.status_code == 404, response.text
+ assert response.json() == snapshot({"detail": "Hero not found"})
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/heroes/": {
+ "post": {
+ "summary": "Create Hero",
+ "operationId": "create_hero_heroes__post",
+ "requestBody": {
+ "required": True,
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Hero"}
+ }
+ },
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Hero"}
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ "get": {
+ "summary": "Read Heroes",
+ "operationId": "read_heroes_heroes__get",
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "default": 0,
+ "title": "Offset",
+ },
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "maximum": 100,
+ "default": 100,
+ "title": "Limit",
+ },
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Hero"
+ },
+ "title": "Response Read Heroes Heroes Get",
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ },
+ "/heroes/{hero_id}": {
+ "get": {
+ "summary": "Read Hero",
+ "operationId": "read_hero_heroes__hero_id__get",
+ "parameters": [
+ {
+ "name": "hero_id",
+ "in": "path",
+ "required": True,
+ "schema": {"type": "integer", "title": "Hero Id"},
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Hero"}
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ "delete": {
+ "summary": "Delete Hero",
+ "operationId": "delete_hero_heroes__hero_id__delete",
+ "parameters": [
+ {
+ "name": "hero_id",
+ "in": "path",
+ "required": True,
+ "schema": {"type": "integer", "title": "Hero Id"},
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ },
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "Hero": {
+ "properties": {
+ "id": IsDict(
+ {
+ "anyOf": [{"type": "integer"}, {"type": "null"}],
+ "title": "Id",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "integer",
+ "title": "Id",
+ }
+ ),
+ "name": {"type": "string", "title": "Name"},
+ "age": IsDict(
+ {
+ "anyOf": [{"type": "integer"}, {"type": "null"}],
+ "title": "Age",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "integer",
+ "title": "Age",
+ }
+ ),
+ "secret_name": {"type": "string", "title": "Secret Name"},
+ },
+ "type": "object",
+ "required": ["name", "secret_name"],
+ "title": "Hero",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )
diff --git a/tests/test_tutorial/test_sql_databases/test_tutorial002.py b/tests/test_tutorial/test_sql_databases/test_tutorial002.py
new file mode 100644
index 000000000..68c1966f5
--- /dev/null
+++ b/tests/test_tutorial/test_sql_databases/test_tutorial002.py
@@ -0,0 +1,481 @@
+import importlib
+import warnings
+
+import pytest
+from dirty_equals import IsDict, IsInt
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+from sqlalchemy import StaticPool
+from sqlmodel import SQLModel, create_engine
+from sqlmodel.main import default_registry
+
+from tests.utils import needs_py39, needs_py310
+
+
+def clear_sqlmodel():
+ # Clear the tables in the metadata for the default base model
+ SQLModel.metadata.clear()
+ # Clear the Models associated with the registry, to avoid warnings
+ default_registry.dispose()
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial002",
+ pytest.param("tutorial002_py39", marks=needs_py39),
+ pytest.param("tutorial002_py310", marks=needs_py310),
+ "tutorial002_an",
+ pytest.param("tutorial002_an_py39", marks=needs_py39),
+ pytest.param("tutorial002_an_py310", marks=needs_py310),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ clear_sqlmodel()
+ # TODO: remove when updating SQL tutorial to use new lifespan API
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ mod = importlib.import_module(f"docs_src.sql_databases.{request.param}")
+ clear_sqlmodel()
+ importlib.reload(mod)
+ mod.sqlite_url = "sqlite://"
+ mod.engine = create_engine(
+ mod.sqlite_url, connect_args={"check_same_thread": False}, poolclass=StaticPool
+ )
+
+ with TestClient(mod.app) as c:
+ yield c
+
+
+def test_crud_app(client: TestClient):
+ # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor
+ # this if using obj.model_validate becomes independent of Pydantic v2
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ # No heroes before creating
+ response = client.get("heroes/")
+ assert response.status_code == 200, response.text
+ assert response.json() == []
+
+ # Create a hero
+ response = client.post(
+ "/heroes/",
+ json={
+ "id": 9000,
+ "name": "Dead Pond",
+ "age": 30,
+ "secret_name": "Dive Wilson",
+ },
+ )
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {"age": 30, "id": IsInt(), "name": "Dead Pond"}
+ )
+ assert (
+ response.json()["id"] != 9000
+ ), "The ID should be generated by the database"
+
+ # Read a hero
+ hero_id = response.json()["id"]
+ response = client.get(f"/heroes/{hero_id}")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {"name": "Dead Pond", "age": 30, "id": IsInt()}
+ )
+
+ # Read all heroes
+ # Create more heroes first
+ response = client.post(
+ "/heroes/",
+ json={"name": "Spider-Boy", "age": 18, "secret_name": "Pedro Parqueador"},
+ )
+ assert response.status_code == 200, response.text
+ response = client.post(
+ "/heroes/", json={"name": "Rusty-Man", "secret_name": "Tommy Sharp"}
+ )
+ assert response.status_code == 200, response.text
+
+ response = client.get("/heroes/")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ [
+ {"name": "Dead Pond", "age": 30, "id": IsInt()},
+ {"name": "Spider-Boy", "age": 18, "id": IsInt()},
+ {"name": "Rusty-Man", "age": None, "id": IsInt()},
+ ]
+ )
+
+ response = client.get("/heroes/?offset=1&limit=1")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ [{"name": "Spider-Boy", "age": 18, "id": IsInt()}]
+ )
+
+ # Update a hero
+ response = client.patch(
+ f"/heroes/{hero_id}", json={"name": "Dog Pond", "age": None}
+ )
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {"name": "Dog Pond", "age": None, "id": hero_id}
+ )
+
+ # Get updated hero
+ response = client.get(f"/heroes/{hero_id}")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {"name": "Dog Pond", "age": None, "id": hero_id}
+ )
+
+ # Delete a hero
+ response = client.delete(f"/heroes/{hero_id}")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot({"ok": True})
+
+ # The hero is no longer found
+ response = client.get(f"/heroes/{hero_id}")
+ assert response.status_code == 404, response.text
+
+ # Delete a hero that does not exist
+ response = client.delete(f"/heroes/{hero_id}")
+ assert response.status_code == 404, response.text
+ assert response.json() == snapshot({"detail": "Hero not found"})
+
+ # Update a hero that does not exist
+ response = client.patch(f"/heroes/{hero_id}", json={"name": "Dog Pond"})
+ assert response.status_code == 404, response.text
+ assert response.json() == snapshot({"detail": "Hero not found"})
+
+
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/heroes/": {
+ "post": {
+ "summary": "Create Hero",
+ "operationId": "create_hero_heroes__post",
+ "requestBody": {
+ "required": True,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HeroCreate"
+ }
+ }
+ },
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HeroPublic"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ "get": {
+ "summary": "Read Heroes",
+ "operationId": "read_heroes_heroes__get",
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "default": 0,
+ "title": "Offset",
+ },
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": False,
+ "schema": {
+ "type": "integer",
+ "maximum": 100,
+ "default": 100,
+ "title": "Limit",
+ },
+ },
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/HeroPublic"
+ },
+ "title": "Response Read Heroes Heroes Get",
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ },
+ "/heroes/{hero_id}": {
+ "get": {
+ "summary": "Read Hero",
+ "operationId": "read_hero_heroes__hero_id__get",
+ "parameters": [
+ {
+ "name": "hero_id",
+ "in": "path",
+ "required": True,
+ "schema": {"type": "integer", "title": "Hero Id"},
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HeroPublic"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ "patch": {
+ "summary": "Update Hero",
+ "operationId": "update_hero_heroes__hero_id__patch",
+ "parameters": [
+ {
+ "name": "hero_id",
+ "in": "path",
+ "required": True,
+ "schema": {"type": "integer", "title": "Hero Id"},
+ }
+ ],
+ "requestBody": {
+ "required": True,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HeroUpdate"
+ }
+ }
+ },
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HeroPublic"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ "delete": {
+ "summary": "Delete Hero",
+ "operationId": "delete_hero_heroes__hero_id__delete",
+ "parameters": [
+ {
+ "name": "hero_id",
+ "in": "path",
+ "required": True,
+ "schema": {"type": "integer", "title": "Hero Id"},
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ },
+ },
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "properties": {
+ "detail": {
+ "items": {
+ "$ref": "#/components/schemas/ValidationError"
+ },
+ "type": "array",
+ "title": "Detail",
+ }
+ },
+ "type": "object",
+ "title": "HTTPValidationError",
+ },
+ "HeroCreate": {
+ "properties": {
+ "name": {"type": "string", "title": "Name"},
+ "age": IsDict(
+ {
+ "anyOf": [{"type": "integer"}, {"type": "null"}],
+ "title": "Age",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "integer",
+ "title": "Age",
+ }
+ ),
+ "secret_name": {"type": "string", "title": "Secret Name"},
+ },
+ "type": "object",
+ "required": ["name", "secret_name"],
+ "title": "HeroCreate",
+ },
+ "HeroPublic": {
+ "properties": {
+ "name": {"type": "string", "title": "Name"},
+ "age": IsDict(
+ {
+ "anyOf": [{"type": "integer"}, {"type": "null"}],
+ "title": "Age",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "integer",
+ "title": "Age",
+ }
+ ),
+ "id": {"type": "integer", "title": "Id"},
+ },
+ "type": "object",
+ "required": ["name", "id"],
+ "title": "HeroPublic",
+ },
+ "HeroUpdate": {
+ "properties": {
+ "name": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Name",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Name",
+ }
+ ),
+ "age": IsDict(
+ {
+ "anyOf": [{"type": "integer"}, {"type": "null"}],
+ "title": "Age",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "integer",
+ "title": "Age",
+ }
+ ),
+ "secret_name": IsDict(
+ {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Secret Name",
+ }
+ )
+ | IsDict(
+ # TODO: remove when deprecating Pydantic v1
+ {
+ "type": "string",
+ "title": "Secret Name",
+ }
+ ),
+ },
+ "type": "object",
+ "title": "HeroUpdate",
+ },
+ "ValidationError": {
+ "properties": {
+ "loc": {
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ "type": "array",
+ "title": "Location",
+ },
+ "msg": {"type": "string", "title": "Message"},
+ "type": {"type": "string", "title": "Error Type"},
+ },
+ "type": "object",
+ "required": ["loc", "msg", "type"],
+ "title": "ValidationError",
+ },
+ }
+ },
+ }
+ )