Sync fastapi docs from 50fa3f7c on 2026-01-11
This commit is contained in:
+3
-3
@@ -4,9 +4,9 @@ This is a mirror of the Fastapi repository.
|
|||||||
|
|
||||||
**Synced from:** https://github.com/tiangolo/fastapi.git
|
**Synced from:** https://github.com/tiangolo/fastapi.git
|
||||||
**Branch:** master
|
**Branch:** master
|
||||||
**Commit:** b5ca13249e3f2002c70c3f2de528a128af2008f7
|
**Commit:** 50fa3f7c882cea592e5488a50354bfc016ea65bb
|
||||||
**Sync Date:** 2025-12-07
|
**Sync Date:** 2026-01-11
|
||||||
**Content:** Complete repository mirror
|
**Content:** Paths: docs, docs_src
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,158 +0,0 @@
|
|||||||
labels: [question]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for your interest in FastAPI! 🚀
|
|
||||||
|
|
||||||
Please follow these instructions, fill every question, and do every step. 🙏
|
|
||||||
|
|
||||||
I'm asking this because answering questions and solving problems in GitHub is what consumes most of the time.
|
|
||||||
|
|
||||||
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling questions.
|
|
||||||
|
|
||||||
All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
|
|
||||||
|
|
||||||
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
|
|
||||||
|
|
||||||
By asking questions in a structured way (following this) it will be much easier to help you.
|
|
||||||
|
|
||||||
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
|
|
||||||
|
|
||||||
As there are too many questions, I'll have to discard and close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
|
|
||||||
- type: checkboxes
|
|
||||||
id: checks
|
|
||||||
attributes:
|
|
||||||
label: First Check
|
|
||||||
description: Please confirm and check all the following options.
|
|
||||||
options:
|
|
||||||
- label: I added a very descriptive title here.
|
|
||||||
required: true
|
|
||||||
- label: I used the GitHub search to find a similar question and didn't find it.
|
|
||||||
required: true
|
|
||||||
- label: I searched the FastAPI documentation, with the integrated search.
|
|
||||||
required: true
|
|
||||||
- label: I already searched in Google "How to X in FastAPI" and didn't find any information.
|
|
||||||
required: true
|
|
||||||
- label: I already read and followed all the tutorial in the docs and didn't find an answer.
|
|
||||||
required: true
|
|
||||||
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/pydantic/pydantic).
|
|
||||||
required: true
|
|
||||||
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
|
|
||||||
required: true
|
|
||||||
- label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
|
|
||||||
required: true
|
|
||||||
- type: checkboxes
|
|
||||||
id: help
|
|
||||||
attributes:
|
|
||||||
label: Commit to Help
|
|
||||||
description: |
|
|
||||||
After submitting this, I commit to one of:
|
|
||||||
|
|
||||||
* Read open questions until I find 2 where I can help someone and add a comment to help there.
|
|
||||||
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
|
|
||||||
* Review one Pull Request by downloading the code and following [all the review process](https://fastapi.tiangolo.com/help-fastapi/#review-pull-requests).
|
|
||||||
|
|
||||||
options:
|
|
||||||
- label: I commit to help with one of those options 👆
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: example
|
|
||||||
attributes:
|
|
||||||
label: Example Code
|
|
||||||
description: |
|
|
||||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
|
|
||||||
|
|
||||||
If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
|
|
||||||
|
|
||||||
placeholder: |
|
|
||||||
from fastapi import FastAPI
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
|
||||||
def read_root():
|
|
||||||
return {"Hello": "World"}
|
|
||||||
render: python
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: description
|
|
||||||
attributes:
|
|
||||||
label: Description
|
|
||||||
description: |
|
|
||||||
What is the problem, question, or error?
|
|
||||||
|
|
||||||
Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
|
|
||||||
placeholder: |
|
|
||||||
* Open the browser and call the endpoint `/`.
|
|
||||||
* It returns a JSON with `{"Hello": "World"}`.
|
|
||||||
* But I expected it to return `{"Hello": "Sara"}`.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: os
|
|
||||||
attributes:
|
|
||||||
label: Operating System
|
|
||||||
description: What operating system are you on?
|
|
||||||
multiple: true
|
|
||||||
options:
|
|
||||||
- Linux
|
|
||||||
- Windows
|
|
||||||
- macOS
|
|
||||||
- Other
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: os-details
|
|
||||||
attributes:
|
|
||||||
label: Operating System Details
|
|
||||||
description: You can add more details about your operating system here, in particular if you chose "Other".
|
|
||||||
- type: input
|
|
||||||
id: fastapi-version
|
|
||||||
attributes:
|
|
||||||
label: FastAPI Version
|
|
||||||
description: |
|
|
||||||
What FastAPI version are you using?
|
|
||||||
|
|
||||||
You can find the FastAPI version with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python -c "import fastapi; print(fastapi.__version__)"
|
|
||||||
```
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: pydantic-version
|
|
||||||
attributes:
|
|
||||||
label: Pydantic Version
|
|
||||||
description: |
|
|
||||||
What Pydantic version are you using?
|
|
||||||
|
|
||||||
You can find the Pydantic version with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python -c "import pydantic; print(pydantic.version.VERSION)"
|
|
||||||
```
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: python-version
|
|
||||||
attributes:
|
|
||||||
label: Python Version
|
|
||||||
description: |
|
|
||||||
What Python version are you using?
|
|
||||||
|
|
||||||
You can find the Python version with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python --version
|
|
||||||
```
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: context
|
|
||||||
attributes:
|
|
||||||
label: Additional Context
|
|
||||||
description: Add any additional context information or screenshots you think are useful.
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
labels: [lang-all]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for your interest in helping translate the FastAPI docs! 🌍
|
|
||||||
|
|
||||||
Please follow these instructions carefully to propose a new language translation. 🙏
|
|
||||||
|
|
||||||
This structured process helps ensure translations can be properly maintained long-term.
|
|
||||||
- type: checkboxes
|
|
||||||
id: checks
|
|
||||||
attributes:
|
|
||||||
label: Initial Checks
|
|
||||||
description: Please confirm and check all the following options.
|
|
||||||
options:
|
|
||||||
- label: I checked that this language is not already being translated in FastAPI docs.
|
|
||||||
required: true
|
|
||||||
- label: I searched existing discussions to ensure no one else proposed this language.
|
|
||||||
required: true
|
|
||||||
- label: I am a native speaker of the language I want to help translate.
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: language
|
|
||||||
attributes:
|
|
||||||
label: Target Language
|
|
||||||
description: What language do you want to translate the FastAPI docs into?
|
|
||||||
placeholder: e.g. Latin
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: additional_info
|
|
||||||
attributes:
|
|
||||||
label: Additional Information
|
|
||||||
description: Any other relevant information about your translation proposal
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Translations are automatized with AI and then reviewed by native speakers. 🤖 🙋
|
|
||||||
|
|
||||||
This allows us to keep them consistent and up-to-date.
|
|
||||||
|
|
||||||
If there are several native speakers commenting on this discussion and
|
|
||||||
committing to help review new translations, the FastAPI team will review it
|
|
||||||
and potentially make it an official translation. 😎
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
github: [tiangolo]
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: Security Contact
|
|
||||||
about: Please report security vulnerabilities to security@tiangolo.com
|
|
||||||
- name: Question or Problem
|
|
||||||
about: Ask a question or ask about a problem in GitHub Discussions.
|
|
||||||
url: https://github.com/fastapi/fastapi/discussions/categories/questions
|
|
||||||
- name: Feature Request
|
|
||||||
about: To suggest an idea or ask about a feature, please start with a question saying what you would like to achieve. There might be a way to do it already.
|
|
||||||
url: https://github.com/fastapi/fastapi/discussions/categories/questions
|
|
||||||
- name: Show and tell
|
|
||||||
about: Show what you built with FastAPI or to be used with FastAPI.
|
|
||||||
url: https://github.com/fastapi/fastapi/discussions/categories/show-and-tell
|
|
||||||
- name: Translations
|
|
||||||
about: Coordinate translations in GitHub Discussions.
|
|
||||||
url: https://github.com/fastapi/fastapi/discussions/categories/translations
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
name: Privileged
|
|
||||||
description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. 👇
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for your interest in FastAPI! 🚀
|
|
||||||
|
|
||||||
If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions) instead.
|
|
||||||
- type: checkboxes
|
|
||||||
id: privileged
|
|
||||||
attributes:
|
|
||||||
label: Privileged issue
|
|
||||||
description: Confirm that you are allowed to create an issue here.
|
|
||||||
options:
|
|
||||||
- label: I'm @tiangolo or he asked me directly to create an issue here.
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: content
|
|
||||||
attributes:
|
|
||||||
label: Issue Content
|
|
||||||
description: Add the content of the issue here.
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
# GitHub Actions
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
commit-message:
|
|
||||||
prefix: ⬆
|
|
||||||
# Python
|
|
||||||
- package-ecosystem: "pip"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "monthly"
|
|
||||||
commit-message:
|
|
||||||
prefix: ⬆
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
docs:
|
|
||||||
- all:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- docs/en/docs/**
|
|
||||||
- docs_src/**
|
|
||||||
- all-globs-to-all-files:
|
|
||||||
- '!fastapi/**'
|
|
||||||
- '!pyproject.toml'
|
|
||||||
- '!docs/en/data/sponsors.yml'
|
|
||||||
- '!docs/en/overrides/main.html'
|
|
||||||
|
|
||||||
lang-all:
|
|
||||||
- all:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- docs/*/docs/**
|
|
||||||
- all-globs-to-all-files:
|
|
||||||
- '!docs/en/docs/**'
|
|
||||||
- '!docs/*/**/_*.md'
|
|
||||||
- '!fastapi/**'
|
|
||||||
- '!pyproject.toml'
|
|
||||||
|
|
||||||
internal:
|
|
||||||
- all:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- .github/**
|
|
||||||
- scripts/**
|
|
||||||
- .gitignore
|
|
||||||
- .pre-commit-config.yaml
|
|
||||||
- pdm_build.py
|
|
||||||
- requirements*.txt
|
|
||||||
- docs/en/data/sponsors.yml
|
|
||||||
- docs/en/overrides/main.html
|
|
||||||
- all-globs-to-all-files:
|
|
||||||
- '!docs/*/docs/**'
|
|
||||||
- '!fastapi/**'
|
|
||||||
- '!pyproject.toml'
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
name: Add to Project
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
issues:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- reopened
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
add-to-project:
|
|
||||||
name: Add to project
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/add-to-project@v1.0.2
|
|
||||||
with:
|
|
||||||
project-url: https://github.com/orgs/fastapi/projects/2
|
|
||||||
github-token: ${{ secrets.PROJECTS_TOKEN }}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
name: Build Docs
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
changes:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# Required permissions
|
|
||||||
permissions:
|
|
||||||
pull-requests: read
|
|
||||||
# Set job outputs to values from filter step
|
|
||||||
outputs:
|
|
||||||
docs: ${{ steps.filter.outputs.docs }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
# For pull requests it's not necessary to checkout the code but for the main branch it is
|
|
||||||
- uses: dorny/paths-filter@v3
|
|
||||||
id: filter
|
|
||||||
with:
|
|
||||||
filters: |
|
|
||||||
docs:
|
|
||||||
- README.md
|
|
||||||
- docs/**
|
|
||||||
- docs_src/**
|
|
||||||
- requirements-docs.txt
|
|
||||||
- pyproject.toml
|
|
||||||
- mkdocs.yml
|
|
||||||
- mkdocs.env.yml
|
|
||||||
- .github/workflows/build-docs.yml
|
|
||||||
- .github/workflows/deploy-docs.yml
|
|
||||||
- scripts/mkdocs_hooks.py
|
|
||||||
langs:
|
|
||||||
needs:
|
|
||||||
- changes
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
langs: ${{ steps.show-langs.outputs.langs }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install docs extras
|
|
||||||
run: uv pip install -r requirements-docs.txt
|
|
||||||
- name: Verify Docs
|
|
||||||
run: python ./scripts/docs.py verify-docs
|
|
||||||
- name: Export Language Codes
|
|
||||||
id: show-langs
|
|
||||||
run: |
|
|
||||||
echo "langs=$(python ./scripts/docs.py langs-json)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
build-docs:
|
|
||||||
needs:
|
|
||||||
- changes
|
|
||||||
- langs
|
|
||||||
if: ${{ needs.changes.outputs.docs == 'true' }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
lang: ${{ fromJson(needs.langs.outputs.langs) }}
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install docs extras
|
|
||||||
run: uv pip install -r requirements-docs.txt
|
|
||||||
- name: Update Languages
|
|
||||||
run: python ./scripts/docs.py update-languages
|
|
||||||
- uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
|
|
||||||
path: docs/${{ matrix.lang }}/.cache
|
|
||||||
- name: Build Docs
|
|
||||||
run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
|
|
||||||
- uses: actions/upload-artifact@v5
|
|
||||||
with:
|
|
||||||
name: docs-site-${{ matrix.lang }}
|
|
||||||
path: ./site/**
|
|
||||||
include-hidden-files: true
|
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/alls-green#why
|
|
||||||
docs-all-green: # This job does nothing and is only used for the branch protection
|
|
||||||
if: always()
|
|
||||||
needs:
|
|
||||||
- build-docs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Decide whether the needed jobs succeeded or failed
|
|
||||||
uses: re-actors/alls-green@release/v1
|
|
||||||
with:
|
|
||||||
jobs: ${{ toJSON(needs) }}
|
|
||||||
allowed-skips: build-docs
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
name: FastAPI People Contributors
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 3 1 * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
debug_enabled:
|
|
||||||
description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
|
|
||||||
required: false
|
|
||||||
default: "false"
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
job:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: uv pip install -r requirements-github-actions.txt
|
|
||||||
# Allow debugging with tmate
|
|
||||||
- name: Setup tmate session
|
|
||||||
uses: mxschmitt/action-tmate@v3
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
|
||||||
with:
|
|
||||||
limit-access-to-actor: true
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
|
||||||
- name: FastAPI People Contributors
|
|
||||||
run: python ./scripts/contributors.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
name: Deploy Docs
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows:
|
|
||||||
- Build Docs
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
deployments: write
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
statuses: write
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy-docs:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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: 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 }}
|
|
||||||
STATE: "pending"
|
|
||||||
- name: Clean site
|
|
||||||
run: |
|
|
||||||
rm -rf ./site
|
|
||||||
mkdir ./site
|
|
||||||
- uses: actions/download-artifact@v6
|
|
||||||
with:
|
|
||||||
path: ./site/
|
|
||||||
pattern: docs-site-*
|
|
||||||
merge-multiple: true
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run-id: ${{ github.event.workflow_run.id }}
|
|
||||||
- name: Deploy to Cloudflare Pages
|
|
||||||
# hashFiles returns an empty string if there are no files
|
|
||||||
if: hashFiles('./site/*')
|
|
||||||
id: deploy
|
|
||||||
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 ) }}
|
|
||||||
uses: cloudflare/wrangler-action@v3
|
|
||||||
with:
|
|
||||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
||||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
||||||
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
|
|
||||||
- name: Deploy Docs Status Error
|
|
||||||
if: failure()
|
|
||||||
run: python ./scripts/deploy_docs_status.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
||||||
RUN_ID: ${{ github.run_id }}
|
|
||||||
STATE: "error"
|
|
||||||
- name: Comment Deploy
|
|
||||||
run: python ./scripts/deploy_docs_status.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}
|
|
||||||
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
||||||
RUN_ID: ${{ github.run_id }}
|
|
||||||
STATE: "success"
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: "Conflict detector"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request_target:
|
|
||||||
types: [synchronize]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
main:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check if PRs have merge conflicts
|
|
||||||
uses: eps1lon/actions-label-merge-conflict@v3
|
|
||||||
with:
|
|
||||||
dirtyLabel: "conflicts"
|
|
||||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
commentOnDirty: "This pull request has a merge conflict that needs to be resolved."
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
name: Issue Manager
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "13 22 * * *"
|
|
||||||
issue_comment:
|
|
||||||
types:
|
|
||||||
- created
|
|
||||||
issues:
|
|
||||||
types:
|
|
||||||
- labeled
|
|
||||||
pull_request_target:
|
|
||||||
types:
|
|
||||||
- labeled
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
issue-manager:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: tiangolo/issue-manager@0.6.0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
config: >
|
|
||||||
{
|
|
||||||
"answered": {
|
|
||||||
"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."
|
|
||||||
},
|
|
||||||
"waiting": {
|
|
||||||
"delay": 2628000,
|
|
||||||
"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.",
|
|
||||||
"reminder": {
|
|
||||||
"before": "P3D",
|
|
||||||
"message": "Heads-up: this will be closed in 3 days unless there’s new activity."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"invalid": {
|
|
||||||
"delay": 0,
|
|
||||||
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
name: Label Approved
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 12 * * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
label-approved:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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":
|
|
||||||
{
|
|
||||||
"number": 1,
|
|
||||||
"await_label": "awaiting-review"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
name: Labels
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
- reopened
|
|
||||||
# For label-checker
|
|
||||||
- labeled
|
|
||||||
- unlabeled
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
labeler:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/labeler@v6
|
|
||||||
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
|
|
||||||
- run: echo "Done adding labels"
|
|
||||||
# Run this after labeler applied labels
|
|
||||||
check-labels:
|
|
||||||
needs:
|
|
||||||
- labeler
|
|
||||||
permissions:
|
|
||||||
pull-requests: read
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: docker://agilepathway/pull-request-label-checker:latest
|
|
||||||
with:
|
|
||||||
one_of: breaking,security,feature,bug,refactor,upgrade,docs,lang-all,internal
|
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
name: Latest Changes
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
types:
|
|
||||||
- closed
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
number:
|
|
||||||
description: PR number
|
|
||||||
required: true
|
|
||||||
debug_enabled:
|
|
||||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
|
||||||
required: false
|
|
||||||
default: 'false'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
latest-changes:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
# pin to actions/checkout@v5 for compatibility with latest-changes
|
|
||||||
# Ref: https://github.com/actions/checkout/issues/2313
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
# To allow latest-changes to commit to the main branch
|
|
||||||
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
|
|
||||||
# Allow debugging with tmate
|
|
||||||
- name: Setup tmate session
|
|
||||||
uses: mxschmitt/action-tmate@v3
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
|
||||||
with:
|
|
||||||
limit-access-to-actor: true
|
|
||||||
- uses: tiangolo/latest-changes@0.4.1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
latest_changes_file: docs/en/docs/release-notes.md
|
|
||||||
latest_changes_header: '## Latest Changes'
|
|
||||||
end_regex: '^## '
|
|
||||||
debug_logs: true
|
|
||||||
label_header_prefix: '### '
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
name: Notify Translations
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types:
|
|
||||||
- labeled
|
|
||||||
- closed
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
number:
|
|
||||||
description: PR number
|
|
||||||
required: true
|
|
||||||
debug_enabled:
|
|
||||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
|
||||||
required: false
|
|
||||||
default: 'false'
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
job:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
discussions: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: uv pip install -r requirements-github-actions.txt
|
|
||||||
# Allow debugging with tmate
|
|
||||||
- name: Setup tmate session
|
|
||||||
uses: mxschmitt/action-tmate@v3
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
|
||||||
with:
|
|
||||||
limit-access-to-actor: true
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Notify Translations
|
|
||||||
run: python ./scripts/notify_translations.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
NUMBER: ${{ github.event.inputs.number || null }}
|
|
||||||
DEBUG: ${{ github.event.inputs.debug_enabled || 'false' }}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
name: FastAPI People
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 14 1 * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
debug_enabled:
|
|
||||||
description: Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
|
|
||||||
required: false
|
|
||||||
default: "false"
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
job:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: uv pip install -r requirements-github-actions.txt
|
|
||||||
# Allow debugging with tmate
|
|
||||||
- name: Setup tmate session
|
|
||||||
uses: mxschmitt/action-tmate@v3
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
|
||||||
with:
|
|
||||||
limit-access-to-actor: true
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
|
|
||||||
- name: FastAPI People Experts
|
|
||||||
run: python ./scripts/people.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
|
|
||||||
SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
name: pre-commit
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
env:
|
|
||||||
IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pre-commit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
name: Checkout PR for own repo
|
|
||||||
if: env.IS_FORK == 'false'
|
|
||||||
with:
|
|
||||||
# To be able to commit it needs more than the last commit
|
|
||||||
ref: ${{ github.head_ref }}
|
|
||||||
# A token other than the default GITHUB_TOKEN is needed to be able to trigger CI
|
|
||||||
token: ${{ secrets.PRE_COMMIT }}
|
|
||||||
# pre-commit lite ci needs the default checkout configs to work
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
name: Checkout PR for fork
|
|
||||||
if: env.IS_FORK == 'true'
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.14"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
uv.lock
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: |
|
|
||||||
uv venv
|
|
||||||
uv pip install -r requirements.txt
|
|
||||||
- name: Run pre-commit
|
|
||||||
id: precommit
|
|
||||||
run: |
|
|
||||||
# Fetch the base branch for comparison
|
|
||||||
git fetch origin ${{ github.base_ref }}
|
|
||||||
uvx pre-commit run --from-ref origin/${{ github.base_ref }} --to-ref HEAD --show-diff-on-failure
|
|
||||||
continue-on-error: true
|
|
||||||
- name: Commit and push changes
|
|
||||||
if: env.IS_FORK == 'false'
|
|
||||||
run: |
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git add -A
|
|
||||||
if git diff --staged --quiet; then
|
|
||||||
echo "No changes to commit"
|
|
||||||
else
|
|
||||||
git commit -m "🎨 Auto format"
|
|
||||||
git push
|
|
||||||
fi
|
|
||||||
- uses: pre-commit-ci/lite-action@v1.1.0
|
|
||||||
if: env.IS_FORK == 'true'
|
|
||||||
with:
|
|
||||||
msg: 🎨 Auto format
|
|
||||||
- name: Error out on pre-commit errors
|
|
||||||
if: steps.precommit.outcome == 'failure'
|
|
||||||
run: exit 1
|
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/alls-green#why
|
|
||||||
pre-commit-alls-green: # This job does nothing and is only used for the branch protection
|
|
||||||
if: always()
|
|
||||||
needs:
|
|
||||||
- pre-commit
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- name: Decide whether the needed jobs succeeded or failed
|
|
||||||
uses: re-actors/alls-green@release/v1
|
|
||||||
with:
|
|
||||||
jobs: ${{ toJSON(needs) }}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
name: Publish
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- created
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
package:
|
|
||||||
- fastapi
|
|
||||||
- fastapi-slim
|
|
||||||
permissions:
|
|
||||||
id-token: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
|
||||||
# cache: "pip"
|
|
||||||
# cache-dependency-path: pyproject.toml
|
|
||||||
- name: Install build dependencies
|
|
||||||
run: pip install build
|
|
||||||
- name: Build distribution
|
|
||||||
env:
|
|
||||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
|
||||||
run: python -m build
|
|
||||||
- name: Publish
|
|
||||||
uses: pypa/gh-action-pypi-publish@v1.13.0
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
name: Smokeshow
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows: [Test]
|
|
||||||
types: [completed]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
statuses: write
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
smokeshow:
|
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: '3.9'
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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@v6
|
|
||||||
with:
|
|
||||||
name: coverage-html
|
|
||||||
path: htmlcov
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run-id: ${{ github.event.workflow_run.id }}
|
|
||||||
# Try 5 times to upload coverage to smokeshow
|
|
||||||
- name: Upload coverage to Smokeshow
|
|
||||||
run: |
|
|
||||||
for i in 1 2 3 4 5; do
|
|
||||||
if smokeshow upload htmlcov; then
|
|
||||||
echo "Smokeshow upload success!"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "Smokeshow upload error, sleep 1 sec and try again."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
env:
|
|
||||||
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
|
|
||||||
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
|
|
||||||
SMOKESHOW_GITHUB_CONTEXT: coverage
|
|
||||||
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
||||||
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
name: FastAPI People Sponsors
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 6 1 * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
debug_enabled:
|
|
||||||
description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
|
|
||||||
required: false
|
|
||||||
default: "false"
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
job:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: uv pip install -r requirements-github-actions.txt
|
|
||||||
# Allow debugging with tmate
|
|
||||||
- name: Setup tmate session
|
|
||||||
uses: mxschmitt/action-tmate@v3
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
|
||||||
with:
|
|
||||||
limit-access-to-actor: true
|
|
||||||
- name: FastAPI People Sponsors
|
|
||||||
run: python ./scripts/sponsors.py
|
|
||||||
env:
|
|
||||||
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }}
|
|
||||||
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
name: Test Redistribute
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test-redistribute:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
package:
|
|
||||||
- fastapi
|
|
||||||
- fastapi-slim
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install build dependencies
|
|
||||||
run: pip install build
|
|
||||||
- name: Build source distribution
|
|
||||||
env:
|
|
||||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
|
||||||
run: python -m build --sdist
|
|
||||||
- name: Decompress source distribution
|
|
||||||
run: |
|
|
||||||
cd dist
|
|
||||||
tar xvf fastapi*.tar.gz
|
|
||||||
- name: Install test dependencies
|
|
||||||
run: |
|
|
||||||
cd dist/fastapi*/
|
|
||||||
pip install -r requirements-tests.txt
|
|
||||||
env:
|
|
||||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
|
||||||
- name: Run source distribution tests
|
|
||||||
run: |
|
|
||||||
cd dist/fastapi*/
|
|
||||||
bash scripts/test.sh
|
|
||||||
- name: Build wheel distribution
|
|
||||||
run: |
|
|
||||||
cd dist
|
|
||||||
pip wheel --no-deps fastapi*.tar.gz
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/alls-green#why
|
|
||||||
test-redistribute-alls-green: # This job does nothing and is only used for the branch protection
|
|
||||||
if: always()
|
|
||||||
needs:
|
|
||||||
- test-redistribute
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Decide whether the needed jobs succeeded or failed
|
|
||||||
uses: re-actors/alls-green@release/v1
|
|
||||||
with:
|
|
||||||
jobs: ${{ toJSON(needs) }}
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
name: Test
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
schedule:
|
|
||||||
# cron every week on monday
|
|
||||||
- cron: "0 0 * * 1"
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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: Install Pydantic v2
|
|
||||||
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
|
||||||
- name: Lint
|
|
||||||
run: bash scripts/lint.sh
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python-version:
|
|
||||||
- "3.14"
|
|
||||||
- "3.13"
|
|
||||||
- "3.12"
|
|
||||||
- "3.11"
|
|
||||||
- "3.10"
|
|
||||||
- "3.9"
|
|
||||||
- "3.8"
|
|
||||||
pydantic-version: ["pydantic-v1", "pydantic-v2"]
|
|
||||||
exclude:
|
|
||||||
- python-version: "3.14"
|
|
||||||
pydantic-version: "pydantic-v1"
|
|
||||||
fail-fast: false
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python-version }}
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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: Install Pydantic v1
|
|
||||||
if: matrix.pydantic-version == 'pydantic-v1'
|
|
||||||
run: uv pip install "pydantic>=1.10.0,<2.0.0"
|
|
||||||
- name: Install Pydantic v2
|
|
||||||
if: matrix.pydantic-version == 'pydantic-v2'
|
|
||||||
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
|
||||||
# TODO: Remove this once Python 3.8 is no longer supported
|
|
||||||
- name: Install older AnyIO in Python 3.8
|
|
||||||
if: matrix.python-version == '3.8'
|
|
||||||
run: uv pip install "anyio[trio]<4.0.0"
|
|
||||||
- run: mkdir coverage
|
|
||||||
- name: Test
|
|
||||||
run: bash scripts/test.sh
|
|
||||||
env:
|
|
||||||
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
|
|
||||||
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
|
|
||||||
- name: Store coverage files
|
|
||||||
uses: actions/upload-artifact@v5
|
|
||||||
with:
|
|
||||||
name: coverage-${{ matrix.python-version }}-${{ matrix.pydantic-version }}
|
|
||||||
path: coverage
|
|
||||||
include-hidden-files: true
|
|
||||||
|
|
||||||
coverage-combine:
|
|
||||||
needs: [test]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: '3.8'
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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@v6
|
|
||||||
with:
|
|
||||||
pattern: coverage-*
|
|
||||||
path: coverage
|
|
||||||
merge-multiple: true
|
|
||||||
- run: ls -la coverage
|
|
||||||
- run: coverage combine coverage
|
|
||||||
- run: coverage report
|
|
||||||
- run: coverage html --title "Coverage for ${{ github.sha }}"
|
|
||||||
- name: Store coverage HTML
|
|
||||||
uses: actions/upload-artifact@v5
|
|
||||||
with:
|
|
||||||
name: coverage-html
|
|
||||||
path: htmlcov
|
|
||||||
include-hidden-files: true
|
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/alls-green#why
|
|
||||||
check: # This job does nothing and is only used for the branch protection
|
|
||||||
if: always()
|
|
||||||
needs:
|
|
||||||
- coverage-combine
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- name: Decide whether the needed jobs succeeded or failed
|
|
||||||
uses: re-actors/alls-green@release/v1
|
|
||||||
with:
|
|
||||||
jobs: ${{ toJSON(needs) }}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
name: Update Topic Repos
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 12 1 * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
topic-repos:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
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: Update Topic Repos
|
|
||||||
run: python ./scripts/topic_repos.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
name: Translate
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
debug_enabled:
|
|
||||||
description: Run with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
|
|
||||||
required: false
|
|
||||||
default: "false"
|
|
||||||
command:
|
|
||||||
description: Command to run
|
|
||||||
type: choice
|
|
||||||
options:
|
|
||||||
- translate-page
|
|
||||||
- translate-lang
|
|
||||||
- update-outdated
|
|
||||||
- add-missing
|
|
||||||
- update-and-add
|
|
||||||
- remove-all-removable
|
|
||||||
language:
|
|
||||||
description: Language to translate to as a letter code (e.g. "es" for Spanish)
|
|
||||||
type: string
|
|
||||||
required: false
|
|
||||||
default: ""
|
|
||||||
en_path:
|
|
||||||
description: File path in English to translate (e.g. docs/en/docs/index.md)
|
|
||||||
type: string
|
|
||||||
required: false
|
|
||||||
default: ""
|
|
||||||
|
|
||||||
env:
|
|
||||||
UV_SYSTEM_PYTHON: 1
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
job:
|
|
||||||
if: github.repository_owner == 'fastapi'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Dump GitHub context
|
|
||||||
env:
|
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
||||||
run: echo "$GITHUB_CONTEXT"
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- name: Setup uv
|
|
||||||
uses: astral-sh/setup-uv@v7
|
|
||||||
with:
|
|
||||||
version: "0.4.15"
|
|
||||||
enable-cache: true
|
|
||||||
cache-dependency-glob: |
|
|
||||||
requirements**.txt
|
|
||||||
pyproject.toml
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
|
|
||||||
# Allow debugging with tmate
|
|
||||||
- name: Setup tmate session
|
|
||||||
uses: mxschmitt/action-tmate@v3
|
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
|
||||||
with:
|
|
||||||
limit-access-to-actor: true
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
|
|
||||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
||||||
- name: FastAPI Translate
|
|
||||||
run: |
|
|
||||||
python ./scripts/translate.py ${{ github.event.inputs.command }}
|
|
||||||
python ./scripts/translate.py make-pr
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
|
|
||||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
||||||
LANGUAGE: ${{ github.event.inputs.language }}
|
|
||||||
EN_PATH: ${{ github.event.inputs.en_path }}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
.idea
|
|
||||||
.ipynb_checkpoints
|
|
||||||
.mypy_cache
|
|
||||||
.vscode
|
|
||||||
__pycache__
|
|
||||||
.pytest_cache
|
|
||||||
htmlcov
|
|
||||||
dist
|
|
||||||
site
|
|
||||||
.coverage*
|
|
||||||
coverage.xml
|
|
||||||
.netlify
|
|
||||||
test.db
|
|
||||||
log.txt
|
|
||||||
Pipfile.lock
|
|
||||||
env3.*
|
|
||||||
env
|
|
||||||
docs_build
|
|
||||||
site_build
|
|
||||||
venv
|
|
||||||
docs.zip
|
|
||||||
archive.zip
|
|
||||||
|
|
||||||
# vim temporary files
|
|
||||||
*~
|
|
||||||
.*.sw?
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# macOS
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Ignore while the setup still depends on requirements.txt files
|
|
||||||
uv.lock
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# See https://pre-commit.com for more information
|
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
|
||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
||||||
rev: v6.0.0
|
|
||||||
hooks:
|
|
||||||
- id: check-added-large-files
|
|
||||||
- id: check-toml
|
|
||||||
- id: check-yaml
|
|
||||||
args:
|
|
||||||
- --unsafe
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
- id: trailing-whitespace
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
||||||
rev: v0.14.3
|
|
||||||
hooks:
|
|
||||||
- id: ruff
|
|
||||||
args:
|
|
||||||
- --fix
|
|
||||||
- id: ruff-format
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- id: local-script
|
|
||||||
language: unsupported
|
|
||||||
name: local script
|
|
||||||
entry: uv run ./scripts/docs.py add-permalinks-pages
|
|
||||||
args:
|
|
||||||
- --update-existing
|
|
||||||
files: ^docs/en/docs/.*\.md$
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# This CITATION.cff file was generated with cffinit.
|
|
||||||
# Visit https://bit.ly/cffinit to generate yours today!
|
|
||||||
|
|
||||||
cff-version: 1.2.0
|
|
||||||
title: FastAPI
|
|
||||||
message: >-
|
|
||||||
If you use this software, please cite it using the
|
|
||||||
metadata from this file.
|
|
||||||
type: software
|
|
||||||
authors:
|
|
||||||
- given-names: Sebastián
|
|
||||||
family-names: Ramírez
|
|
||||||
email: tiangolo@gmail.com
|
|
||||||
identifiers:
|
|
||||||
repository-code: 'https://github.com/fastapi/fastapi'
|
|
||||||
url: 'https://fastapi.tiangolo.com'
|
|
||||||
abstract: >-
|
|
||||||
FastAPI framework, high performance, easy to learn, fast to code,
|
|
||||||
ready for production
|
|
||||||
keywords:
|
|
||||||
- fastapi
|
|
||||||
- pydantic
|
|
||||||
- starlette
|
|
||||||
license: MIT
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Please read the [Development - Contributing](https://fastapi.tiangolo.com/contributing/) guidelines in the documentation site.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2018 Sebastián Ramírez
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
@@ -1,562 +0,0 @@
|
|||||||
<p align="center">
|
|
||||||
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
|
||||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
|
||||||
</a>
|
|
||||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
|
|
||||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
|
|
||||||
</a>
|
|
||||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
|
||||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
||||||
</a>
|
|
||||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
|
||||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
|
||||||
|
|
||||||
**Source Code**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints.
|
|
||||||
|
|
||||||
The key features are:
|
|
||||||
|
|
||||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
|
||||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
|
|
||||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
|
||||||
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
|
|
||||||
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
|
|
||||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
|
|
||||||
* **Robust**: Get production-ready code. With automatic interactive documentation.
|
|
||||||
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
|
||||||
|
|
||||||
<small>* estimation based on tests conducted by an internal development team, building production applications.</small>
|
|
||||||
|
|
||||||
## Sponsors
|
|
||||||
|
|
||||||
<!-- sponsors -->
|
|
||||||
### Keystone Sponsor
|
|
||||||
|
|
||||||
<a href="https://fastapicloud.com" target="_blank" title="FastAPI Cloud. By the same team behind FastAPI. You code. We Cloud."><img src="https://fastapi.tiangolo.com/img/sponsors/fastapicloud.png"></a>
|
|
||||||
|
|
||||||
### Gold and Silver Sponsors
|
|
||||||
|
|
||||||
<a href="https://blockbee.io?ref=fastapi" target="_blank" title="BlockBee Cryptocurrency Payment Gateway"><img src="https://fastapi.tiangolo.com/img/sponsors/blockbee.png"></a>
|
|
||||||
<a href="https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge" target="_blank" title="Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files"><img src="https://fastapi.tiangolo.com/img/sponsors/scalar.svg"></a>
|
|
||||||
<a href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge" target="_blank" title="Auth, user management and more for your B2B product"><img src="https://fastapi.tiangolo.com/img/sponsors/propelauth.png"></a>
|
|
||||||
<a href="https://zuplo.link/fastapi-gh" target="_blank" title="Zuplo: Deploy, Secure, Document, and Monetize your FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/zuplo.png"></a>
|
|
||||||
<a href="https://liblab.com?utm_source=fastapi" target="_blank" title="liblab - Generate SDKs from FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/liblab.png"></a>
|
|
||||||
<a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra."><img src="https://fastapi.tiangolo.com/img/sponsors/render.svg"></a>
|
|
||||||
<a href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi" target="_blank" title="Cut Code Review Time & Bugs in Half with CodeRabbit"><img src="https://fastapi.tiangolo.com/img/sponsors/coderabbit.png"></a>
|
|
||||||
<a href="https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source" target="_blank" title="The Gold Standard in Retail Account Linking"><img src="https://fastapi.tiangolo.com/img/sponsors/subtotal.svg"></a>
|
|
||||||
<a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" target="_blank" title="Deploy enterprise applications at startup speed"><img src="https://fastapi.tiangolo.com/img/sponsors/railway.png"></a>
|
|
||||||
<a href="https://serpapi.com/?utm_source=fastapi_website" target="_blank" title="SerpApi: Web Search API"><img src="https://fastapi.tiangolo.com/img/sponsors/serpapi.png"></a>
|
|
||||||
<a href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank" title="Greptile: The AI Code Reviewer"><img src="https://fastapi.tiangolo.com/img/sponsors/greptile.png"></a>
|
|
||||||
<a href="https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
|
|
||||||
<a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" target="_blank" title="SDKs for your API | Speakeasy"><img src="https://fastapi.tiangolo.com/img/sponsors/speakeasy.png"></a>
|
|
||||||
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
|
|
||||||
<a href="https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral" target="_blank" title="Stainless | Generate best-in-class SDKs"><img src="https://fastapi.tiangolo.com/img/sponsors/stainless.png"></a>
|
|
||||||
<a href="https://www.permit.io/blog/implement-authorization-in-fastapi?utm_source=github&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Fine-Grained Authorization for FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/permit.png"></a>
|
|
||||||
<a href="https://www.interviewpal.com/?utm_source=fastapi&utm_medium=open-source&utm_campaign=dev-hiring" target="_blank" title="InterviewPal - AI Interview Coach for Engineers and Devs"><img src="https://fastapi.tiangolo.com/img/sponsors/interviewpal.png"></a>
|
|
||||||
<a href="https://dribia.com/en/" target="_blank" title="Dribia - Data Science within your reach"><img src="https://fastapi.tiangolo.com/img/sponsors/dribia.png"></a>
|
|
||||||
|
|
||||||
<!-- /sponsors -->
|
|
||||||
|
|
||||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
|
|
||||||
|
|
||||||
## Opinions
|
|
||||||
|
|
||||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
|
|
||||||
|
|
||||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
|
|
||||||
|
|
||||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## **Typer**, the FastAPI of CLIs
|
|
||||||
|
|
||||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
|
||||||
|
|
||||||
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
|
||||||
|
|
||||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
FastAPI stands on the shoulders of giants:
|
|
||||||
|
|
||||||
* <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> for the web parts.
|
|
||||||
* <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Create and activate a <a href="https://fastapi.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a> and then install FastAPI:
|
|
||||||
|
|
||||||
<div class="termy">
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ pip install "fastapi[standard]"
|
|
||||||
|
|
||||||
---> 100%
|
|
||||||
```
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
### Create it
|
|
||||||
|
|
||||||
Create a file `main.py` with:
|
|
||||||
|
|
||||||
```Python
|
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
|
||||||
def read_root():
|
|
||||||
return {"Hello": "World"}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
|
||||||
def read_item(item_id: int, q: Union[str, None] = None):
|
|
||||||
return {"item_id": item_id, "q": q}
|
|
||||||
```
|
|
||||||
|
|
||||||
<details markdown="1">
|
|
||||||
<summary>Or use <code>async def</code>...</summary>
|
|
||||||
|
|
||||||
If your code uses `async` / `await`, use `async def`:
|
|
||||||
|
|
||||||
```Python hl_lines="9 14"
|
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
|
||||||
async def read_root():
|
|
||||||
return {"Hello": "World"}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
|
||||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
|
||||||
return {"item_id": item_id, "q": q}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note**:
|
|
||||||
|
|
||||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Run it
|
|
||||||
|
|
||||||
Run the server with:
|
|
||||||
|
|
||||||
<div class="termy">
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ fastapi dev main.py
|
|
||||||
|
|
||||||
╭────────── FastAPI CLI - Development mode ───────────╮
|
|
||||||
│ │
|
|
||||||
│ Serving at: http://127.0.0.1:8000 │
|
|
||||||
│ │
|
|
||||||
│ API docs: http://127.0.0.1:8000/docs │
|
|
||||||
│ │
|
|
||||||
│ Running in development mode, for production use: │
|
|
||||||
│ │
|
|
||||||
│ fastapi run │
|
|
||||||
│ │
|
|
||||||
╰─────────────────────────────────────────────────────╯
|
|
||||||
|
|
||||||
INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
|
|
||||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|
||||||
INFO: Started reloader process [2248755] using WatchFiles
|
|
||||||
INFO: Started server process [2248757]
|
|
||||||
INFO: Waiting for application startup.
|
|
||||||
INFO: Application startup complete.
|
|
||||||
```
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<details markdown="1">
|
|
||||||
<summary>About the command <code>fastapi dev main.py</code>...</summary>
|
|
||||||
|
|
||||||
The command `fastapi dev` reads your `main.py` file, detects the **FastAPI** app in it, and starts a server using <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
|
|
||||||
|
|
||||||
By default, `fastapi dev` will start with auto-reload enabled for local development.
|
|
||||||
|
|
||||||
You can read more about it in the <a href="https://fastapi.tiangolo.com/fastapi-cli/" target="_blank">FastAPI CLI docs</a>.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Check it
|
|
||||||
|
|
||||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
|
||||||
|
|
||||||
You will see the JSON response as:
|
|
||||||
|
|
||||||
```JSON
|
|
||||||
{"item_id": 5, "q": "somequery"}
|
|
||||||
```
|
|
||||||
|
|
||||||
You already created an API that:
|
|
||||||
|
|
||||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
|
||||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
|
||||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
|
||||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
|
||||||
|
|
||||||
### Interactive API docs
|
|
||||||
|
|
||||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
|
||||||
|
|
||||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
|
||||||
|
|
||||||

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

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

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

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

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

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

|
|
||||||
|
|
||||||
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
|
||||||
|
|
||||||
**Spoiler alert**: the tutorial - user guide includes:
|
|
||||||
|
|
||||||
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
|
|
||||||
* How to set **validation constraints** as `maximum_length` or `regex`.
|
|
||||||
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
|
|
||||||
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
|
|
||||||
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
|
|
||||||
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
|
|
||||||
* Many extra features (thanks to Starlette) as:
|
|
||||||
* **WebSockets**
|
|
||||||
* extremely easy tests based on HTTPX and `pytest`
|
|
||||||
* **CORS**
|
|
||||||
* **Cookie Sessions**
|
|
||||||
* ...and more.
|
|
||||||
|
|
||||||
### Deploy your app (optional)
|
|
||||||
|
|
||||||
You can optionally deploy your FastAPI app to <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, go and join the waiting list if you haven't. 🚀
|
|
||||||
|
|
||||||
If you already have a **FastAPI Cloud** account (we invited you from the waiting list 😉), you can deploy your application with one command.
|
|
||||||
|
|
||||||
Before deploying, make sure you are logged in:
|
|
||||||
|
|
||||||
<div class="termy">
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ fastapi login
|
|
||||||
|
|
||||||
You are logged in to FastAPI Cloud 🚀
|
|
||||||
```
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Then deploy your app:
|
|
||||||
|
|
||||||
<div class="termy">
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ fastapi deploy
|
|
||||||
|
|
||||||
Deploying to FastAPI Cloud...
|
|
||||||
|
|
||||||
✅ Deployment successful!
|
|
||||||
|
|
||||||
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
|
|
||||||
```
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
That's it! Now you can access your app at that URL. ✨
|
|
||||||
|
|
||||||
#### About FastAPI Cloud
|
|
||||||
|
|
||||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** is built by the same author and team behind **FastAPI**.
|
|
||||||
|
|
||||||
It streamlines the process of **building**, **deploying**, and **accessing** an API with minimal effort.
|
|
||||||
|
|
||||||
It brings the same **developer experience** of building apps with FastAPI to **deploying** them to the cloud. 🎉
|
|
||||||
|
|
||||||
FastAPI Cloud is the primary sponsor and funding provider for the *FastAPI and friends* open source projects. ✨
|
|
||||||
|
|
||||||
#### Deploy to other cloud providers
|
|
||||||
|
|
||||||
FastAPI is open source and based on standards. You can deploy FastAPI apps to any cloud provider you choose.
|
|
||||||
|
|
||||||
Follow your cloud provider's guides to deploy FastAPI apps with them. 🤓
|
|
||||||
|
|
||||||
## Performance
|
|
||||||
|
|
||||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
|
||||||
|
|
||||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
FastAPI depends on Pydantic and Starlette.
|
|
||||||
|
|
||||||
### `standard` Dependencies
|
|
||||||
|
|
||||||
When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
|
|
||||||
|
|
||||||
Used by Pydantic:
|
|
||||||
|
|
||||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - for email validation.
|
|
||||||
|
|
||||||
Used by Starlette:
|
|
||||||
|
|
||||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
|
|
||||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
|
||||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
|
||||||
|
|
||||||
Used by FastAPI:
|
|
||||||
|
|
||||||
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
|
|
||||||
* `fastapi-cli[standard]` - to provide the `fastapi` command.
|
|
||||||
* This includes `fastapi-cloud-cli`, which allows you to deploy your FastAPI application to <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
|
|
||||||
|
|
||||||
### Without `standard` Dependencies
|
|
||||||
|
|
||||||
If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
|
|
||||||
|
|
||||||
### Without `fastapi-cloud-cli`
|
|
||||||
|
|
||||||
If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
|
|
||||||
|
|
||||||
### Additional Optional Dependencies
|
|
||||||
|
|
||||||
There are some additional dependencies you might want to install.
|
|
||||||
|
|
||||||
Additional optional Pydantic dependencies:
|
|
||||||
|
|
||||||
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
|
|
||||||
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.
|
|
||||||
|
|
||||||
Additional optional FastAPI dependencies:
|
|
||||||
|
|
||||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
|
||||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the terms of the MIT license.
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
# Security Policy
|
|
||||||
|
|
||||||
Security is very important for FastAPI and its community. 🔒
|
|
||||||
|
|
||||||
Learn more about it below. 👇
|
|
||||||
|
|
||||||
## Versions
|
|
||||||
|
|
||||||
The latest version of FastAPI is supported.
|
|
||||||
|
|
||||||
You are encouraged to [write tests](https://fastapi.tiangolo.com/tutorial/testing/) for your application and update your FastAPI version frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and **security fixes**.
|
|
||||||
|
|
||||||
You can learn more about [FastAPI versions and how to pin and upgrade them](https://fastapi.tiangolo.com/deployment/versions/) for your project in the docs.
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
|
|
||||||
|
|
||||||
I (the author, [@tiangolo](https://x.com/tiangolo)) will review it thoroughly and get back to you.
|
|
||||||
|
|
||||||
## Public Discussions
|
|
||||||
|
|
||||||
Please restrain from publicly discussing a potential security vulnerability. 🙊
|
|
||||||
|
|
||||||
It's better to discuss privately and try to find a solution first, to limit the potential impact as much as possible.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Thanks for your help!
|
|
||||||
|
|
||||||
The FastAPI community and I thank you for that. 🙇
|
|
||||||
@@ -15,7 +15,7 @@ So verwenden:
|
|||||||
|
|
||||||
Die Tests:
|
Die Tests:
|
||||||
|
|
||||||
## Codeschnipsel { #code-snippets}
|
## Codeschnipsel { #code-snippets }
|
||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Siehe zum Beispiel den Abschnitt `### Quotes` in `docs/de/llm-prompt.md`.
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
## Anführungszeichen in Codeschnipseln { #quotes-in-code-snippets}
|
## Anführungszeichen in Codeschnipseln { #quotes-in-code-snippets }
|
||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Jedes dieser Response-`dict`s kann einen Schlüssel `model` haben, welcher ein P
|
|||||||
|
|
||||||
Um beispielsweise eine weitere Response mit dem Statuscode `404` und einem Pydantic-Modell `Message` zu deklarieren, können Sie schreiben:
|
Um beispielsweise eine weitere Response mit dem Statuscode `404` und einem Pydantic-Modell `Message` zu deklarieren, können Sie schreiben:
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
|
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ Sie können denselben `responses`-Parameter verwenden, um verschiedene Medientyp
|
|||||||
|
|
||||||
Sie können beispielsweise einen zusätzlichen Medientyp `image/png` hinzufügen und damit deklarieren, dass Ihre *Pfadoperation* ein JSON-Objekt (mit dem Medientyp `application/json`) oder ein PNG-Bild zurückgeben kann:
|
Sie können beispielsweise einen zusätzlichen Medientyp `image/png` hinzufügen und damit deklarieren, dass Ihre *Pfadoperation* ein JSON-Objekt (mit dem Medientyp `application/json`) oder ein PNG-Bild zurückgeben kann:
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
|
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ Sie können beispielsweise eine Response mit dem Statuscode `404` deklarieren, d
|
|||||||
|
|
||||||
Und eine Response mit dem Statuscode `200`, die Ihr `response_model` verwendet, aber ein benutzerdefiniertes Beispiel (`example`) enthält:
|
Und eine Response mit dem Statuscode `200`, die Ihr `response_model` verwendet, aber ein benutzerdefiniertes Beispiel (`example`) enthält:
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
|
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
|
||||||
|
|
||||||
Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt:
|
Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt:
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ Mit dieser Technik können Sie einige vordefinierte Responses in Ihren *Pfadoper
|
|||||||
|
|
||||||
Zum Beispiel:
|
Zum Beispiel:
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
|
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
|
||||||
|
|
||||||
## Weitere Informationen zu OpenAPI-Responses { #more-information-about-openapi-responses }
|
## Weitere Informationen zu OpenAPI-Responses { #more-information-about-openapi-responses }
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [Größ
|
|||||||
|
|
||||||
Die Datei `main.py` hätte als Inhalt:
|
Die Datei `main.py` hätte als Inhalt:
|
||||||
|
|
||||||
{* ../../docs_src/async_tests/main.py *}
|
{* ../../docs_src/async_tests/app_a_py39/main.py *}
|
||||||
|
|
||||||
Die Datei `test_main.py` hätte die Tests für `main.py`, das könnte jetzt so aussehen:
|
Die Datei `test_main.py` hätte die Tests für `main.py`, das könnte jetzt so aussehen:
|
||||||
|
|
||||||
{* ../../docs_src/async_tests/test_main.py *}
|
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
|
||||||
|
|
||||||
## Es ausführen { #run-it }
|
## Es ausführen { #run-it }
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ $ pytest
|
|||||||
|
|
||||||
Der Marker `@pytest.mark.anyio` teilt pytest mit, dass diese Testfunktion asynchron aufgerufen werden soll:
|
Der Marker `@pytest.mark.anyio` teilt pytest mit, dass diese Testfunktion asynchron aufgerufen werden soll:
|
||||||
|
|
||||||
{* ../../docs_src/async_tests/test_main.py hl[7] *}
|
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ Beachten Sie, dass die Testfunktion jetzt `async def` ist und nicht nur `def` wi
|
|||||||
|
|
||||||
Dann können wir einen `AsyncClient` mit der App erstellen und mit `await` asynchrone Requests an ihn senden.
|
Dann können wir einen `AsyncClient` mit der App erstellen und mit `await` asynchrone Requests an ihn senden.
|
||||||
|
|
||||||
{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
|
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
|
||||||
|
|
||||||
Das ist das Äquivalent zu:
|
Das ist das Äquivalent zu:
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
|
|||||||
|
|
||||||
Angenommen, Sie definieren eine *Pfadoperation* `/items/`:
|
Angenommen, Sie definieren eine *Pfadoperation* `/items/`:
|
||||||
|
|
||||||
{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
|
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
|
||||||
|
|
||||||
Wenn der Client versucht, zu `/items` zu gehen, würde er standardmäßig zu `/items/` umgeleitet.
|
Wenn der Client versucht, zu `/items` zu gehen, würde er standardmäßig zu `/items/` umgeleitet.
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ In diesem Fall würde der ursprüngliche Pfad `/app` tatsächlich unter `/api/v1
|
|||||||
|
|
||||||
Auch wenn Ihr gesamter Code unter der Annahme geschrieben ist, dass es nur `/app` gibt.
|
Auch wenn Ihr gesamter Code unter der Annahme geschrieben ist, dass es nur `/app` gibt.
|
||||||
|
|
||||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
|
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
Und der Proxy würde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> an den Anwendungsserver (wahrscheinlich Uvicorn via FastAPI CLI) übermittelt, dafür sorgend, dass Ihre Anwendung davon überzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren müssen, das Präfix `/api/v1` zu verwenden.
|
Und der Proxy würde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> an den Anwendungsserver (wahrscheinlich Uvicorn via FastAPI CLI) übermittelt, dafür sorgend, dass Ihre Anwendung davon überzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren müssen, das Präfix `/api/v1` zu verwenden.
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ Sie können den aktuellen `root_path` abrufen, der von Ihrer Anwendung für jede
|
|||||||
|
|
||||||
Hier fügen wir ihn, nur zu Demonstrationszwecken, in die Nachricht ein.
|
Hier fügen wir ihn, nur zu Demonstrationszwecken, in die Nachricht ein.
|
||||||
|
|
||||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
|
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
|
||||||
|
|
||||||
Wenn Sie Uvicorn dann starten mit:
|
Wenn Sie Uvicorn dann starten mit:
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ wäre die <abbr title="Response – Antwort: Daten, die der Server zum anfragend
|
|||||||
|
|
||||||
Falls Sie keine Möglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu übergeben, können Sie, alternativ dazu, beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen:
|
Falls Sie keine Möglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu übergeben, können Sie, alternativ dazu, beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen:
|
||||||
|
|
||||||
{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
|
{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
|
||||||
|
|
||||||
Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn.
|
Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn.
|
||||||
|
|
||||||
@@ -400,7 +400,7 @@ Wenn Sie eine benutzerdefinierte Liste von Servern (`servers`) übergeben und es
|
|||||||
|
|
||||||
Zum Beispiel:
|
Zum Beispiel:
|
||||||
|
|
||||||
{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
|
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
|
||||||
|
|
||||||
Erzeugt ein OpenAPI-Schema, wie:
|
Erzeugt ein OpenAPI-Schema, wie:
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ Wenn Sie den Parameter `servers` nicht angeben und `root_path` den Wert `/` hat,
|
|||||||
|
|
||||||
Wenn Sie nicht möchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, können Sie den Parameter `root_path_in_servers=False` verwenden:
|
Wenn Sie nicht möchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, können Sie den Parameter `root_path_in_servers=False` verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
|
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
|
||||||
|
|
||||||
Dann wird er nicht in das OpenAPI-Schema aufgenommen.
|
Dann wird er nicht in das OpenAPI-Schema aufgenommen.
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Das liegt daran, dass FastAPI standardmäßig jedes enthaltene Element überprü
|
|||||||
|
|
||||||
Wenn Sie jedoch sicher sind, dass der von Ihnen zurückgegebene Inhalt **mit JSON serialisierbar** ist, können Sie ihn direkt an die Response-Klasse übergeben und die zusätzliche Arbeit vermeiden, die FastAPI hätte, indem es Ihren zurückgegebenen Inhalt durch den `jsonable_encoder` leitet, bevor es ihn an die Response-Klasse übergibt.
|
Wenn Sie jedoch sicher sind, dass der von Ihnen zurückgegebene Inhalt **mit JSON serialisierbar** ist, können Sie ihn direkt an die Response-Klasse übergeben und die zusätzliche Arbeit vermeiden, die FastAPI hätte, indem es Ihren zurückgegebenen Inhalt durch den `jsonable_encoder` leitet, bevor es ihn an die Response-Klasse übergibt.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
|
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
|
||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ Um eine Response mit HTML direkt von **FastAPI** zurückzugeben, verwenden Sie `
|
|||||||
* Importieren Sie `HTMLResponse`.
|
* Importieren Sie `HTMLResponse`.
|
||||||
* Übergeben Sie `HTMLResponse` als den Parameter `response_class` Ihres *Pfadoperation-Dekorators*.
|
* Übergeben Sie `HTMLResponse` als den Parameter `response_class` Ihres *Pfadoperation-Dekorators*.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
|
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
|
||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ Wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link
|
|||||||
|
|
||||||
Das gleiche Beispiel von oben, das eine `HTMLResponse` zurückgibt, könnte so aussehen:
|
Das gleiche Beispiel von oben, das eine `HTMLResponse` zurückgibt, könnte so aussehen:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
|
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
|
||||||
|
|
||||||
/// warning | Achtung
|
/// warning | Achtung
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ Die `response_class` wird dann nur zur Dokumentation der OpenAPI-*Pfadoperation*
|
|||||||
|
|
||||||
Es könnte zum Beispiel so etwas sein:
|
Es könnte zum Beispiel so etwas sein:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
|
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
|
||||||
|
|
||||||
In diesem Beispiel generiert die Funktion `generate_html_response()` bereits eine `Response` und gibt sie zurück, anstatt das HTML in einem `str` zurückzugeben.
|
In diesem Beispiel generiert die Funktion `generate_html_response()` bereits eine `Response` und gibt sie zurück, anstatt das HTML in einem `str` zurückzugeben.
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ Sie akzeptiert die folgenden Parameter:
|
|||||||
|
|
||||||
FastAPI (eigentlich Starlette) fügt automatisch einen Content-Length-Header ein. Außerdem wird es einen Content-Type-Header einfügen, der auf dem media_type basiert, und für Texttypen einen Zeichensatz (charset) anfügen.
|
FastAPI (eigentlich Starlette) fügt automatisch einen Content-Length-Header ein. Außerdem wird es einen Content-Type-Header einfügen, der auf dem media_type basiert, und für Texttypen einen Zeichensatz (charset) anfügen.
|
||||||
|
|
||||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
|
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
|
||||||
|
|
||||||
### `HTMLResponse` { #htmlresponse }
|
### `HTMLResponse` { #htmlresponse }
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ Nimmt Text oder Bytes entgegen und gibt eine HTML-Response zurück, wie Sie oben
|
|||||||
|
|
||||||
Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurück.
|
Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurück.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
|
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
|
||||||
|
|
||||||
### `JSONResponse` { #jsonresponse }
|
### `JSONResponse` { #jsonresponse }
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ Dazu muss `ujson` installiert werden, z. B. mit `pip install ujson`.
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
|
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -194,13 +194,13 @@ Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurück. Verwendet standardmäßig
|
|||||||
|
|
||||||
Sie können eine `RedirectResponse` direkt zurückgeben:
|
Sie können eine `RedirectResponse` direkt zurückgeben:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
|
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Oder Sie können sie im Parameter `response_class` verwenden:
|
Oder Sie können sie im Parameter `response_class` verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
|
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
|
||||||
|
|
||||||
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||||
|
|
||||||
@@ -210,13 +210,13 @@ In diesem Fall ist der verwendete `status_code` der Standardcode für die `Redir
|
|||||||
|
|
||||||
Sie können den Parameter `status_code` auch in Kombination mit dem Parameter `response_class` verwenden:
|
Sie können den Parameter `status_code` auch in Kombination mit dem Parameter `response_class` verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
|
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
|
||||||
|
|
||||||
### `StreamingResponse` { #streamingresponse }
|
### `StreamingResponse` { #streamingresponse }
|
||||||
|
|
||||||
Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody.
|
Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
|
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
|
||||||
|
|
||||||
#### Verwendung von `StreamingResponse` mit dateiartigen Objekten { #using-streamingresponse-with-file-like-objects }
|
#### Verwendung von `StreamingResponse` mit dateiartigen Objekten { #using-streamingresponse-with-file-like-objects }
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ Auf diese Weise müssen Sie nicht alles zuerst in den Arbeitsspeicher lesen und
|
|||||||
|
|
||||||
Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen.
|
Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
|
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
|
||||||
|
|
||||||
1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält.
|
1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält.
|
||||||
2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiartige Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist.
|
2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiartige Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist.
|
||||||
@@ -255,11 +255,11 @@ Nimmt zur Instanziierung einen anderen Satz von Argumenten entgegen als die ande
|
|||||||
|
|
||||||
Datei-Responses enthalten die entsprechenden `Content-Length`-, `Last-Modified`- und `ETag`-Header.
|
Datei-Responses enthalten die entsprechenden `Content-Length`-, `Last-Modified`- und `ETag`-Header.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
|
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
|
||||||
|
|
||||||
Sie können auch den Parameter `response_class` verwenden:
|
Sie können auch den Parameter `response_class` verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
|
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
|
||||||
|
|
||||||
In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ Sie möchten etwa, dass Ihre Response eingerücktes und formatiertes JSON zurüc
|
|||||||
|
|
||||||
Sie könnten eine `CustomORJSONResponse` erstellen. Das Wichtigste, was Sie tun müssen, ist, eine `Response.render(content)`-Methode zu erstellen, die den Inhalt als `bytes` zurückgibt:
|
Sie könnten eine `CustomORJSONResponse` erstellen. Das Wichtigste, was Sie tun müssen, ist, eine `Response.render(content)`-Methode zu erstellen, die den Inhalt als `bytes` zurückgibt:
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
|
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
|
||||||
|
|
||||||
Statt:
|
Statt:
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ Der Parameter, der das definiert, ist `default_response_class`.
|
|||||||
|
|
||||||
Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`.
|
Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`.
|
||||||
|
|
||||||
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
|
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-M
|
|||||||
|
|
||||||
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>:
|
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>:
|
||||||
|
|
||||||
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
|
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
|
||||||
|
|
||||||
Das ist dank **Pydantic** ebenfalls möglich, da es <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses` intern unterstützt</a>.
|
Das ist dank **Pydantic** ebenfalls möglich, da es <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses` intern unterstützt</a>.
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ Wenn Sie jedoch eine Menge Datenklassen herumliegen haben, ist dies ein guter Tr
|
|||||||
|
|
||||||
Sie können `dataclasses` auch im Parameter `response_model` verwenden:
|
Sie können `dataclasses` auch im Parameter `response_model` verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
|
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
|
||||||
|
|
||||||
Die Datenklasse wird automatisch in eine Pydantic-Datenklasse konvertiert.
|
Die Datenklasse wird automatisch in eine Pydantic-Datenklasse konvertiert.
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ In einigen Fällen müssen Sie möglicherweise immer noch Pydantics Version von
|
|||||||
|
|
||||||
In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.dataclasses` ersetzen, was einen direkten Ersatz darstellt:
|
In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.dataclasses` ersetzen, was einen direkten Ersatz darstellt:
|
||||||
|
|
||||||
{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
|
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
|
||||||
|
|
||||||
1. Wir importieren `field` weiterhin von Standard-`dataclasses`.
|
1. Wir importieren `field` weiterhin von Standard-`dataclasses`.
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Beginnen wir mit einem Beispiel und sehen es uns dann im Detail an.
|
|||||||
|
|
||||||
Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt:
|
Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt:
|
||||||
|
|
||||||
{* ../../docs_src/events/tutorial003.py hl[16,19] *}
|
{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
|
||||||
|
|
||||||
Hier simulieren wir den langsamen *Startup*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*.
|
Hier simulieren wir den langsamen *Startup*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*.
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ Möglicherweise müssen Sie eine neue Version starten, oder Sie haben es einfach
|
|||||||
|
|
||||||
Das Erste, was auffällt, ist, dass wir eine asynchrone Funktion mit `yield` definieren. Das ist sehr ähnlich zu Abhängigkeiten mit `yield`.
|
Das Erste, was auffällt, ist, dass wir eine asynchrone Funktion mit `yield` definieren. Das ist sehr ähnlich zu Abhängigkeiten mit `yield`.
|
||||||
|
|
||||||
{* ../../docs_src/events/tutorial003.py hl[14:19] *}
|
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
|
||||||
|
|
||||||
Der erste Teil der Funktion, vor dem `yield`, wird ausgeführt **bevor** die Anwendung startet.
|
Der erste Teil der Funktion, vor dem `yield`, wird ausgeführt **bevor** die Anwendung startet.
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ Wie Sie sehen, ist die Funktion mit einem `@asynccontextmanager` versehen.
|
|||||||
|
|
||||||
Dadurch wird die Funktion in einen sogenannten „**asynchronen Kontextmanager**“ umgewandelt.
|
Dadurch wird die Funktion in einen sogenannten „**asynchronen Kontextmanager**“ umgewandelt.
|
||||||
|
|
||||||
{* ../../docs_src/events/tutorial003.py hl[1,13] *}
|
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
|
||||||
|
|
||||||
Ein **Kontextmanager** in Python ist etwas, das Sie in einer `with`-Anweisung verwenden können, zum Beispiel kann `open()` als Kontextmanager verwendet werden:
|
Ein **Kontextmanager** in Python ist etwas, das Sie in einer `with`-Anweisung verwenden können, zum Beispiel kann `open()` als Kontextmanager verwendet werden:
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ In unserem obigen Codebeispiel verwenden wir ihn nicht direkt, sondern übergebe
|
|||||||
|
|
||||||
Der Parameter `lifespan` der `FastAPI`-App benötigt einen **asynchronen Kontextmanager**, wir können ihm also unseren neuen asynchronen Kontextmanager `lifespan` übergeben.
|
Der Parameter `lifespan` der `FastAPI`-App benötigt einen **asynchronen Kontextmanager**, wir können ihm also unseren neuen asynchronen Kontextmanager `lifespan` übergeben.
|
||||||
|
|
||||||
{* ../../docs_src/events/tutorial003.py hl[22] *}
|
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
|
||||||
|
|
||||||
## Alternative Events (<abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr>) { #alternative-events-deprecated }
|
## Alternative Events (<abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr>) { #alternative-events-deprecated }
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ Diese Funktionen können mit `async def` oder normalem `def` deklariert werden.
|
|||||||
|
|
||||||
Um eine Funktion hinzuzufügen, die vor dem Start der Anwendung ausgeführt werden soll, deklarieren Sie diese mit dem Event `startup`:
|
Um eine Funktion hinzuzufügen, die vor dem Start der Anwendung ausgeführt werden soll, deklarieren Sie diese mit dem Event `startup`:
|
||||||
|
|
||||||
{* ../../docs_src/events/tutorial001.py hl[8] *}
|
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
|
||||||
|
|
||||||
In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenbank“ der Items (nur ein `dict`) mit einigen Werten.
|
In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenbank“ der Items (nur ein `dict`) mit einigen Werten.
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ Und Ihre Anwendung empfängt erst dann Requests, wenn alle `startup`-Eventhandle
|
|||||||
|
|
||||||
Um eine Funktion hinzuzufügen, die beim Shutdown der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `shutdown`:
|
Um eine Funktion hinzuzufügen, die beim Shutdown der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `shutdown`:
|
||||||
|
|
||||||
{* ../../docs_src/events/tutorial002.py hl[6] *}
|
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
|
||||||
|
|
||||||
Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.
|
Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ Aber für den generierten Client könnten wir die OpenAPI-Operation-IDs direkt v
|
|||||||
|
|
||||||
Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den präfixierten Tag entfernen**:
|
Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den präfixierten Tag entfernen**:
|
||||||
|
|
||||||
{* ../../docs_src/generate_clients/tutorial004.py *}
|
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
|
||||||
|
|
||||||
//// tab | Node.js
|
//// tab | Node.js
|
||||||
|
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ Erzwingt, dass alle eingehenden <abbr title="Request – Anfrage: Daten, die der
|
|||||||
|
|
||||||
Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
|
Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
|
||||||
|
|
||||||
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
|
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
|
||||||
|
|
||||||
## `TrustedHostMiddleware` { #trustedhostmiddleware }
|
## `TrustedHostMiddleware` { #trustedhostmiddleware }
|
||||||
|
|
||||||
Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
|
Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
|
||||||
|
|
||||||
{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
|
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
|
||||||
|
|
||||||
Die folgenden Argumente werden unterstützt:
|
Die folgenden Argumente werden unterstützt:
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`
|
|||||||
|
|
||||||
Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
|
Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
|
||||||
|
|
||||||
{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
|
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
|
||||||
|
|
||||||
Die folgenden Argumente werden unterstützt:
|
Die folgenden Argumente werden unterstützt:
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ 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:
|
Dieser Teil ist ziemlich normal, der größte Teil des Codes ist Ihnen wahrscheinlich bereits bekannt:
|
||||||
|
|
||||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -90,7 +90,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.
|
Erstellen Sie zunächst einen neuen `APIRouter`, der einen oder mehrere Callbacks enthält.
|
||||||
|
|
||||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
|
||||||
|
|
||||||
### Die Callback-*Pfadoperation* erstellen { #create-the-callback-path-operation }
|
### Die Callback-*Pfadoperation* erstellen { #create-the-callback-path-operation }
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ Sie sollte wie eine normale FastAPI-*Pfadoperation* aussehen:
|
|||||||
* Sie sollte wahrscheinlich eine Deklaration des Bodys enthalten, die sie erhalten soll, z. B. `body: InvoiceEvent`.
|
* Sie sollte wahrscheinlich eine Deklaration des Bodys enthalten, die sie erhalten soll, z. B. `body: InvoiceEvent`.
|
||||||
* Und sie könnte auch eine Deklaration der Response enthalten, die zurückgegeben werden soll, z. B. `response_model=InvoiceEventReceived`.
|
* Und sie könnte auch eine Deklaration der Response enthalten, die zurückgegeben werden soll, z. B. `response_model=InvoiceEventReceived`.
|
||||||
|
|
||||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
|
||||||
|
|
||||||
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
|
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ 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:
|
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:
|
||||||
|
|
||||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
|
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,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, das Sie verwenden können, um *Webhooks* zu definieren, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`.
|
Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, das Sie verwenden können, um *Webhooks* zu definieren, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`.
|
||||||
|
|
||||||
{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
|
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
|
||||||
|
|
||||||
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
|
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,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.
|
Sie müssten sicherstellen, dass sie für jede Operation eindeutig ist.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid }
|
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid }
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ 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.
|
Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefügt haben.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -40,7 +40,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`:
|
Um eine *Pfadoperation* aus dem generierten OpenAPI-Schema (und damit aus den automatischen Dokumentationssystemen) auszuschließen, verwenden Sie den Parameter `include_in_schema` und setzen Sie ihn auf `False`:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
|
||||||
|
|
||||||
## Fortgeschrittene Beschreibung mittels Docstring { #advanced-description-from-docstring }
|
## Fortgeschrittene Beschreibung mittels Docstring { #advanced-description-from-docstring }
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ Sie können die verwendeten Zeilen aus dem Docstring einer *Pfadoperation-Funkti
|
|||||||
|
|
||||||
Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu, dass **FastAPI** die für OpenAPI verwendete Ausgabe an dieser Stelle abschneidet.
|
Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu, dass **FastAPI** die für OpenAPI verwendete Ausgabe an dieser Stelle abschneidet.
|
||||||
|
|
||||||
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) können den Rest verwenden.
|
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (wie z. B. Sphinx) können den Rest verwenden.
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
|
||||||
|
|
||||||
## Zusätzliche Responses { #additional-responses }
|
## Zusätzliche Responses { #additional-responses }
|
||||||
|
|
||||||
@@ -92,7 +92,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](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) zu deklarieren:
|
Dieses `openapi_extra` kann beispielsweise hilfreich sein, um [OpenAPI-Erweiterungen](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) zu deklarieren:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
|
||||||
|
|
||||||
Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
|
Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request
|
|||||||
|
|
||||||
Das könnte man mit `openapi_extra` machen:
|
Das könnte man mit `openapi_extra` machen:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
|
||||||
|
|
||||||
In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <abbr title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertieren">geparst</abbr>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
|
In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <abbr title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertieren">geparst</abbr>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
|
||||||
|
|
||||||
@@ -153,47 +153,15 @@ Und Sie könnten dies auch tun, wenn der Datentyp im Request nicht JSON ist.
|
|||||||
|
|
||||||
In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
|
In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic Version 1 hieß die Methode zum Abrufen des JSON-Schemas für ein Modell `Item.schema()`, in Pydantic Version 2 heißt die Methode `Item.model_json_schema()`.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
Obwohl wir nicht die standardmäßig integrierte Funktionalität verwenden, verwenden wir dennoch ein Pydantic-Modell, um das JSON-Schema für die Daten, die wir in YAML empfangen möchten, manuell zu generieren.
|
Obwohl wir nicht die standardmäßig integrierte Funktionalität verwenden, verwenden wir dennoch ein Pydantic-Modell, um das JSON-Schema für die Daten, die wir in YAML empfangen möchten, manuell zu generieren.
|
||||||
|
|
||||||
Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das bedeutet, dass FastAPI nicht einmal versucht, den Request-Payload als JSON zu parsen.
|
Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das bedeutet, dass FastAPI nicht einmal versucht, die Request-Payload als JSON zu parsen.
|
||||||
|
|
||||||
Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann wieder dasselbe Pydantic-Modell, um den YAML-Inhalt zu validieren:
|
Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann wieder dasselbe Pydantic-Modell, um den YAML-Inhalt zu validieren:
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic Version 1 war die Methode zum Parsen und Validieren eines Objekts `Item.parse_obj()`, in Pydantic Version 2 heißt die Methode `Item.model_validate()`.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,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* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
|
Anschließend können Sie den `status_code` in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
|
||||||
|
|
||||||
{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
|
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
|
||||||
|
|
||||||
Und dann können Sie jedes benötigte Objekt zurückgeben, wie Sie es normalerweise tun würden (ein `dict`, ein Datenbankmodell usw.).
|
Und dann können Sie jedes benötigte Objekt zurückgeben, wie Sie es normalerweise tun würden (ein `dict`, ein Datenbankmodell usw.).
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
|||||||
|
|
||||||
Und dann können Sie Cookies in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt setzen.
|
Und dann können Sie Cookies in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt setzen.
|
||||||
|
|
||||||
{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
|
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
|
||||||
|
|
||||||
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ 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:
|
Setzen Sie dann Cookies darin und geben Sie sie dann zurück:
|
||||||
|
|
||||||
{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
|
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ 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:
|
In diesen Fällen können Sie den `jsonable_encoder` verwenden, um Ihre Daten zu konvertieren, bevor Sie sie an eine Response übergeben:
|
||||||
|
|
||||||
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
|
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ Nehmen wir an, Sie möchten eine <a href="https://en.wikipedia.org/wiki/XML" cla
|
|||||||
|
|
||||||
Sie könnten Ihren XML-Inhalt als String in eine `Response` einfügen und sie zurückgeben:
|
Sie könnten Ihren XML-Inhalt als String in eine `Response` einfügen und sie zurückgeben:
|
||||||
|
|
||||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
|
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
|
||||||
|
|
||||||
## Anmerkungen { #notes }
|
## Anmerkungen { #notes }
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
|||||||
|
|
||||||
Und dann können Sie Header in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
|
Und dann können Sie Header in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
|
||||||
|
|
||||||
{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
|
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
|
||||||
|
|
||||||
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ Sie können auch Header hinzufügen, wenn Sie eine `Response` direkt zurückgebe
|
|||||||
|
|
||||||
Erstellen Sie eine Response wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} beschrieben und übergeben Sie die Header als zusätzlichen Parameter:
|
Erstellen Sie eine Response wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} beschrieben und übergeben Sie die Header als zusätzlichen Parameter:
|
||||||
|
|
||||||
{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
|
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
|
|||||||
@@ -60,23 +60,7 @@ Auf die gleiche Weise wie bei Pydantic-Modellen deklarieren Sie Klassenattribute
|
|||||||
|
|
||||||
Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für Pydantic-Modelle verwenden, z. B. verschiedene Datentypen und zusätzliche Validierungen mit `Field()`.
|
Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für Pydantic-Modelle verwenden, z. B. verschiedene Datentypen und zusätzliche Validierungen mit `Field()`.
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
|
||||||
|
|
||||||
{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydantic_settings` importieren.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -92,7 +76,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:
|
Dann können Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
|
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
|
||||||
|
|
||||||
### Den Server ausführen { #run-the-server }
|
### Den Server ausführen { #run-the-server }
|
||||||
|
|
||||||
@@ -126,11 +110,11 @@ Sie könnten diese Einstellungen in eine andere Moduldatei einfügen, wie Sie in
|
|||||||
|
|
||||||
Sie könnten beispielsweise eine Datei `config.py` haben mit:
|
Sie könnten beispielsweise eine Datei `config.py` haben mit:
|
||||||
|
|
||||||
{* ../../docs_src/settings/app01/config.py *}
|
{* ../../docs_src/settings/app01_py39/config.py *}
|
||||||
|
|
||||||
Und dann verwenden Sie diese in einer Datei `main.py`:
|
Und dann verwenden Sie diese in einer Datei `main.py`:
|
||||||
|
|
||||||
{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
|
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -148,7 +132,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:
|
Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
|
||||||
|
|
||||||
{* ../../docs_src/settings/app02/config.py hl[10] *}
|
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
|
||||||
|
|
||||||
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
|
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
|
||||||
|
|
||||||
@@ -174,7 +158,7 @@ Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einf
|
|||||||
|
|
||||||
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
|
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
|
||||||
|
|
||||||
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
|
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -215,9 +199,7 @@ APP_NAME="ChimichangApp"
|
|||||||
|
|
||||||
Und dann aktualisieren Sie Ihre `config.py` mit:
|
Und dann aktualisieren Sie Ihre `config.py` mit:
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -225,26 +207,6 @@ Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet.
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
|
|
||||||
|
|
||||||
/// tip | Tipp
|
|
||||||
|
|
||||||
Die Klasse `Config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic Version 1 erfolgte die Konfiguration in einer internen Klasse `Config`, in Pydantic Version 2 erfolgt sie in einem Attribut `model_config`. Dieses Attribut akzeptiert ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr>. Um automatische Codevervollständigung und Inline-Fehlerberichte zu erhalten, können Sie `SettingsConfigDict` importieren und verwenden, um dieses `dict` zu definieren.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden möchten.
|
Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden möchten.
|
||||||
|
|
||||||
### Die `Settings` nur einmal laden mittels `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
### Die `Settings` nur einmal laden mittels `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen O
|
|||||||
|
|
||||||
Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
|
Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
|
||||||
|
|
||||||
{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
|
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
|
||||||
|
|
||||||
### Unteranwendung { #sub-application }
|
### Unteranwendung { #sub-application }
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*.
|
|||||||
|
|
||||||
Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
|
Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
|
||||||
|
|
||||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
|
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
|
||||||
|
|
||||||
### Die Unteranwendung mounten { #mount-the-sub-application }
|
### Die Unteranwendung mounten { #mount-the-sub-application }
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`.
|
|||||||
|
|
||||||
In diesem Fall wird sie im Pfad `/subapi` gemountet:
|
In diesem Fall wird sie im Pfad `/subapi` gemountet:
|
||||||
|
|
||||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
|
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
|
||||||
|
|
||||||
### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs }
|
### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs }
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ $ pip install jinja2
|
|||||||
* Deklarieren Sie einen `<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>`-Parameter in der *Pfadoperation*, welcher ein Template zurückgibt.
|
* Deklarieren Sie einen `<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>`-Parameter in der *Pfadoperation*, welcher ein Template zurückgibt.
|
||||||
* Verwenden Sie die von Ihnen erstellten `templates`, um eine `TemplateResponse` zu rendern und zurückzugeben, übergeben Sie den Namen des Templates, das Requestobjekt und ein „Kontext“-<abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Schlüssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen.
|
* 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“-<abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Schlüssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen.
|
||||||
|
|
||||||
{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
|
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
Wenn Sie `lifespan` in Ihren Tests ausführen müssen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
|
Wenn Sie `lifespan` in Ihren Tests ausführen müssen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
|
{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
|
||||||
|
|
||||||
|
|
||||||
Sie können mehr Details unter [„Lifespan in Tests ausführen in der offiziellen Starlette-Dokumentation.“](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) nachlesen.
|
Sie können mehr Details unter [„Lifespan in Tests ausführen in der offiziellen Starlette-Dokumentation.“](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) nachlesen.
|
||||||
|
|
||||||
Für die deprecateten Events <abbr title="Hochfahren">`startup`</abbr> und <abbr title="Herunterfahren">`shutdown`</abbr> können Sie den `TestClient` wie folgt verwenden:
|
Für die deprecateten Events <abbr title="Hochfahren">`startup`</abbr> und <abbr title="Herunterfahren">`shutdown`</abbr> können Sie den `TestClient` wie folgt verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
|
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ 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:
|
Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung zum WebSocket herstellend:
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
|
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Angenommen, Sie möchten auf die IP-Adresse/den Host des Clients in Ihrer *Pfado
|
|||||||
|
|
||||||
Dazu müssen Sie direkt auf den Request zugreifen.
|
Dazu müssen Sie direkt auf den Request zugreifen.
|
||||||
|
|
||||||
{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
|
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
|
||||||
|
|
||||||
Durch die Deklaration eines *Pfadoperation-Funktionsparameters*, dessen Typ der `Request` ist, weiß **FastAPI**, dass es den `Request` diesem Parameter übergeben soll.
|
Durch die Deklaration eines *Pfadoperation-Funktionsparameters*, dessen Typ der `Request` ist, weiß **FastAPI**, dass es den `Request` diesem Parameter übergeben soll.
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ In der Produktion hätten Sie eine der oben genannten Optionen.
|
|||||||
|
|
||||||
Aber es ist der einfachste Weg, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben:
|
Aber es ist der einfachste Weg, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben:
|
||||||
|
|
||||||
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
|
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
|
||||||
|
|
||||||
## Einen `websocket` erstellen { #create-a-websocket }
|
## Einen `websocket` erstellen { #create-a-websocket }
|
||||||
|
|
||||||
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
|
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
|
||||||
|
|
||||||
{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
|
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ Sie könnten auch `from starlette.websockets import WebSocket` verwenden.
|
|||||||
|
|
||||||
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
|
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
|
||||||
|
|
||||||
{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
|
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
|
||||||
|
|
||||||
Sie können Binär-, Text- und JSON-Daten empfangen und senden.
|
Sie können Binär-, Text- und JSON-Daten empfangen und senden.
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
|
|||||||
|
|
||||||
Und dann mounten Sie das auf einem Pfad.
|
Und dann mounten Sie das auf einem Pfad.
|
||||||
|
|
||||||
{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
|
{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
|
||||||
|
|
||||||
## Es testen { #check-it }
|
## Es testen { #check-it }
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener
|
|||||||
|
|
||||||
Zum Beispiel:
|
Zum Beispiel:
|
||||||
|
|
||||||
{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
|
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
|
||||||
|
|
||||||
Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.
|
Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Ohne Änderung der Einstellungen ist die Syntaxhervorhebung standardmäßig akti
|
|||||||
|
|
||||||
Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` setzen:
|
Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` setzen:
|
||||||
|
|
||||||
{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
|
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
|
||||||
|
|
||||||
... und dann zeigt die Swagger-Oberfläche die Syntaxhervorhebung nicht mehr an:
|
... und dann zeigt die Swagger-Oberfläche die Syntaxhervorhebung nicht mehr an:
|
||||||
|
|
||||||
@@ -28,7 +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):
|
Auf die gleiche Weise könnten Sie das Theme der Syntaxhervorhebung mit dem Schlüssel `"syntaxHighlight.theme"` festlegen (beachten Sie, dass er einen Punkt in der Mitte hat):
|
||||||
|
|
||||||
{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
|
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
|
||||||
|
|
||||||
Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern:
|
Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern:
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ FastAPI enthält einige Defaultkonfigurationsparameter, die für die meisten Anw
|
|||||||
|
|
||||||
Es umfasst die folgenden Defaultkonfigurationen:
|
Es umfasst die folgenden Defaultkonfigurationen:
|
||||||
|
|
||||||
{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
|
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
|
||||||
|
|
||||||
Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_parameters` einen anderen Wert festlegen.
|
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:
|
Um beispielsweise `deepLinking` zu deaktivieren, könnten Sie folgende Einstellungen an `swagger_ui_parameters` übergeben:
|
||||||
|
|
||||||
{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
|
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
|
||||||
|
|
||||||
## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters }
|
## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters }
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,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`:
|
Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
|
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
|
||||||
|
|
||||||
### Die benutzerdefinierten Dokumentationen hinzufügen { #include-the-custom-docs }
|
### Die benutzerdefinierten Dokumentationen hinzufügen { #include-the-custom-docs }
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ Sie können die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei
|
|||||||
|
|
||||||
Und ähnlich für ReDoc ...
|
Und ähnlich für ReDoc ...
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
|
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -50,7 +50,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*:
|
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
|
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
|
||||||
|
|
||||||
### Es testen { #test-it }
|
### Es testen { #test-it }
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen:
|
|||||||
* Importieren Sie `StaticFiles`.
|
* Importieren Sie `StaticFiles`.
|
||||||
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
|
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
|
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
|
||||||
|
|
||||||
### Die statischen Dateien testen { #test-the-static-files }
|
### Die statischen Dateien testen { #test-the-static-files }
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt d
|
|||||||
|
|
||||||
Um sie zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
|
Um sie zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
|
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
|
||||||
|
|
||||||
### Die benutzerdefinierten Dokumentationen für statische Dateien hinzufügen { #include-the-custom-docs-for-static-files }
|
### Die benutzerdefinierten Dokumentationen für statische Dateien hinzufügen { #include-the-custom-docs-for-static-files }
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ Auch hier können Sie die internen Funktionen von FastAPI wiederverwenden, um di
|
|||||||
|
|
||||||
Und ähnlich für ReDoc ...
|
Und ähnlich für ReDoc ...
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
|
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -176,7 +176,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*:
|
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
|
||||||
|
|
||||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
|
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
|
||||||
|
|
||||||
### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui }
|
### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui }
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,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.
|
Auf diese Weise kann dieselbe Routenklasse gzip-komprimierte oder unkomprimierte Requests verarbeiten.
|
||||||
|
|
||||||
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
|
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
|
||||||
|
|
||||||
### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen { #create-a-custom-gziproute-class }
|
### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen { #create-a-custom-gziproute-class }
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ Diese Methode gibt eine Funktion zurück. Und diese Funktion empfängt einen <ab
|
|||||||
|
|
||||||
Hier verwenden wir sie, um aus dem ursprünglichen Request einen `GzipRequest` zu erstellen.
|
Hier verwenden wir sie, um aus dem ursprünglichen Request einen `GzipRequest` zu erstellen.
|
||||||
|
|
||||||
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
|
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
@@ -92,18 +92,18 @@ 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:
|
Alles, was wir tun müssen, ist, den Request innerhalb eines `try`/`except`-Blocks zu handhaben:
|
||||||
|
|
||||||
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
|
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
|
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
|
||||||
|
|
||||||
## Benutzerdefinierte `APIRoute`-Klasse in einem Router { #custom-apiroute-class-in-a-router }
|
## Benutzerdefinierte `APIRoute`-Klasse in einem Router { #custom-apiroute-class-in-a-router }
|
||||||
|
|
||||||
Sie können auch den Parameter `route_class` eines `APIRouter` festlegen:
|
Sie können auch den Parameter `route_class` eines `APIRouter` festlegen:
|
||||||
|
|
||||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
|
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
|
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
|
||||||
|
|||||||
@@ -43,19 +43,19 @@ Fügen wir beispielsweise <a href="https://github.com/Rebilly/ReDoc/blob/master/
|
|||||||
|
|
||||||
Schreiben Sie zunächst wie gewohnt Ihre ganze **FastAPI**-Anwendung:
|
Schreiben Sie zunächst wie gewohnt Ihre ganze **FastAPI**-Anwendung:
|
||||||
|
|
||||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
|
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
|
||||||
|
|
||||||
### Das OpenAPI-Schema generieren { #generate-the-openapi-schema }
|
### Das OpenAPI-Schema generieren { #generate-the-openapi-schema }
|
||||||
|
|
||||||
Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren:
|
Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren:
|
||||||
|
|
||||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
|
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
|
||||||
|
|
||||||
### Das OpenAPI-Schema ändern { #modify-the-openapi-schema }
|
### Das OpenAPI-Schema ändern { #modify-the-openapi-schema }
|
||||||
|
|
||||||
Jetzt können Sie die ReDoc-Erweiterung hinzufügen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufügen:
|
Jetzt können Sie die ReDoc-Erweiterung hinzufügen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufügen:
|
||||||
|
|
||||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
|
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
|
||||||
|
|
||||||
### Zwischenspeichern des OpenAPI-Schemas { #cache-the-openapi-schema }
|
### Zwischenspeichern des OpenAPI-Schemas { #cache-the-openapi-schema }
|
||||||
|
|
||||||
@@ -65,13 +65,13 @@ Auf diese Weise muss Ihre Anwendung das Schema nicht jedes Mal generieren, wenn
|
|||||||
|
|
||||||
Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema für die nächsten <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> verwendet.
|
Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema für die nächsten <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> verwendet.
|
||||||
|
|
||||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
|
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
|
||||||
|
|
||||||
### Die Methode überschreiben { #override-the-method }
|
### Die Methode überschreiben { #override-the-method }
|
||||||
|
|
||||||
Jetzt können Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen.
|
Jetzt können Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen.
|
||||||
|
|
||||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
|
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
|
||||||
|
|
||||||
### Es testen { #check-it }
|
### Es testen { #check-it }
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Abhängig von Ihrem Anwendungsfall könnten Sie eine andere Bibliothek vorziehen
|
|||||||
|
|
||||||
Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
|
Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
|
||||||
|
|
||||||
{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
|
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
|
||||||
|
|
||||||
Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.
|
Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,23 @@
|
|||||||
|
|
||||||
Wenn Sie eine ältere FastAPI-App haben, nutzen Sie möglicherweise Pydantic Version 1.
|
Wenn Sie eine ältere FastAPI-App haben, nutzen Sie möglicherweise Pydantic Version 1.
|
||||||
|
|
||||||
FastAPI unterstützt seit Version 0.100.0 sowohl Pydantic v1 als auch v2.
|
FastAPI Version 0.100.0 unterstützte sowohl Pydantic v1 als auch v2. Es verwendete, was auch immer Sie installiert hatten.
|
||||||
|
|
||||||
Wenn Sie Pydantic v2 installiert hatten, wurde dieses verwendet. Wenn stattdessen Pydantic v1 installiert war, wurde jenes verwendet.
|
FastAPI Version 0.119.0 führte eine teilweise Unterstützung für Pydantic v1 innerhalb von Pydantic v2 (als `pydantic.v1`) ein, um die Migration zu v2 zu erleichtern.
|
||||||
|
|
||||||
Pydantic v1 ist jetzt deprecatet und die Unterstützung dafür wird in den nächsten Versionen von FastAPI entfernt, Sie sollten also zu **Pydantic v2 migrieren**. Auf diese Weise erhalten Sie die neuesten Features, Verbesserungen und Fixes.
|
FastAPI 0.126.0 entfernte die Unterstützung für Pydantic v1, während `pydantic.v1` noch eine Weile unterstützt wurde.
|
||||||
|
|
||||||
/// warning | Achtung
|
/// warning | Achtung
|
||||||
|
|
||||||
Außerdem hat das Pydantic-Team die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
|
Das Pydantic-Team hat die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
|
||||||
|
|
||||||
|
Dies schließt `pydantic.v1` ein, das unter Python 3.14 und höher nicht mehr unterstützt wird.
|
||||||
|
|
||||||
Wenn Sie die neuesten Features von Python nutzen möchten, müssen Sie sicherstellen, dass Sie Pydantic v2 verwenden.
|
Wenn Sie die neuesten Features von Python nutzen möchten, müssen Sie sicherstellen, dass Sie Pydantic v2 verwenden.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Wenn Sie eine ältere FastAPI-App mit Pydantic v1 haben, zeige ich Ihnen hier, wie Sie sie zu Pydantic v2 migrieren, und die **neuen Features in FastAPI 0.119.0**, die Ihnen bei einer schrittweisen Migration helfen.
|
Wenn Sie eine ältere FastAPI-App mit Pydantic v1 haben, zeige ich Ihnen hier, wie Sie sie zu Pydantic v2 migrieren, und die **Features in FastAPI 0.119.0**, die Ihnen bei einer schrittweisen Migration helfen.
|
||||||
|
|
||||||
## Offizieller Leitfaden { #official-guide }
|
## Offizieller Leitfaden { #official-guide }
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ Danach können Sie die Tests ausführen und prüfen, ob alles funktioniert. Fall
|
|||||||
|
|
||||||
## Pydantic v1 in v2 { #pydantic-v1-in-v2 }
|
## Pydantic v1 in v2 { #pydantic-v1-in-v2 }
|
||||||
|
|
||||||
Pydantic v2 enthält alles aus Pydantic v1 als Untermodul `pydantic.v1`.
|
Pydantic v2 enthält alles aus Pydantic v1 als Untermodul `pydantic.v1`. Dies wird aber in Versionen oberhalb von Python 3.13 nicht mehr unterstützt.
|
||||||
|
|
||||||
Das bedeutet, Sie können die neueste Version von Pydantic v2 installieren und die alten Pydantic‑v1‑Komponenten aus diesem Untermodul importieren und verwenden, als hätten Sie das alte Pydantic v1 installiert.
|
Das bedeutet, Sie können die neueste Version von Pydantic v2 installieren und die alten Pydantic‑v1‑Komponenten aus diesem Untermodul importieren und verwenden, als hätten Sie das alte Pydantic v1 installiert.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Separate OpenAPI-Schemas für Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not }
|
# Separate OpenAPI-Schemas für Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not }
|
||||||
|
|
||||||
Bei Verwendung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
|
Seit der Veröffentlichung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
|
||||||
|
|
||||||
Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI für dasselbe Pydantic-Modell, für Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben.
|
Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI für dasselbe Pydantic-Modell, für Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben.
|
||||||
|
|
||||||
@@ -100,5 +100,3 @@ Und jetzt wird es ein einziges Schema für die Eingabe und Ausgabe des Modells g
|
|||||||
<div class="screenshot">
|
<div class="screenshot">
|
||||||
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Dies ist das gleiche Verhalten wie in Pydantic v1. 🤓
|
|
||||||
|
|||||||
+14
-8
@@ -52,13 +52,13 @@ Seine Schlüssel-Merkmale sind:
|
|||||||
|
|
||||||
<!-- sponsors -->
|
<!-- sponsors -->
|
||||||
|
|
||||||
### Keystone-Sponsor
|
### Keystone-Sponsor { #keystone-sponsor }
|
||||||
|
|
||||||
{% for sponsor in sponsors.keystone -%}
|
{% for sponsor in sponsors.keystone -%}
|
||||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
|
|
||||||
### Gold- und Silber-Sponsoren
|
### Gold- und Silber-Sponsoren { #gold-and-silver-sponsors }
|
||||||
|
|
||||||
{% for sponsor in sponsors.gold -%}
|
{% for sponsor in sponsors.gold -%}
|
||||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
@@ -117,6 +117,12 @@ Seine Schlüssel-Merkmale sind:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## FastAPI Mini-Dokumentarfilm { #fastapi-mini-documentary }
|
||||||
|
|
||||||
|
Es gibt einen <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI-Mini-Dokumentarfilm</a>, veröffentlicht Ende 2025, Sie können ihn online ansehen:
|
||||||
|
|
||||||
|
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini-Dokumentarfilm"></a>
|
||||||
|
|
||||||
## **Typer**, das FastAPI der CLIs { #typer-the-fastapi-of-clis }
|
## **Typer**, das FastAPI der CLIs { #typer-the-fastapi-of-clis }
|
||||||
|
|
||||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||||
@@ -233,7 +239,7 @@ INFO: Application startup complete.
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<details markdown="1">
|
<details markdown="1">
|
||||||
<summary>Was der Befehl <code>fastapi dev main.py</code> macht ...</summary>
|
<summary>Über den Befehl <code>fastapi dev main.py</code> ...</summary>
|
||||||
|
|
||||||
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
|
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
|
||||||
|
|
||||||
@@ -276,7 +282,7 @@ Sie sehen die alternative automatische Dokumentation (bereitgestellt von <a href
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Beispiel Aktualisierung { #example-upgrade }
|
## Beispielaktualisierung { #example-upgrade }
|
||||||
|
|
||||||
Ändern Sie jetzt die Datei `main.py`, um den <abbr title="Body – Körper, Inhalt: Der eigentliche Inhalt einer Nachricht, nicht die Metadaten">Body</abbr> eines `PUT`-Requests zu empfangen.
|
Ändern Sie jetzt die Datei `main.py`, um den <abbr title="Body – Körper, Inhalt: Der eigentliche Inhalt einer Nachricht, nicht die Metadaten">Body</abbr> eines `PUT`-Requests zu empfangen.
|
||||||
|
|
||||||
@@ -326,7 +332,7 @@ Gehen Sie jetzt auf <a href="http://127.0.0.1:8000/docs" class="external-link" t
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
* Klicken Sie dann auf den Button „Execute“, die Benutzeroberfläche wird mit Ihrer API kommunizieren, sendet die Parameter, holt die Ergebnisse und zeigt sie auf dem Bildschirm an:
|
* Klicken Sie dann auf den Button „Execute“, die Benutzeroberfläche wird mit Ihrer API kommunizieren, die Parameter senden, die Ergebnisse erhalten und sie auf dem Bildschirm anzeigen:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -439,7 +445,7 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
|
|||||||
|
|
||||||
* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header**, **Cookies**, **Formularfelder** und **Dateien**.
|
* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header**, **Cookies**, **Formularfelder** und **Dateien**.
|
||||||
* Wie man **Validierungs-Constraints** wie `maximum_length` oder `regex` setzt.
|
* Wie man **Validierungs-Constraints** wie `maximum_length` oder `regex` setzt.
|
||||||
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<abbr title="Dependency Injection – Einbringen von Abhängigkeiten: Auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>**.
|
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<abbr title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>**.
|
||||||
* Sicherheit und Authentifizierung, einschließlich Unterstützung für **OAuth2** mit **JWT-Tokens** und **HTTP Basic** Authentifizierung.
|
* Sicherheit und Authentifizierung, einschließlich Unterstützung für **OAuth2** mit **JWT-Tokens** und **HTTP Basic** Authentifizierung.
|
||||||
* Fortgeschrittenere (aber ebenso einfache) Techniken zur Deklaration **tief verschachtelter JSON-Modelle** (dank Pydantic).
|
* Fortgeschrittenere (aber ebenso einfache) Techniken zur Deklaration **tief verschachtelter JSON-Modelle** (dank Pydantic).
|
||||||
* **GraphQL**-Integration mit <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> und anderen Bibliotheken.
|
* **GraphQL**-Integration mit <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> und anderen Bibliotheken.
|
||||||
@@ -452,7 +458,7 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
|
|||||||
|
|
||||||
### Ihre App deployen (optional) { #deploy-your-app-optional }
|
### Ihre App deployen (optional) { #deploy-your-app-optional }
|
||||||
|
|
||||||
Optional können Sie Ihre FastAPI-App in die <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
|
Optional können Sie Ihre FastAPI-App in die <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, gehen Sie und treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
|
||||||
|
|
||||||
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem einzigen Befehl deployen.
|
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem einzigen Befehl deployen.
|
||||||
|
|
||||||
@@ -494,7 +500,7 @@ Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Zugreifens**
|
|||||||
|
|
||||||
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
|
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
|
||||||
|
|
||||||
FastAPI Cloud ist der Hauptsponsor und Finanzierer der „FastAPI and friends“ Open-Source-Projekte. ✨
|
FastAPI Cloud ist der Hauptsponsor und Finanzierer der *FastAPI and friends* Open-Source-Projekte. ✨
|
||||||
|
|
||||||
#### Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
|
#### Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,18 @@ GitHub-Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-templ
|
|||||||
## Full Stack FastAPI Template – Technologiestack und Funktionen { #full-stack-fastapi-template-technology-stack-and-features }
|
## Full Stack FastAPI Template – Technologiestack und Funktionen { #full-stack-fastapi-template-technology-stack-and-features }
|
||||||
|
|
||||||
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/de) für die Python-Backend-API.
|
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/de) für die Python-Backend-API.
|
||||||
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
|
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
|
||||||
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
|
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
|
||||||
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
|
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
|
||||||
- 🚀 [React](https://react.dev) für das Frontend.
|
- 🚀 [React](https://react.dev) für das Frontend.
|
||||||
- 💃 Verwendung von TypeScript, Hooks, [Vite](https://vitejs.dev) und anderen Teilen eines modernen Frontend-Stacks.
|
- 💃 Verwendung von TypeScript, Hooks, Vite und anderen Teilen eines modernen Frontend-Stacks.
|
||||||
- 🎨 [Chakra UI](https://chakra-ui.com) für die Frontend-Komponenten.
|
- 🎨 [Tailwind CSS](https://tailwindcss.com) und [shadcn/ui](https://ui.shadcn.com) für die Frontend-Komponenten.
|
||||||
- 🤖 Ein automatisch generierter Frontend-Client.
|
- 🤖 Ein automatisch generierter Frontend-Client.
|
||||||
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
|
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
|
||||||
- 🦇 Unterstützung des Dunkelmodus.
|
- 🦇 „Dark-Mode“-Unterstützung.
|
||||||
- 🐋 [Docker Compose](https://www.docker.com) für Entwicklung und Produktion.
|
- 🐋 [Docker Compose](https://www.docker.com) für Entwicklung und Produktion.
|
||||||
- 🔒 Sicheres Passwort-Hashing standardmäßig.
|
- 🔒 Sicheres Passwort-Hashing standardmäßig.
|
||||||
- 🔑 JWT-Token-Authentifizierung.
|
- 🔑 JWT (JSON Web Token)-Token-Authentifizierung.
|
||||||
- 📫 E-Mail-basierte Passwortwiederherstellung.
|
- 📫 E-Mail-basierte Passwortwiederherstellung.
|
||||||
- ✅ Tests mit [Pytest](https://pytest.org).
|
- ✅ Tests mit [Pytest](https://pytest.org).
|
||||||
- 📞 [Traefik](https://traefik.io) als Reverse-Proxy / Load Balancer.
|
- 📞 [Traefik](https://traefik.io) als Reverse-Proxy / Load Balancer.
|
||||||
|
|||||||
+30
-142
@@ -22,7 +22,7 @@ Wenn Sie ein Python-Experte sind und bereits alles über Typhinweise wissen, üb
|
|||||||
|
|
||||||
Fangen wir mit einem einfachen Beispiel an:
|
Fangen wir mit einem einfachen Beispiel an:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial001.py *}
|
{* ../../docs_src/python_types/tutorial001_py39.py *}
|
||||||
|
|
||||||
Dieses Programm gibt aus:
|
Dieses Programm gibt aus:
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ Die Funktion macht Folgendes:
|
|||||||
|
|
||||||
* Nimmt einen `first_name` und `last_name`.
|
* Nimmt einen `first_name` und `last_name`.
|
||||||
* Schreibt den ersten Buchstaben eines jeden Wortes groß, mithilfe von `title()`.
|
* Schreibt den ersten Buchstaben eines jeden Wortes groß, mithilfe von `title()`.
|
||||||
* <abbr title="Füge zu einer Einheit zusammen, eins nach dem anderen.">Verkettet</abbr> sie mit einem Leerzeichen in der Mitte.
|
* <abbr title="Fügt sie zu einer Einheit zusammen. Mit dem Inhalt des einen nach dem anderen.">Verkettet</abbr> sie mit einem Leerzeichen in der Mitte.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
|
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
|
||||||
|
|
||||||
### Es bearbeiten { #edit-it }
|
### Es bearbeiten { #edit-it }
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ Das war's.
|
|||||||
|
|
||||||
Das sind die „Typhinweise“:
|
Das sind die „Typhinweise“:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial002.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
|
||||||
|
|
||||||
Das ist nicht das gleiche wie das Deklarieren von Defaultwerten, wie es hier der Fall ist:
|
Das ist nicht das gleiche wie das Deklarieren von Defaultwerten, wie es hier der Fall ist:
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ Hier können Sie durch die Optionen blättern, bis Sie diejenige finden, bei der
|
|||||||
|
|
||||||
Sehen Sie sich diese Funktion an, sie hat bereits Typhinweise:
|
Sehen Sie sich diese Funktion an, sie hat bereits Typhinweise:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial003.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
|
||||||
|
|
||||||
Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervollständigung, sondern auch eine Fehlerprüfung:
|
Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervollständigung, sondern auch eine Fehlerprüfung:
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervoll
|
|||||||
|
|
||||||
Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mittels `str(age)` in einen String:
|
Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mittels `str(age)` in einen String:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial004.py hl[2] *}
|
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
|
||||||
|
|
||||||
## Deklarieren von Typen { #declaring-types }
|
## Deklarieren von Typen { #declaring-types }
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ Zum Beispiel diese:
|
|||||||
* `bool`
|
* `bool`
|
||||||
* `bytes`
|
* `bytes`
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
|
||||||
|
|
||||||
### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters }
|
### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters }
|
||||||
|
|
||||||
@@ -161,56 +161,24 @@ Wenn Sie über die **neueste Version von Python** verfügen, verwenden Sie die B
|
|||||||
|
|
||||||
Definieren wir zum Beispiel eine Variable, die eine `list` von `str` – eine Liste von Strings – sein soll.
|
Definieren wir zum Beispiel eine Variable, die eine `list` von `str` – eine Liste von Strings – sein soll.
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
|
||||||
|
|
||||||
Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
|
Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
|
||||||
|
|
||||||
Als Typ nehmen Sie `list`.
|
Als Typ nehmen Sie `list`.
|
||||||
|
|
||||||
Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
|
Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
|
||||||
|
|
||||||
```Python hl_lines="1"
|
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
|
||||||
{!> ../../docs_src/python_types/tutorial006_py39.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
Von `typing` importieren Sie `List` (mit Großbuchstaben `L`):
|
|
||||||
|
|
||||||
```Python hl_lines="1"
|
|
||||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
|
|
||||||
|
|
||||||
Als Typ nehmen Sie das `List`, das Sie von `typing` importiert haben.
|
|
||||||
|
|
||||||
Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
|
|
||||||
|
|
||||||
```Python hl_lines="4"
|
|
||||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
Die inneren Typen in den eckigen Klammern werden als „Typ-Parameter“ bezeichnet.
|
Die inneren Typen in den eckigen Klammern werden als „Typ-Parameter“ bezeichnet.
|
||||||
|
|
||||||
In diesem Fall ist `str` der Typ-Parameter, der an `List` übergeben wird (oder `list` in Python 3.9 und darüber).
|
In diesem Fall ist `str` der Typ-Parameter, der an `list` übergeben wird.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
Das bedeutet: Die Variable `items` ist eine Liste – `list` – und jedes der Elemente in dieser Liste ist ein String – `str`.
|
Das bedeutet: Die Variable `items` ist eine Liste – `list` – und jedes der Elemente in dieser Liste ist ein String – `str`.
|
||||||
|
|
||||||
/// tip | Tipp
|
|
||||||
|
|
||||||
Wenn Sie Python 3.9 oder höher verwenden, müssen Sie `List` nicht von `typing` importieren, Sie können stattdessen den regulären `list`-Typ verwenden.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
Auf diese Weise kann Ihr Editor Sie auch bei der Bearbeitung von Einträgen aus der Liste unterstützen:
|
Auf diese Weise kann Ihr Editor Sie auch bei der Bearbeitung von Einträgen aus der Liste unterstützen:
|
||||||
|
|
||||||
<img src="/img/python-types/image05.png">
|
<img src="/img/python-types/image05.png">
|
||||||
@@ -225,21 +193,7 @@ Und trotzdem weiß der Editor, dass es sich um ein `str` handelt, und bietet ent
|
|||||||
|
|
||||||
Das Gleiche gilt für die Deklaration eines Tupels – `tuple` – und einer Menge – `set`:
|
Das Gleiche gilt für die Deklaration eines Tupels – `tuple` – und einer Menge – `set`:
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
|
||||||
|
|
||||||
```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!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
Das bedeutet:
|
Das bedeutet:
|
||||||
|
|
||||||
@@ -254,21 +208,7 @@ Der erste Typ-Parameter ist für die Schlüssel des `dict`.
|
|||||||
|
|
||||||
Der zweite Typ-Parameter ist für die Werte des `dict`:
|
Der zweite Typ-Parameter ist für die Werte des `dict`:
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
|
||||||
|
|
||||||
```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!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
Das bedeutet:
|
Das bedeutet:
|
||||||
|
|
||||||
@@ -282,7 +222,7 @@ Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** se
|
|||||||
|
|
||||||
In Python 3.6 und höher (inklusive Python 3.10) können Sie den `Union`-Typ von `typing` verwenden und die möglichen Typen innerhalb der eckigen Klammern auflisten.
|
In Python 3.6 und höher (inklusive Python 3.10) können Sie den `Union`-Typ von `typing` verwenden und die möglichen Typen innerhalb der eckigen Klammern auflisten.
|
||||||
|
|
||||||
In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem <abbr title='Allgemein: „oder“. In anderem Zusammenhang auch „Bitweises ODER“, aber letztere Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> aufzulisten.
|
In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem <abbr title='auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> aufzulisten.
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
//// tab | Python 3.10+
|
||||||
|
|
||||||
@@ -292,10 +232,10 @@ In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die mö
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
```Python hl_lines="1 4"
|
||||||
{!> ../../docs_src/python_types/tutorial008b.py!}
|
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
|
||||||
```
|
```
|
||||||
|
|
||||||
////
|
////
|
||||||
@@ -309,7 +249,7 @@ Sie können deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` se
|
|||||||
In Python 3.6 und darüber (inklusive Python 3.10) können Sie das deklarieren, indem Sie `Optional` vom `typing` Modul importieren und verwenden.
|
In Python 3.6 und darüber (inklusive Python 3.10) können Sie das deklarieren, indem Sie `Optional` vom `typing` Modul importieren und verwenden.
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
```Python hl_lines="1 4"
|
||||||
{!../../docs_src/python_types/tutorial009.py!}
|
{!../../docs_src/python_types/tutorial009_py39.py!}
|
||||||
```
|
```
|
||||||
|
|
||||||
Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein könnte.
|
Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein könnte.
|
||||||
@@ -326,18 +266,18 @@ Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
```Python hl_lines="1 4"
|
||||||
{!> ../../docs_src/python_types/tutorial009.py!}
|
{!> ../../docs_src/python_types/tutorial009_py39.py!}
|
||||||
```
|
```
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ Alternative
|
//// tab | Python 3.9+ Alternative
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
```Python hl_lines="1 4"
|
||||||
{!> ../../docs_src/python_types/tutorial009b.py!}
|
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
|
||||||
```
|
```
|
||||||
|
|
||||||
////
|
////
|
||||||
@@ -353,11 +293,11 @@ Beide sind äquivalent und im Hintergrund dasselbe, aber ich empfehle `Union` st
|
|||||||
|
|
||||||
Ich denke, `Union[SomeType, None]` ist expliziter bezüglich seiner Bedeutung.
|
Ich denke, `Union[SomeType, None]` ist expliziter bezüglich seiner Bedeutung.
|
||||||
|
|
||||||
Es geht nur um Wörter und Namen. Aber diese Worte können beeinflussen, wie Sie und Ihre Teamkollegen über den Code denken.
|
Es geht nur um Worte und Namen. Aber diese Worte können beeinflussen, wie Sie und Ihre Teamkollegen über den Code denken.
|
||||||
|
|
||||||
Nehmen wir zum Beispiel diese Funktion:
|
Nehmen wir zum Beispiel diese Funktion:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
|
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
|
||||||
|
|
||||||
Der Parameter `name` ist definiert als `Optional[str]`, aber er ist **nicht optional**, Sie können die Funktion nicht ohne diesen Parameter aufrufen:
|
Der Parameter `name` ist definiert als `Optional[str]`, aber er ist **nicht optional**, Sie können die Funktion nicht ohne diesen Parameter aufrufen:
|
||||||
|
|
||||||
@@ -390,13 +330,13 @@ Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern u
|
|||||||
* `set`
|
* `set`
|
||||||
* `dict`
|
* `dict`
|
||||||
|
|
||||||
Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
Und ebenso wie bei früheren Python-Versionen, aus dem `typing`-Modul:
|
||||||
|
|
||||||
* `Union`
|
* `Union`
|
||||||
* `Optional` (so wie unter Python 3.8)
|
* `Optional`
|
||||||
* ... und andere.
|
* ... und andere.
|
||||||
|
|
||||||
In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den <abbr title='Allgemein: „oder“. In anderem Zusammenhang auch „Bitweises ODER“, aber letztere Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher.
|
In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den <abbr title='auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher.
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
@@ -409,7 +349,7 @@ Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern u
|
|||||||
* `set`
|
* `set`
|
||||||
* `dict`
|
* `dict`
|
||||||
|
|
||||||
Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
Und Generics aus dem `typing`-Modul:
|
||||||
|
|
||||||
* `Union`
|
* `Union`
|
||||||
* `Optional`
|
* `Optional`
|
||||||
@@ -417,29 +357,17 @@ Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
* `List`
|
|
||||||
* `Tuple`
|
|
||||||
* `Set`
|
|
||||||
* `Dict`
|
|
||||||
* `Union`
|
|
||||||
* `Optional`
|
|
||||||
* ... und andere.
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
### Klassen als Typen { #classes-as-types }
|
### Klassen als Typen { #classes-as-types }
|
||||||
|
|
||||||
Sie können auch eine Klasse als Typ einer Variablen deklarieren.
|
Sie können auch eine Klasse als Typ einer Variablen deklarieren.
|
||||||
|
|
||||||
Nehmen wir an, Sie haben eine Klasse `Person`, mit einem Namen:
|
Nehmen wir an, Sie haben eine Klasse `Person`, mit einem Namen:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
|
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
|
||||||
|
|
||||||
Dann können Sie eine Variable vom Typ `Person` deklarieren:
|
Dann können Sie eine Variable vom Typ `Person` deklarieren:
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial010.py hl[6] *}
|
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
|
||||||
|
|
||||||
Und wiederum bekommen Sie die volle Editor-Unterstützung:
|
Und wiederum bekommen Sie die volle Editor-Unterstützung:
|
||||||
|
|
||||||
@@ -463,29 +391,7 @@ Und Sie erhalten volle Editor-Unterstützung für dieses Objekt.
|
|||||||
|
|
||||||
Ein Beispiel aus der offiziellen Pydantic Dokumentation:
|
Ein Beispiel aus der offiziellen Pydantic Dokumentation:
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
{* ../../docs_src/python_types/tutorial011_py310.py *}
|
||||||
|
|
||||||
```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 | Info
|
/// info | Info
|
||||||
|
|
||||||
@@ -507,27 +413,9 @@ Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None
|
|||||||
|
|
||||||
Python bietet auch die Möglichkeit, **zusätzliche <abbr title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</abbr>** in Typhinweisen unterzubringen, mittels `Annotated`.
|
Python bietet auch die Möglichkeit, **zusätzliche <abbr title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</abbr>** in Typhinweisen unterzubringen, mittels `Annotated`.
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
Seit Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren.
|
||||||
|
|
||||||
In Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren.
|
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
|
||||||
{!> ../../docs_src/python_types/tutorial013_py39.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
In Versionen niedriger als Python 3.9 importieren Sie `Annotated` von `typing_extensions`.
|
|
||||||
|
|
||||||
Es wird bereits mit **FastAPI** installiert sein.
|
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
|
||||||
{!> ../../docs_src/python_types/tutorial013.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.
|
Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Ressourcen { #resources }
|
# Ressourcen { #resources }
|
||||||
|
|
||||||
Zusätzliche Ressourcen, externe Links, Artikel und mehr. ✈️
|
Zusätzliche Ressourcen, externe Links und mehr. ✈️
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Hierzu zählen beispielsweise:
|
|||||||
|
|
||||||
Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`:
|
Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`:
|
||||||
|
|
||||||
{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
|
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
|
||||||
|
|
||||||
**FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter.
|
**FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter.
|
||||||
|
|
||||||
@@ -31,13 +31,13 @@ In diesem Fall schreibt die Taskfunktion in eine Datei (den Versand einer E-Mail
|
|||||||
|
|
||||||
Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir die Funktion mit normalem `def`:
|
Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir die Funktion mit normalem `def`:
|
||||||
|
|
||||||
{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
|
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
|
||||||
|
|
||||||
## Den Hintergrundtask hinzufügen { #add-the-background-task }
|
## Den Hintergrundtask hinzufügen { #add-the-background-task }
|
||||||
|
|
||||||
Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt:
|
Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt:
|
||||||
|
|
||||||
{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
|
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
|
||||||
|
|
||||||
`.add_task()` erhält als Argumente:
|
`.add_task()` erhält als Argumente:
|
||||||
|
|
||||||
|
|||||||
@@ -85,9 +85,7 @@ Sie können die *Pfadoperationen* für dieses Modul mit `APIRouter` erstellen.
|
|||||||
|
|
||||||
Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie mit der Klasse `FastAPI`:
|
Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie mit der Klasse `FastAPI`:
|
||||||
|
|
||||||
```Python hl_lines="1 3" title="app/routers/users.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/users.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
### *Pfadoperationen* mit `APIRouter` { #path-operations-with-apirouter }
|
### *Pfadoperationen* mit `APIRouter` { #path-operations-with-apirouter }
|
||||||
|
|
||||||
@@ -95,9 +93,7 @@ Und dann verwenden Sie ihn, um Ihre *Pfadoperationen* zu deklarieren.
|
|||||||
|
|
||||||
Verwenden Sie ihn auf die gleiche Weise wie die Klasse `FastAPI`:
|
Verwenden Sie ihn auf die gleiche Weise wie die Klasse `FastAPI`:
|
||||||
|
|
||||||
```Python hl_lines="6 11 16" title="app/routers/users.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/users.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Sie können sich `APIRouter` als eine „Mini-`FastAPI`“-Klasse vorstellen.
|
Sie können sich `APIRouter` als eine „Mini-`FastAPI`“-Klasse vorstellen.
|
||||||
|
|
||||||
@@ -121,35 +117,7 @@ Also fügen wir sie in ihr eigenes `dependencies`-Modul (`app/dependencies.py`)
|
|||||||
|
|
||||||
Wir werden nun eine einfache Abhängigkeit verwenden, um einen benutzerdefinierten `X-Token`-Header zu lesen:
|
Wir werden nun eine einfache Abhängigkeit verwenden, um einen benutzerdefinierten `X-Token`-Header zu lesen:
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
|
||||||
|
|
||||||
```Python hl_lines="3 6-8" title="app/dependencies.py"
|
|
||||||
{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
```Python hl_lines="1 5-7" title="app/dependencies.py"
|
|
||||||
{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
|
||||||
|
|
||||||
/// tip | Tipp
|
|
||||||
|
|
||||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
```Python hl_lines="1 4-6" title="app/dependencies.py"
|
|
||||||
{!> ../../docs_src/bigger_applications/app/dependencies.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -181,9 +149,7 @@ Wir wissen, dass alle *Pfadoperationen* in diesem Modul folgendes haben:
|
|||||||
|
|
||||||
Anstatt also alles zu jeder *Pfadoperation* hinzuzufügen, können wir es dem `APIRouter` hinzufügen.
|
Anstatt also alles zu jeder *Pfadoperation* hinzuzufügen, können wir es dem `APIRouter` hinzufügen.
|
||||||
|
|
||||||
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Da der Pfad jeder *Pfadoperation* mit `/` beginnen muss, wie in:
|
Da der Pfad jeder *Pfadoperation* mit `/` beginnen muss, wie in:
|
||||||
|
|
||||||
@@ -242,9 +208,7 @@ Und wir müssen die Abhängigkeitsfunktion aus dem Modul `app.dependencies` impo
|
|||||||
|
|
||||||
Daher verwenden wir einen relativen Import mit `..` für die Abhängigkeiten:
|
Daher verwenden wir einen relativen Import mit `..` für die Abhängigkeiten:
|
||||||
|
|
||||||
```Python hl_lines="3" title="app/routers/items.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Wie relative Importe funktionieren { #how-relative-imports-work }
|
#### Wie relative Importe funktionieren { #how-relative-imports-work }
|
||||||
|
|
||||||
@@ -315,9 +279,7 @@ Wir fügen weder das Präfix `/items` noch `tags=["items"]` zu jeder *Pfadoperat
|
|||||||
|
|
||||||
Aber wir können immer noch _mehr_ `tags` hinzufügen, die auf eine bestimmte *Pfadoperation* angewendet werden, sowie einige zusätzliche `responses`, die speziell für diese *Pfadoperation* gelten:
|
Aber wir können immer noch _mehr_ `tags` hinzufügen, die auf eine bestimmte *Pfadoperation* angewendet werden, sowie einige zusätzliche `responses`, die speziell für diese *Pfadoperation* gelten:
|
||||||
|
|
||||||
```Python hl_lines="30-31" title="app/routers/items.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -343,17 +305,13 @@ Sie importieren und erstellen wie gewohnt eine `FastAPI`-Klasse.
|
|||||||
|
|
||||||
Und wir können sogar [globale Abhängigkeiten](dependencies/global-dependencies.md){.internal-link target=_blank} deklarieren, die mit den Abhängigkeiten für jeden `APIRouter` kombiniert werden:
|
Und wir können sogar [globale Abhängigkeiten](dependencies/global-dependencies.md){.internal-link target=_blank} deklarieren, die mit den Abhängigkeiten für jeden `APIRouter` kombiniert werden:
|
||||||
|
|
||||||
```Python hl_lines="1 3 7" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Den `APIRouter` importieren { #import-the-apirouter }
|
### Den `APIRouter` importieren { #import-the-apirouter }
|
||||||
|
|
||||||
Jetzt importieren wir die anderen Submodule, die `APIRouter` haben:
|
Jetzt importieren wir die anderen Submodule, die `APIRouter` haben:
|
||||||
|
|
||||||
```Python hl_lines="4-5" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Da es sich bei den Dateien `app/routers/users.py` und `app/routers/items.py` um Submodule handelt, die Teil desselben Python-Packages `app` sind, können wir einen einzelnen Punkt `.` verwenden, um sie mit „relativen Imports“ zu importieren.
|
Da es sich bei den Dateien `app/routers/users.py` und `app/routers/items.py` um Submodule handelt, die Teil desselben Python-Packages `app` sind, können wir einen einzelnen Punkt `.` verwenden, um sie mit „relativen Imports“ zu importieren.
|
||||||
|
|
||||||
@@ -416,17 +374,13 @@ würde der `router` von `users` den von `items` überschreiben und wir könnten
|
|||||||
|
|
||||||
Um also beide in derselben Datei verwenden zu können, importieren wir die Submodule direkt:
|
Um also beide in derselben Datei verwenden zu können, importieren wir die Submodule direkt:
|
||||||
|
|
||||||
```Python hl_lines="5" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Die `APIRouter` für `users` und `items` inkludieren { #include-the-apirouters-for-users-and-items }
|
### Die `APIRouter` für `users` und `items` inkludieren { #include-the-apirouters-for-users-and-items }
|
||||||
|
|
||||||
Inkludieren wir nun die `router` aus diesen Submodulen `users` und `items`:
|
Inkludieren wir nun die `router` aus diesen Submodulen `users` und `items`:
|
||||||
|
|
||||||
```Python hl_lines="10-11" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
@@ -466,17 +420,13 @@ Sie enthält einen `APIRouter` mit einigen administrativen *Pfadoperationen*, di
|
|||||||
|
|
||||||
In diesem Beispiel wird es ganz einfach sein. Nehmen wir jedoch an, dass wir, da sie mit anderen Projekten in der Organisation geteilt wird, sie nicht ändern und kein `prefix`, `dependencies`, `tags`, usw. direkt zum `APIRouter` hinzufügen können:
|
In diesem Beispiel wird es ganz einfach sein. Nehmen wir jedoch an, dass wir, da sie mit anderen Projekten in der Organisation geteilt wird, sie nicht ändern und kein `prefix`, `dependencies`, `tags`, usw. direkt zum `APIRouter` hinzufügen können:
|
||||||
|
|
||||||
```Python hl_lines="3" title="app/internal/admin.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/internal/admin.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Aber wir möchten immer noch ein benutzerdefiniertes `prefix` festlegen, wenn wir den `APIRouter` einbinden, sodass alle seine *Pfadoperationen* mit `/admin` beginnen, wir möchten es mit den `dependencies` sichern, die wir bereits für dieses Projekt haben, und wir möchten `tags` und `responses` hinzufügen.
|
Aber wir möchten immer noch ein benutzerdefiniertes `prefix` festlegen, wenn wir den `APIRouter` einbinden, sodass alle seine *Pfadoperationen* mit `/admin` beginnen, wir möchten es mit den `dependencies` sichern, die wir bereits für dieses Projekt haben, und wir möchten `tags` und `responses` hinzufügen.
|
||||||
|
|
||||||
Wir können das alles deklarieren, ohne den ursprünglichen `APIRouter` ändern zu müssen, indem wir diese Parameter an `app.include_router()` übergeben:
|
Wir können das alles deklarieren, ohne den ursprünglichen `APIRouter` ändern zu müssen, indem wir diese Parameter an `app.include_router()` übergeben:
|
||||||
|
|
||||||
```Python hl_lines="14-17" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Auf diese Weise bleibt der ursprüngliche `APIRouter` unverändert, sodass wir dieselbe `app/internal/admin.py`-Datei weiterhin mit anderen Projekten in der Organisation teilen können.
|
Auf diese Weise bleibt der ursprüngliche `APIRouter` unverändert, sodass wir dieselbe `app/internal/admin.py`-Datei weiterhin mit anderen Projekten in der Organisation teilen können.
|
||||||
|
|
||||||
@@ -497,9 +447,7 @@ Wir können *Pfadoperationen* auch direkt zur `FastAPI`-App hinzufügen.
|
|||||||
|
|
||||||
Hier machen wir es ... nur um zu zeigen, dass wir es können 🤷:
|
Hier machen wir es ... nur um zu zeigen, dass wir es können 🤷:
|
||||||
|
|
||||||
```Python hl_lines="21-23" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
und es wird korrekt funktionieren, zusammen mit allen anderen *Pfadoperationen*, die mit `app.include_router()` hinzugefügt wurden.
|
und es wird korrekt funktionieren, zusammen mit allen anderen *Pfadoperationen*, die mit `app.include_router()` hinzugefügt wurden.
|
||||||
|
|
||||||
|
|||||||
@@ -14,35 +14,14 @@ Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts über den Typ der
|
|||||||
|
|
||||||
Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren.
|
Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren.
|
||||||
|
|
||||||
### `List` von `typing` importieren { #import-typings-list }
|
|
||||||
|
|
||||||
In Python 3.9 oder darüber können Sie einfach `list` verwenden, um diese Typannotationen zu deklarieren, wie wir unten sehen werden. 💡
|
|
||||||
|
|
||||||
In Python-Versionen vor 3.9 (3.6 und darüber), müssen Sie zuerst `List` von Pythons Standardmodul `typing` importieren.
|
|
||||||
|
|
||||||
{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
|
|
||||||
|
|
||||||
### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter }
|
### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter }
|
||||||
|
|
||||||
Um Typen wie `list`, `dict`, `tuple` mit inneren Typ-Parametern (inneren Typen) zu deklarieren:
|
Um Typen zu deklarieren, die Typ-Parameter (innere Typen) haben, wie `list`, `dict`, `tuple`, übergeben Sie den/die inneren Typ(en) als „Typ-Parameter“ in eckigen Klammern: `[` und `]`
|
||||||
|
|
||||||
* Wenn Sie eine Python-Version kleiner als 3.9 verwenden, importieren Sie das Äquivalent zum entsprechenden Typ vom `typing`-Modul
|
|
||||||
* Überreichen Sie den/die inneren Typ(en) von eckigen Klammern umschlossen, `[` und `]`, als „Typ-Parameter“
|
|
||||||
|
|
||||||
In Python 3.9 wäre das:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
my_list: list[str]
|
my_list: list[str]
|
||||||
```
|
```
|
||||||
|
|
||||||
Und in Python-Versionen vor 3.9:
|
|
||||||
|
|
||||||
```Python
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
my_list: List[str]
|
|
||||||
```
|
|
||||||
|
|
||||||
Das ist alles Standard-Python-Syntax für Typdeklarationen.
|
Das ist alles Standard-Python-Syntax für Typdeklarationen.
|
||||||
|
|
||||||
Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen.
|
Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen.
|
||||||
@@ -178,12 +157,6 @@ Beachten Sie, wie `Offer` eine Liste von `Item`s hat, die ihrerseits eine option
|
|||||||
|
|
||||||
Wenn das äußerste Element des JSON-Bodys, das Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, können Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen:
|
Wenn das äußerste Element des JSON-Bodys, das Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, können Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen:
|
||||||
|
|
||||||
```Python
|
|
||||||
images: List[Image]
|
|
||||||
```
|
|
||||||
|
|
||||||
oder in Python 3.9 und darüber:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
images: list[Image]
|
images: list[Image]
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -50,14 +50,6 @@ Wenn Sie Teil-Aktualisierungen entgegennehmen, ist der `exclude_unset`-Parameter
|
|||||||
|
|
||||||
Wie in `item.model_dump(exclude_unset=True)`.
|
Wie in `item.model_dump(exclude_unset=True)`.
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_dump()` umbenannt.
|
|
||||||
|
|
||||||
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
Das wird ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> erstellen, mit nur den Daten, die gesetzt wurden, als das `item`-Modell erstellt wurde, Defaultwerte ausgeschlossen.
|
Das wird ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> erstellen, mit nur den Daten, die gesetzt wurden, als das `item`-Modell erstellt wurde, Defaultwerte ausgeschlossen.
|
||||||
|
|
||||||
Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>) gesendeten Daten enthält, ohne Defaultwerte:
|
Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>) gesendeten Daten enthält, ohne Defaultwerte:
|
||||||
@@ -68,14 +60,6 @@ Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr tit
|
|||||||
|
|
||||||
Jetzt können Sie eine Kopie des existierenden Modells mittels `.model_copy()` erstellen, wobei Sie dem `update`-Parameter ein `dict` mit den zu ändernden Daten übergeben.
|
Jetzt können Sie eine Kopie des existierenden Modells mittels `.model_copy()` erstellen, wobei Sie dem `update`-Parameter ein `dict` mit den zu ändernden Daten übergeben.
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic v1 hieß diese Methode `.copy()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_copy()` umbenannt.
|
|
||||||
|
|
||||||
Die Beispiele hier verwenden `.copy()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_copy()` verwenden, wenn Sie Pydantic v2 verwenden können.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
Wie in `stored_item_model.model_copy(update=update_data)`:
|
Wie in `stored_item_model.model_copy(update=update_data)`:
|
||||||
|
|
||||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
||||||
|
|||||||
@@ -127,14 +127,6 @@ Innerhalb der Funktion können Sie alle Attribute des Modellobjekts direkt verwe
|
|||||||
|
|
||||||
{* ../../docs_src/body/tutorial002_py310.py *}
|
{* ../../docs_src/body/tutorial002_py310.py *}
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic v1 hieß die Methode `.dict()`, sie wurde in Pydantic v2 deprecatet (aber weiterhin unterstützt) und in `.model_dump()` umbenannt.
|
|
||||||
|
|
||||||
Die Beispiele hier verwenden `.dict()` zur Kompatibilität mit Pydantic v1, aber Sie sollten stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 nutzen können.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
## Requestbody- + Pfad-Parameter { #request-body-path-parameters }
|
## Requestbody- + Pfad-Parameter { #request-body-path-parameters }
|
||||||
|
|
||||||
Sie können Pfad-Parameter und den Requestbody gleichzeitig deklarieren.
|
Sie können Pfad-Parameter und den Requestbody gleichzeitig deklarieren.
|
||||||
@@ -162,7 +154,7 @@ Die Funktionsparameter werden wie folgt erkannt:
|
|||||||
|
|
||||||
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`.
|
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`.
|
||||||
|
|
||||||
Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.8+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
|
Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.9+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
|
||||||
|
|
||||||
Das Hinzufügen der Typannotationen ermöglicht jedoch Ihrem Editor, Ihnen eine bessere Unterstützung zu bieten und Fehler zu erkennen.
|
Das Hinzufügen der Typannotationen ermöglicht jedoch Ihrem Editor, Ihnen eine bessere Unterstützung zu bieten und Fehler zu erkennen.
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Ihre API hat jetzt die Macht, ihre eigene <abbr title="Das ist ein Scherz, nur f
|
|||||||
|
|
||||||
Sie können die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu verbieten (`forbid`):
|
Sie können die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu verbieten (`forbid`):
|
||||||
|
|
||||||
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
|
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
|
||||||
|
|
||||||
Wenn ein Client versucht, einige **zusätzliche Cookies** zu senden, erhält er eine **Error-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**.
|
Wenn ein Client versucht, einige **zusätzliche Cookies** zu senden, erhält er eine **Error-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**.
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ Sie können auch angeben, ob Ihr Backend erlaubt:
|
|||||||
* Bestimmte HTTP-Methoden (`POST`, `PUT`) oder alle mit der Wildcard `"*"`.
|
* Bestimmte HTTP-Methoden (`POST`, `PUT`) oder alle mit der Wildcard `"*"`.
|
||||||
* Bestimmte HTTP-Header oder alle mit der Wildcard `"*"`.
|
* Bestimmte HTTP-Header oder alle mit der Wildcard `"*"`.
|
||||||
|
|
||||||
{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
|
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
|
||||||
|
|
||||||
Die von der `CORSMiddleware`-Implementierung verwendeten Defaultparameter sind standardmäßig restriktiv, daher müssen Sie bestimmte Origins, Methoden oder Header ausdrücklich aktivieren, damit Browser sie in einem Cross-Domain-Kontext verwenden dürfen.
|
Die von der `CORSMiddleware`-Implementierung verwendeten Defaultparameter sind standardmäßig restriktiv, daher müssen Sie bestimmte Origins, Methoden oder Header ausdrücklich aktivieren, damit Browser sie in einem Cross-Domain-Kontext verwenden dürfen.
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Sie können den Debugger in Ihrem Editor verbinden, zum Beispiel mit Visual Stud
|
|||||||
|
|
||||||
Importieren und führen Sie `uvicorn` direkt in Ihrer FastAPI-Anwendung aus:
|
Importieren und führen Sie `uvicorn` direkt in Ihrer FastAPI-Anwendung aus:
|
||||||
|
|
||||||
{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
|
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
|
||||||
|
|
||||||
### Über `__name__ == "__main__"` { #about-name-main }
|
### Über `__name__ == "__main__"` { #about-name-main }
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ Jetzt können Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren.
|
|||||||
|
|
||||||
Beachten Sie, wie wir `CommonQueryParams` im obigen Code zweimal schreiben:
|
Beachten Sie, wie wir `CommonQueryParams` im obigen Code zweimal schreiben:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||||
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ Aus diesem extrahiert FastAPI die deklarierten Parameter, und dieses ist es, was
|
|||||||
|
|
||||||
In diesem Fall hat das erste `CommonQueryParams` in:
|
In diesem Fall hat das erste `CommonQueryParams` in:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[CommonQueryParams, ...
|
commons: Annotated[CommonQueryParams, ...
|
||||||
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
|
|||||||
|
|
||||||
Sie könnten tatsächlich einfach schreiben:
|
Sie könnten tatsächlich einfach schreiben:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[Any, Depends(CommonQueryParams)]
|
commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||||
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ Es wird jedoch empfohlen, den Typ zu deklarieren, da Ihr Editor so weiß, was al
|
|||||||
|
|
||||||
Aber Sie sehen, dass wir hier etwas Codeduplizierung haben, indem wir `CommonQueryParams` zweimal schreiben:
|
Aber Sie sehen, dass wir hier etwas Codeduplizierung haben, indem wir `CommonQueryParams` zweimal schreiben:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||||
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ In diesem speziellen Fall können Sie Folgendes tun:
|
|||||||
|
|
||||||
Anstatt zu schreiben:
|
Anstatt zu schreiben:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||||
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
|
|||||||
|
|
||||||
... schreiben Sie:
|
... schreiben Sie:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[CommonQueryParams, Depends()]
|
commons: Annotated[CommonQueryParams, Depends()]
|
||||||
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8 nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -29,15 +29,15 @@ Sie könnten damit beispielsweise eine Datenbanksession erstellen und diese nach
|
|||||||
|
|
||||||
Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgeführt, bevor eine <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> erzeugt wird:
|
Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgeführt, bevor eine <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> erzeugt wird:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
|
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
|
||||||
|
|
||||||
Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeiten eingefügt wird:
|
Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeiten eingefügt wird:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
|
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
|
||||||
|
|
||||||
Der auf die `yield`-Anweisung folgende Code wird nach der Response ausgeführt:
|
Der auf die `yield`-Anweisung folgende Code wird nach der Response ausgeführt:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
|
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ Sie können also mit `except SomeException` diese bestimmte Exception innerhalb
|
|||||||
|
|
||||||
Auf die gleiche Weise können Sie `finally` verwenden, um sicherzustellen, dass die Exit-Schritte ausgeführt werden, unabhängig davon, ob eine Exception geworfen wurde oder nicht.
|
Auf die gleiche Weise können Sie `finally` verwenden, um sicherzustellen, dass die Exit-Schritte ausgeführt werden, unabhängig davon, ob eine Exception geworfen wurde oder nicht.
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
|
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
|
||||||
|
|
||||||
## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
|
## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ In Python können Sie Kontextmanager erstellen, indem Sie <a href="https://docs.
|
|||||||
|
|
||||||
Sie können solche auch innerhalb von **FastAPI**-Abhängigkeiten mit `yield` verwenden, indem Sie `with`- oder `async with`-Anweisungen innerhalb der Abhängigkeits-Funktion verwenden:
|
Sie können solche auch innerhalb von **FastAPI**-Abhängigkeiten mit `yield` verwenden, indem Sie `with`- oder `async with`-Anweisungen innerhalb der Abhängigkeits-Funktion verwenden:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
|
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Bei einigen Anwendungstypen möchten Sie möglicherweise Abhängigkeiten zur ges
|
|||||||
|
|
||||||
In diesem Fall werden sie auf alle *Pfadoperationen* in der Anwendung angewendet:
|
In diesem Fall werden sie auf alle *Pfadoperationen* in der Anwendung angewendet:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
|
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
|
||||||
|
|
||||||
Und alle Ideen aus dem Abschnitt über das [Hinzufügen von `dependencies` zu den *Pfadoperation-Dekoratoren*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} gelten weiterhin, aber in diesem Fall für alle *Pfadoperationen* in der App.
|
Und alle Ideen aus dem Abschnitt über das [Hinzufügen von `dependencies` zu den *Pfadoperation-Dekoratoren*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} gelten weiterhin, aber in diesem Fall für alle *Pfadoperationen* in der App.
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Und es speichert den zurückgegebenen Wert in einem <abbr title="Mechanismus, de
|
|||||||
|
|
||||||
In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (möglicherweise mehrmals) in demselben Request aufgerufen werden muss, anstatt den zwischengespeicherten Wert zu verwenden, können Sie den Parameter `use_cache=False` festlegen, wenn Sie `Depends` verwenden:
|
In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (möglicherweise mehrmals) in demselben Request aufgerufen werden muss, anstatt den zwischengespeicherten Wert zu verwenden, können Sie den Parameter `use_cache=False` festlegen, wenn Sie `Depends` verwenden:
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python hl_lines="1"
|
```Python hl_lines="1"
|
||||||
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
|
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
|
||||||
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.9+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -22,21 +22,13 @@ Hier ist eine allgemeine Idee, wie die Modelle mit ihren Passwortfeldern aussehe
|
|||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
||||||
|
|
||||||
/// info | Info
|
### Über `**user_in.model_dump()` { #about-user-in-model-dump }
|
||||||
|
|
||||||
In Pydantic v1 hieß die Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber weiterhin unterstützt) und in `.model_dump()` umbenannt.
|
#### Pydantics `.model_dump()` { #pydantics-model-dump }
|
||||||
|
|
||||||
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, aber Sie sollten `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
### Über `**user_in.dict()` { #about-user-in-dict }
|
|
||||||
|
|
||||||
#### Die `.dict()`-Methode von Pydantic { #pydantics-dict }
|
|
||||||
|
|
||||||
`user_in` ist ein Pydantic-Modell der Klasse `UserIn`.
|
`user_in` ist ein Pydantic-Modell der Klasse `UserIn`.
|
||||||
|
|
||||||
Pydantic-Modelle haben eine `.dict()`-Methode, die ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> mit den Daten des Modells zurückgibt.
|
Pydantic-Modelle haben eine `.model_dump()`-Methode, die ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> mit den Daten des Modells zurückgibt.
|
||||||
|
|
||||||
Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so:
|
Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so:
|
||||||
|
|
||||||
@@ -47,7 +39,7 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
|
|||||||
und dann aufrufen:
|
und dann aufrufen:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
user_dict = user_in.dict()
|
user_dict = user_in.model_dump()
|
||||||
```
|
```
|
||||||
|
|
||||||
haben wir jetzt ein `dict` mit den Daten in der Variablen `user_dict` (es ist ein `dict` statt eines Pydantic-Modellobjekts).
|
haben wir jetzt ein `dict` mit den Daten in der Variablen `user_dict` (es ist ein `dict` statt eines Pydantic-Modellobjekts).
|
||||||
@@ -103,20 +95,20 @@ UserInDB(
|
|||||||
|
|
||||||
#### Ein Pydantic-Modell aus dem Inhalt eines anderen { #a-pydantic-model-from-the-contents-of-another }
|
#### Ein Pydantic-Modell aus dem Inhalt eines anderen { #a-pydantic-model-from-the-contents-of-another }
|
||||||
|
|
||||||
Da wir im obigen Beispiel `user_dict` von `user_in.dict()` bekommen haben, wäre dieser Code:
|
Da wir im obigen Beispiel `user_dict` von `user_in.model_dump()` bekommen haben, wäre dieser Code:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
user_dict = user_in.dict()
|
user_dict = user_in.model_dump()
|
||||||
UserInDB(**user_dict)
|
UserInDB(**user_dict)
|
||||||
```
|
```
|
||||||
|
|
||||||
gleichwertig zu:
|
gleichwertig zu:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(**user_in.dict())
|
UserInDB(**user_in.model_dump())
|
||||||
```
|
```
|
||||||
|
|
||||||
... weil `user_in.dict()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` übergeben.
|
... weil `user_in.model_dump()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` übergeben.
|
||||||
|
|
||||||
Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells.
|
Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells.
|
||||||
|
|
||||||
@@ -125,7 +117,7 @@ Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pyd
|
|||||||
Und dann fügen wir das zusätzliche Schlüsselwort-Argument `hashed_password=hashed_password` hinzu, wie in:
|
Und dann fügen wir das zusätzliche Schlüsselwort-Argument `hashed_password=hashed_password` hinzu, wie in:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
UserInDB(**user_in.dict(), hashed_password=hashed_password)
|
UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
|
||||||
```
|
```
|
||||||
|
|
||||||
... was so ist wie:
|
... was so ist wie:
|
||||||
@@ -180,7 +172,6 @@ Wenn Sie eine <a href="https://docs.pydantic.dev/latest/concepts/types/#unions"
|
|||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
|
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
|
||||||
|
|
||||||
|
|
||||||
### `Union` in Python 3.10 { #union-in-python-3-10 }
|
### `Union` in Python 3.10 { #union-in-python-3-10 }
|
||||||
|
|
||||||
In diesem Beispiel übergeben wir `Union[PlaneItem, CarItem]` als Wert des Arguments `response_model`.
|
In diesem Beispiel übergeben wir `Union[PlaneItem, CarItem]` als Wert des Arguments `response_model`.
|
||||||
@@ -203,7 +194,6 @@ Dafür verwenden Sie Pythons Standard-`typing.List` (oder nur `list` in Python 3
|
|||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
|
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
|
||||||
|
|
||||||
|
|
||||||
## Response mit beliebigem `dict` { #response-with-arbitrary-dict }
|
## Response mit beliebigem `dict` { #response-with-arbitrary-dict }
|
||||||
|
|
||||||
Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgibt, indem Sie nur die Typen der Schlüssel und Werte ohne ein Pydantic-Modell deklarieren.
|
Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgibt, indem Sie nur die Typen der Schlüssel und Werte ohne ein Pydantic-Modell deklarieren.
|
||||||
@@ -214,7 +204,6 @@ In diesem Fall können Sie `typing.Dict` verwenden (oder nur `dict` in Python 3.
|
|||||||
|
|
||||||
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
|
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
|
||||||
|
|
||||||
|
|
||||||
## Zusammenfassung { #recap }
|
## Zusammenfassung { #recap }
|
||||||
|
|
||||||
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf.
|
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Die einfachste FastAPI-Datei könnte wie folgt aussehen:
|
Die einfachste FastAPI-Datei könnte wie folgt aussehen:
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py *}
|
||||||
|
|
||||||
Kopieren Sie das in eine Datei `main.py`.
|
Kopieren Sie das in eine Datei `main.py`.
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ Das war's! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
|
|||||||
|
|
||||||
### Schritt 1: `FastAPI` importieren { #step-1-import-fastapi }
|
### Schritt 1: `FastAPI` importieren { #step-1-import-fastapi }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
|
||||||
|
|
||||||
`FastAPI` ist eine Python-Klasse, die die gesamte Funktionalität für Ihre API bereitstellt.
|
`FastAPI` ist eine Python-Klasse, die die gesamte Funktionalität für Ihre API bereitstellt.
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ Sie können alle <a href="https://www.starlette.dev/" class="external-link" targ
|
|||||||
|
|
||||||
### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ { #step-2-create-a-fastapi-instance }
|
### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ { #step-2-create-a-fastapi-instance }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
|
||||||
|
|
||||||
In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI`.
|
In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI`.
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ Wir werden sie auch „**Operationen**“ nennen.
|
|||||||
|
|
||||||
#### Definieren eines *Pfadoperation-Dekorators* { #define-a-path-operation-decorator }
|
#### Definieren eines *Pfadoperation-Dekorators* { #define-a-path-operation-decorator }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die Bearbeitung von <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zuständig ist, die an:
|
Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die Bearbeitung von <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zuständig ist, die an:
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ Das ist unsere „**Pfadoperation-Funktion**“:
|
|||||||
* **Operation**: ist `get`.
|
* **Operation**: ist `get`.
|
||||||
* **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`).
|
* **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`).
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
|
||||||
|
|
||||||
Dies ist eine Python-Funktion.
|
Dies ist eine Python-Funktion.
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ In diesem Fall handelt es sich um eine `async`-Funktion.
|
|||||||
|
|
||||||
Sie könnten sie auch als normale Funktion anstelle von `async def` definieren:
|
Sie könnten sie auch als normale Funktion anstelle von `async def` definieren:
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
|
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
@@ -342,7 +342,7 @@ Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../as
|
|||||||
|
|
||||||
### Schritt 5: den Inhalt zurückgeben { #step-5-return-the-content }
|
### Schritt 5: den Inhalt zurückgeben { #step-5-return-the-content }
|
||||||
|
|
||||||
{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
|
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
|
||||||
|
|
||||||
Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben.
|
Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben.
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Um HTTP-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden
|
|||||||
|
|
||||||
### `HTTPException` importieren { #import-httpexception }
|
### `HTTPException` importieren { #import-httpexception }
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
|
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
|
||||||
|
|
||||||
### Eine `HTTPException` in Ihrem Code auslösen { #raise-an-httpexception-in-your-code }
|
### Eine `HTTPException` in Ihrem Code auslösen { #raise-an-httpexception-in-your-code }
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ Der Vorteil des Auslösens einer Exception gegenüber dem Zurückgeben eines Wer
|
|||||||
|
|
||||||
In diesem Beispiel lösen wir eine Exception mit einem Statuscode von `404` aus, wenn der Client einen Artikel mit einer nicht existierenden ID anfordert:
|
In diesem Beispiel lösen wir eine Exception mit einem Statuscode von `404` aus, wenn der Client einen Artikel mit einer nicht existierenden ID anfordert:
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
|
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
|
||||||
|
|
||||||
### Die resultierende Response { #the-resulting-response }
|
### Die resultierende Response { #the-resulting-response }
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ Sie werden es wahrscheinlich nicht direkt in Ihrem Code verwenden müssen.
|
|||||||
|
|
||||||
Aber falls Sie es für ein fortgeschrittenes Szenario benötigen, können Sie benutzerdefinierte Header hinzufügen:
|
Aber falls Sie es für ein fortgeschrittenes Szenario benötigen, können Sie benutzerdefinierte Header hinzufügen:
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
|
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
|
||||||
|
|
||||||
## Benutzerdefinierte Exceptionhandler installieren { #install-custom-exception-handlers }
|
## Benutzerdefinierte Exceptionhandler installieren { #install-custom-exception-handlers }
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ Und Sie möchten diese Exception global mit FastAPI handhaben.
|
|||||||
|
|
||||||
Sie könnten einen benutzerdefinierten Exceptionhandler mit `@app.exception_handler()` hinzufügen:
|
Sie könnten einen benutzerdefinierten Exceptionhandler mit `@app.exception_handler()` hinzufügen:
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
|
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
|
||||||
|
|
||||||
Hier, wenn Sie `/unicorns/yolo` anfordern, wird die *Pfadoperation* eine `UnicornException` `raise`n.
|
Hier, wenn Sie `/unicorns/yolo` anfordern, wird die *Pfadoperation* eine `UnicornException` `raise`n.
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und ve
|
|||||||
|
|
||||||
Der Exceptionhandler erhält einen `Request` und die Exception.
|
Der Exceptionhandler erhält einen `Request` und die Exception.
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
|
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
|
||||||
|
|
||||||
Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen JSON-Fehlers mit:
|
Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen JSON-Fehlers mit:
|
||||||
|
|
||||||
@@ -149,36 +149,17 @@ Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen
|
|||||||
eine Textversion mit:
|
eine Textversion mit:
|
||||||
|
|
||||||
```
|
```
|
||||||
1 validation error
|
Validation errors:
|
||||||
path -> item_id
|
Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
|
||||||
value is not a valid integer (type=type_error.integer)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `RequestValidationError` vs. `ValidationError` { #requestvalidationerror-vs-validationerror }
|
|
||||||
|
|
||||||
/// warning | Achtung
|
|
||||||
|
|
||||||
Dies sind technische Details, die Sie überspringen können, wenn sie für Sie jetzt nicht wichtig sind.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
`RequestValidationError` ist eine Unterklasse von Pydantics <a href="https://docs.pydantic.dev/latest/concepts/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a>.
|
|
||||||
|
|
||||||
**FastAPI** verwendet diesen so, dass, wenn Sie ein Pydantic-Modell in `response_model` verwenden und Ihre Daten einen Fehler haben, Sie den Fehler in Ihrem Log sehen.
|
|
||||||
|
|
||||||
Aber der Client/Benutzer wird ihn nicht sehen. Stattdessen erhält der Client einen „Internal Server Error“ mit einem HTTP-Statuscode `500`.
|
|
||||||
|
|
||||||
Es sollte so sein, denn wenn Sie einen Pydantic `ValidationError` in Ihrer *Response* oder irgendwo anders in Ihrem Code haben (nicht im *Request* des Clients), ist es tatsächlich ein Fehler in Ihrem Code.
|
|
||||||
|
|
||||||
Und während Sie den Fehler beheben, sollten Ihre Clients/Benutzer keinen Zugriff auf interne Informationen über den Fehler haben, da das eine Sicherheitslücke aufdecken könnte.
|
|
||||||
|
|
||||||
### Überschreiben des `HTTPException`-Fehlerhandlers { #override-the-httpexception-error-handler }
|
### Überschreiben des `HTTPException`-Fehlerhandlers { #override-the-httpexception-error-handler }
|
||||||
|
|
||||||
Auf die gleiche Weise können Sie den `HTTPException`-Handler überschreiben.
|
Auf die gleiche Weise können Sie den `HTTPException`-Handler überschreiben.
|
||||||
|
|
||||||
Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
|
Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
|
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
@@ -188,13 +169,21 @@ Sie könnten auch `from starlette.responses import PlainTextResponse` verwenden.
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
/// warning | Achtung
|
||||||
|
|
||||||
|
Beachten Sie, dass der `RequestValidationError` Informationen über den Dateinamen und die Zeile enthält, in der der Validierungsfehler auftritt, sodass Sie ihn bei Bedarf mit den relevanten Informationen in Ihren Logs anzeigen können.
|
||||||
|
|
||||||
|
Das bedeutet aber auch, dass, wenn Sie ihn einfach in einen String umwandeln und diese Informationen direkt zurückgeben, Sie möglicherweise ein paar Informationen über Ihr System preisgeben. Daher extrahiert und zeigt der Code hier jeden Fehler getrennt.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
### Verwenden des `RequestValidationError`-Bodys { #use-the-requestvalidationerror-body }
|
### Verwenden des `RequestValidationError`-Bodys { #use-the-requestvalidationerror-body }
|
||||||
|
|
||||||
Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen Daten.
|
Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen Daten.
|
||||||
|
|
||||||
Sie könnten diesen während der Entwicklung Ihrer Anwendung verwenden, um den Body zu loggen und zu debuggen, ihn an den Benutzer zurückzugeben usw.
|
Sie könnten diesen während der Entwicklung Ihrer Anwendung verwenden, um den Body zu loggen und zu debuggen, ihn an den Benutzer zurückzugeben usw.
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
|
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
|
||||||
|
|
||||||
Versuchen Sie nun, einen ungültigen Artikel zu senden:
|
Versuchen Sie nun, einen ungültigen Artikel zu senden:
|
||||||
|
|
||||||
@@ -250,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
|||||||
|
|
||||||
Wenn Sie die Exception zusammen mit den gleichen Default-Exceptionhandlern von **FastAPI** verwenden möchten, können Sie die Default-Exceptionhandler aus `fastapi.exception_handlers` importieren und wiederverwenden:
|
Wenn Sie die Exception zusammen mit den gleichen Default-Exceptionhandlern von **FastAPI** verwenden möchten, können Sie die Default-Exceptionhandler aus `fastapi.exception_handlers` importieren und wiederverwenden:
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
|
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
|
||||||
|
|
||||||
In diesem Beispiel geben Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht aus, aber Sie verstehen das Prinzip. Sie können die Exception verwenden und dann einfach die Default-Exceptionhandler wiederverwenden.
|
In diesem Beispiel geben Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht aus, aber Sie verstehen das Prinzip. Sie können die Exception verwenden und dann einfach die Default-Exceptionhandler wiederverwenden.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Sie können die folgenden Felder festlegen, die in der OpenAPI-Spezifikation und
|
|||||||
|
|
||||||
Sie können diese wie folgt setzen:
|
Sie können diese wie folgt setzen:
|
||||||
|
|
||||||
{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
|
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ Seit OpenAPI 3.1.0 und FastAPI 0.99.0 können Sie die `license_info` auch mit ei
|
|||||||
|
|
||||||
Zum Beispiel:
|
Zum Beispiel:
|
||||||
|
|
||||||
{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
|
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
|
||||||
|
|
||||||
## Metadaten für Tags { #metadata-for-tags }
|
## Metadaten für Tags { #metadata-for-tags }
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ Versuchen wir es mit einem Beispiel mit Tags für `users` und `items`.
|
|||||||
|
|
||||||
Erstellen Sie Metadaten für Ihre Tags und übergeben Sie diese an den Parameter `openapi_tags`:
|
Erstellen Sie Metadaten für Ihre Tags und übergeben Sie diese an den Parameter `openapi_tags`:
|
||||||
|
|
||||||
{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
|
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
|
||||||
|
|
||||||
Beachten Sie, dass Sie Markdown innerhalb der Beschreibungen verwenden können. Zum Beispiel wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt.
|
Beachten Sie, dass Sie Markdown innerhalb der Beschreibungen verwenden können. Zum Beispiel wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt.
|
||||||
|
|
||||||
@@ -72,7 +72,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:
|
Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n), um diese verschiedenen Tags zuzuweisen:
|
||||||
|
|
||||||
{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
|
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
|
||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ Sie können das aber mit dem Parameter `openapi_url` konfigurieren.
|
|||||||
|
|
||||||
Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestellt wird:
|
Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestellt wird:
|
||||||
|
|
||||||
{* ../../docs_src/metadata/tutorial002.py hl[3] *}
|
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -117,4 +117,4 @@ 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:
|
Um beispielsweise Swagger UI so einzustellen, dass sie unter `/documentation` bereitgestellt wird, und ReDoc zu deaktivieren:
|
||||||
|
|
||||||
{* ../../docs_src/metadata/tutorial003.py hl[3] *}
|
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Die Middleware-Funktion erhält:
|
|||||||
* Dann gibt es die von der entsprechenden *Pfadoperation* generierte `response` zurück.
|
* 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.
|
* Sie können die `response` dann weiter modifizieren, bevor Sie sie zurückgeben.
|
||||||
|
|
||||||
{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
|
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -57,7 +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:
|
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:
|
||||||
|
|
||||||
{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
|
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
|
|||||||
|
|
||||||
**FastAPI** unterstützt das auf die gleiche Weise wie einfache Strings:
|
**FastAPI** unterstützt das auf die gleiche Weise wie einfache Strings:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
|
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
|
||||||
|
|
||||||
## Zusammenfassung und Beschreibung { #summary-and-description }
|
## Zusammenfassung und Beschreibung { #summary-and-description }
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Daher, wenn Sie keine vergeben, wird **FastAPI** automatisch eine für „Erfolg
|
|||||||
|
|
||||||
Wenn Sie eine *Pfadoperation* als <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
|
Wenn Sie eine *Pfadoperation* als <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
|
||||||
|
|
||||||
{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
|
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
|
||||||
|
|
||||||
Sie wird in der interaktiven Dokumentation gut sichtbar als deprecatet markiert werden:
|
Sie wird in der interaktiven Dokumentation gut sichtbar als deprecatet markiert werden:
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Für **FastAPI** spielt es keine Rolle. Es erkennt die Parameter anhand ihrer Na
|
|||||||
|
|
||||||
Sie können Ihre Funktion also so deklarieren:
|
Sie können Ihre Funktion also so deklarieren:
|
||||||
|
|
||||||
{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
|
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
|
||||||
|
|
||||||
Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da es nicht darauf ankommt, dass Sie keine Funktionsparameter-Defaultwerte für `Query()` oder `Path()` verwenden.
|
Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da es nicht darauf ankommt, dass Sie keine Funktionsparameter-Defaultwerte für `Query()` oder `Path()` verwenden.
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ Wenn Sie:
|
|||||||
|
|
||||||
Python wird nichts mit diesem `*` machen, aber es wird wissen, dass alle folgenden Parameter als Schlüsselwortargumente (Schlüssel-Wert-Paare) verwendet werden sollen, auch bekannt als <abbr title="Von: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Selbst wenn diese keinen Defaultwert haben.
|
Python wird nichts mit diesem `*` machen, aber es wird wissen, dass alle folgenden Parameter als Schlüsselwortargumente (Schlüssel-Wert-Paare) verwendet werden sollen, auch bekannt als <abbr title="Von: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Selbst wenn diese keinen Defaultwert haben.
|
||||||
|
|
||||||
{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
|
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
|
||||||
|
|
||||||
### Besser mit `Annotated` { #better-with-annotated }
|
### Besser mit `Annotated` { #better-with-annotated }
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-<abbr title="Formatstring – Formatierter String: Der String enthält Ausdrücke, die mit geschweiften Klammern umschlossen sind. Solche Stellen werden durch den Wert des Ausdrucks ersetzt">Formatstrings</abbr> verwendet wird:
|
Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-<abbr title="Formatstring – Formatierter String: Der String enthält Ausdrücke, die mit geschweiften Klammern umschlossen sind. Solche Stellen werden durch den Wert des Ausdrucks ersetzt">Formatstrings</abbr> verwendet wird:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
|
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
|
||||||
|
|
||||||
Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
|
Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ Wenn Sie dieses Beispiel ausführen und auf <a href="http://127.0.0.1:8000/items
|
|||||||
|
|
||||||
Sie können den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen:
|
Sie können den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial002.py hl[7] *}
|
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
|
||||||
|
|
||||||
In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl.
|
In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl.
|
||||||
|
|
||||||
@@ -118,13 +118,13 @@ Und Sie haben auch einen Pfad `/users/{user_id}`, um Daten über einen spezifisc
|
|||||||
|
|
||||||
Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad `/users/me` vor `/users/{user_id}` deklariert wurde:
|
Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad `/users/me` vor `/users/{user_id}` deklariert wurde:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
|
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
|
||||||
|
|
||||||
Ansonsten würde der Pfad für `/users/{user_id}` auch `/users/me` auswerten, und annehmen, dass ein Parameter `user_id` mit dem Wert `"me"` übergeben wurde.
|
Ansonsten würde der Pfad für `/users/{user_id}` auch `/users/me` auswerten, und annehmen, dass ein Parameter `user_id` mit dem Wert `"me"` übergeben wurde.
|
||||||
|
|
||||||
Sie können eine Pfadoperation auch nicht erneut definieren:
|
Sie können eine Pfadoperation auch nicht erneut definieren:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
|
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
|
||||||
|
|
||||||
Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst übereinstimmt.
|
Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst übereinstimmt.
|
||||||
|
|
||||||
@@ -140,13 +140,8 @@ Indem Sie von `str` erben, weiß die API-Dokumentation, dass die Werte vom Typ `
|
|||||||
|
|
||||||
Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden:
|
Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerationen (oder Enums)</a> gibt es in Python seit Version 3.4.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -158,7 +153,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`):
|
Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`):
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[16] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
|
||||||
|
|
||||||
### Die API-Dokumentation testen { #check-the-docs }
|
### Die API-Dokumentation testen { #check-the-docs }
|
||||||
|
|
||||||
@@ -174,13 +169,13 @@ Der *Pfad-Parameter* wird ein *<abbr title="Member – Mitglied: Einer der mögl
|
|||||||
|
|
||||||
Sie können ihn mit einem Member Ihrer Enumeration `ModelName` vergleichen:
|
Sie können ihn mit einem Member Ihrer Enumeration `ModelName` vergleichen:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[17] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
|
||||||
|
|
||||||
#### *Enumerations-Wert* erhalten { #get-the-enumeration-value }
|
#### *Enumerations-Wert* erhalten { #get-the-enumeration-value }
|
||||||
|
|
||||||
Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `your_enum_member.value`:
|
Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `your_enum_member.value`:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[20] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -194,7 +189,7 @@ Sie können *Enum-Member* in ihrer *Pfadoperation* zurückgeben, sogar verschach
|
|||||||
|
|
||||||
Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie zum Client übertragen werden:
|
Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie zum Client übertragen werden:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
|
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
|
||||||
|
|
||||||
In Ihrem Client erhalten Sie eine JSON-Response, wie etwa:
|
In Ihrem Client erhalten Sie eine JSON-Response, wie etwa:
|
||||||
|
|
||||||
@@ -233,7 +228,7 @@ In diesem Fall ist der Name des Parameters `file_path`. Der letzte Teil, `:path`
|
|||||||
|
|
||||||
Sie verwenden das also wie folgt:
|
Sie verwenden das also wie folgt:
|
||||||
|
|
||||||
{* ../../docs_src/path_params/tutorial004.py hl[6] *}
|
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ q: str | None = None
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
q: Union[str, None] = None
|
q: Union[str, None] = None
|
||||||
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
//// tab | Python 3.9+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
q: Annotated[Union[str, None]] = None
|
q: Annotated[Union[str, None]] = None
|
||||||
@@ -205,20 +205,6 @@ Wenn Sie sich mit all diesen **„regulärer Ausdruck“**-Ideen verloren fühle
|
|||||||
|
|
||||||
Aber nun wissen Sie, dass Sie sie in **FastAPI** immer dann verwenden können, wenn Sie sie brauchen.
|
Aber nun wissen Sie, dass Sie sie in **FastAPI** immer dann verwenden können, wenn Sie sie brauchen.
|
||||||
|
|
||||||
### Pydantic v1 `regex` statt `pattern` { #pydantic-v1-regex-instead-of-pattern }
|
|
||||||
|
|
||||||
Vor Pydantic Version 2 und FastAPI 0.100.0, hieß der Parameter `regex` statt `pattern`, aber das ist jetzt obsolet.
|
|
||||||
|
|
||||||
Sie könnten immer noch Code sehen, der den alten Namen verwendet:
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
Beachten Sie aber, dass das obsolet ist und auf den neuen Parameter `pattern` aktualisiert werden sollte. 🤓
|
|
||||||
|
|
||||||
## Defaultwerte { #default-values }
|
## Defaultwerte { #default-values }
|
||||||
|
|
||||||
Natürlich können Sie Defaultwerte verwenden, die nicht `None` sind.
|
Natürlich können Sie Defaultwerte verwenden, die nicht `None` sind.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Wenn Sie in Ihrer Funktion andere Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.
|
Wenn Sie in Ihrer Funktion andere Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial001.py hl[9] *}
|
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
|
||||||
|
|
||||||
Die <abbr title="Abfrage">Query</abbr> ist die Menge von Schlüssel-Wert-Paaren, die nach dem `?` in einer URL folgen und durch `&`-Zeichen getrennt sind.
|
Die <abbr title="Abfrage">Query</abbr> ist die Menge von Schlüssel-Wert-Paaren, die nach dem `?` in einer URL folgen und durch `&`-Zeichen getrennt sind.
|
||||||
|
|
||||||
@@ -127,7 +127,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:
|
Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert:
|
||||||
|
|
||||||
{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
|
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
|
||||||
|
|
||||||
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.
|
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,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}.
|
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}.
|
||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
|
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
|
||||||
|
|
||||||
Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist.
|
Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist.
|
||||||
|
|
||||||
@@ -193,7 +193,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.
|
Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden.
|
||||||
|
|
||||||
{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
|
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
|
||||||
|
|
||||||
Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert.
|
Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert.
|
||||||
|
|
||||||
@@ -252,20 +252,6 @@ Wenn Sie also den Artikel mit der ID `foo` bei der *Pfadoperation* anfragen, wir
|
|||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_dump()` umbenannt.
|
|
||||||
|
|
||||||
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
FastAPI verwendet `.dict()` von Pydantic Modellen, <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">mit dessen `exclude_unset`-Parameter</a>, um das zu erreichen.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
Sie können auch:
|
Sie können auch:
|
||||||
|
|
||||||
* `response_model_exclude_defaults=True`
|
* `response_model_exclude_defaults=True`
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-St
|
|||||||
* `@app.delete()`
|
* `@app.delete()`
|
||||||
* usw.
|
* usw.
|
||||||
|
|
||||||
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
|
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ Um mehr über die einzelnen Statuscodes zu erfahren und welcher wofür verwendet
|
|||||||
|
|
||||||
Lassen Sie uns das vorherige Beispiel noch einmal anschauen:
|
Lassen Sie uns das vorherige Beispiel noch einmal anschauen:
|
||||||
|
|
||||||
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
|
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
|
||||||
|
|
||||||
`201` ist der Statuscode für „Created“ („Erzeugt“).
|
`201` ist der Statuscode für „Created“ („Erzeugt“).
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ Aber Sie müssen sich nicht merken, was jeder dieser Codes bedeutet.
|
|||||||
|
|
||||||
Sie können die Annehmlichkeit von Variablen aus `fastapi.status` nutzen.
|
Sie können die Annehmlichkeit von Variablen aus `fastapi.status` nutzen.
|
||||||
|
|
||||||
{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
|
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
|
||||||
|
|
||||||
Diese sind nur eine Annehmlichkeit, sie enthalten dieselbe Zahl, aber so können Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden:
|
Diese sind nur eine Annehmlichkeit, sie enthalten dieselbe Zahl, aber so können Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden:
|
||||||
|
|
||||||
|
|||||||
@@ -8,36 +8,14 @@ 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.
|
Sie können `examples` („Beispiele“) für ein Pydantic-Modell deklarieren, welche dem generierten JSON-Schema hinzugefügt werden.
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
|
||||||
|
|
||||||
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
|
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
Diese zusätzlichen Informationen werden unverändert zum für dieses Modell ausgegebenen **JSON-Schema** hinzugefügt und in der API-Dokumentation verwendet.
|
Diese zusätzlichen Informationen werden unverändert zum für dieses Modell ausgegebenen **JSON-Schema** hinzugefügt und in der API-Dokumentation verwendet.
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
Sie können das Attribut `model_config` verwenden, das ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic-Dokumentation: Configuration</a>.
|
||||||
|
|
||||||
In Pydantic Version 2 würden Sie das Attribut `model_config` verwenden, das ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic-Dokumentation: Configuration</a>.
|
|
||||||
|
|
||||||
Sie können `json_schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
|
Sie können `json_schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
|
||||||
|
|
||||||
In Pydantic Version 1 würden Sie eine interne Klasse `Config` und `schema_extra` verwenden, wie beschrieben in <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic-Dokumentation: Schema customization</a>.
|
|
||||||
|
|
||||||
Sie können `schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
Mit derselben Technik können Sie das JSON-Schema erweitern und Ihre eigenen benutzerdefinierten Zusatzinformationen hinzufügen.
|
Mit derselben Technik können Sie das JSON-Schema erweitern und Ihre eigenen benutzerdefinierten Zusatzinformationen hinzufügen.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisc
|
|||||||
* Importieren Sie `StaticFiles`.
|
* Importieren Sie `StaticFiles`.
|
||||||
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
|
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
|
||||||
|
|
||||||
{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
|
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ 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`).
|
Schreiben Sie einfache `assert`-Anweisungen mit den Standard-Python-Ausdrücken, die Sie überprüfen müssen (wiederum, Standard-`pytest`).
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
|
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ Nehmen wir an, Sie haben eine Dateistruktur wie in [Größere Anwendungen](bigge
|
|||||||
In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung:
|
In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung:
|
||||||
|
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/main.py *}
|
{* ../../docs_src/app_testing/app_a_py39/main.py *}
|
||||||
|
|
||||||
|
|
||||||
### Testdatei { #testing-file }
|
### Testdatei { #testing-file }
|
||||||
@@ -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:
|
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:
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/test_main.py hl[3] *}
|
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
|
||||||
|
|
||||||
|
|
||||||
... und haben den Code für die Tests wie zuvor.
|
... und haben den Code für die Tests wie zuvor.
|
||||||
@@ -122,63 +122,13 @@ Sie verfügt über eine `POST`-Operation, die mehrere Fehler zurückgeben könnt
|
|||||||
|
|
||||||
Beide *Pfadoperationen* erfordern einen `X-Token`-Header.
|
Beide *Pfadoperationen* erfordern einen `X-Token`-Header.
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
|
||||||
|
|
||||||
```Python
|
|
||||||
{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
|
||||||
|
|
||||||
```Python
|
|
||||||
{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
```Python
|
|
||||||
{!> ../../docs_src/app_testing/app_b_an/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.10+ nicht annotiert
|
|
||||||
|
|
||||||
/// tip | Tipp
|
|
||||||
|
|
||||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
```Python
|
|
||||||
{!> ../../docs_src/app_testing/app_b_py310/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
|
||||||
|
|
||||||
/// tip | Tipp
|
|
||||||
|
|
||||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
```Python
|
|
||||||
{!> ../../docs_src/app_testing/app_b/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
### Erweiterte Testdatei { #extended-testing-file }
|
### Erweiterte Testdatei { #extended-testing-file }
|
||||||
|
|
||||||
Anschließend könnten Sie `test_main.py` mit den erweiterten Tests aktualisieren:
|
Anschließend könnten Sie `test_main.py` mit den erweiterten Tests aktualisieren:
|
||||||
|
|
||||||
{* ../../docs_src/app_testing/app_b/test_main.py *}
|
{* ../../docs_src/app_testing/app_b_an_py310/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.
|
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.
|
||||||
|
|||||||
+230
-246
@@ -4,213 +4,197 @@ Translate to German (Deutsch).
|
|||||||
|
|
||||||
Language code: de.
|
Language code: de.
|
||||||
|
|
||||||
|
|
||||||
### Definitions
|
|
||||||
|
|
||||||
"hyphen"
|
|
||||||
The character «-»
|
|
||||||
Unicode U+002D (HYPHEN-MINUS)
|
|
||||||
Alternative names: hyphen, dash, minus sign
|
|
||||||
|
|
||||||
"dash"
|
|
||||||
The character «–»
|
|
||||||
Unicode U+2013 (EN DASH)
|
|
||||||
German name: Halbgeviertstrich
|
|
||||||
|
|
||||||
|
|
||||||
### Grammar to use when talking to the reader
|
### Grammar to use when talking to the reader
|
||||||
|
|
||||||
Use the formal grammar (use «Sie» instead of «Du»).
|
Use the formal grammar (use `Sie` instead of `Du`).
|
||||||
|
|
||||||
|
|
||||||
### Quotes
|
### Quotes
|
||||||
|
|
||||||
1) Convert neutral double quotes («"») and English double typographic quotes («“» and «”») to German double typographic quotes («„» and «“»). Convert neutral single quotes («'») and English single typographic quotes («‘» and «’») to German single typographic quotes («‚» and «‘»). Do NOT convert «`"» to «„», do NOT convert «"`» to «“».
|
1) Convert neutral double quotes (`"`) to German double typographic quotes (`„` and `“`). Convert neutral single quotes (`'`) to German single typographic quotes (`‚` and `‘`).
|
||||||
|
|
||||||
|
Do NOT convert quotes in code snippets and code blocks to their German typographic equivalents.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
"Hello world"
|
"Hello world"
|
||||||
“Hello Universe”
|
“Hello Universe”
|
||||||
"He said: 'Hello'"
|
"He said: 'Hello'"
|
||||||
“my name is ‘Nils’”
|
“my name is ‘Nils’”
|
||||||
`"__main__"`
|
`"__main__"`
|
||||||
`"items"`
|
`"items"`
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Result (German):
|
Result (German):
|
||||||
|
|
||||||
«««
|
|
||||||
„Hallo Welt“
|
|
||||||
„Hallo Universum“
|
|
||||||
„Er sagte: ‚Hallo‘“
|
|
||||||
„Mein Name ist ‚Nils‘“
|
|
||||||
`"__main__"`
|
|
||||||
`"items"`
|
|
||||||
»»»
|
|
||||||
|
|
||||||
|
```
|
||||||
|
„Hallo Welt“
|
||||||
|
„Hallo Universum“
|
||||||
|
„Er sagte: ‚Hallo‘“
|
||||||
|
„Mein Name ist ‚Nils‘“
|
||||||
|
`"__main__"`
|
||||||
|
`"items"`
|
||||||
|
```
|
||||||
|
|
||||||
### Ellipsis
|
### Ellipsis
|
||||||
|
|
||||||
1) Make sure there is a space between an ellipsis and a word following or preceding the ellipsis.
|
- Make sure there is a space between an ellipsis and a word following or preceding the ellipsis.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
...as we intended.
|
...as we intended.
|
||||||
...this would work:
|
...this would work:
|
||||||
...etc.
|
...etc.
|
||||||
others...
|
others...
|
||||||
More to come...
|
More to come...
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Result (German):
|
Result (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
... wie wir es beabsichtigt hatten.
|
... wie wir es beabsichtigt hatten.
|
||||||
... das würde funktionieren:
|
... das würde funktionieren:
|
||||||
... usw.
|
... usw.
|
||||||
Andere ...
|
Andere ...
|
||||||
Später mehr ...
|
Später mehr ...
|
||||||
»»»
|
```
|
||||||
|
|
||||||
2) This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there.
|
|
||||||
|
|
||||||
|
- This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there.
|
||||||
|
|
||||||
### Headings
|
### Headings
|
||||||
|
|
||||||
1) Translate headings using the infinite form.
|
- Translate headings using the infinite form.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Create a Project { #create-a-project }
|
## Create a Project { #create-a-project }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Translate with (German):
|
Result (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Ein Projekt erstellen { #create-a-project }
|
## Ein Projekt erstellen { #create-a-project }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Do NOT translate with (German):
|
Do NOT translate with (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Erstellen Sie ein Projekt { #create-a-project }
|
## Erstellen Sie ein Projekt { #create-a-project }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
# Install Packages { #install-packages }
|
# Install Packages { #install-packages }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Translate with (German):
|
Translate with (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
# Pakete installieren { #install-packages }
|
# Pakete installieren { #install-packages }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Do NOT translate with (German):
|
Do NOT translate with (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
# Installieren Sie Pakete { #install-packages }
|
# Installieren Sie Pakete { #install-packages }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
### Run Your Program { #run-your-program }
|
### Run Your Program { #run-your-program }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Translate with (German):
|
Translate with (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
### Ihr Programm ausführen { #run-your-program }
|
### Ihr Programm ausführen { #run-your-program }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Do NOT translate with (German):
|
Do NOT translate with (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
### Führen Sie Ihr Programm aus { #run-your-program }
|
### Führen Sie Ihr Programm aus { #run-your-program }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
2) Make sure that the translated part of the heading does not end with a period.
|
- Make sure that the translated part of the heading does not end with a period.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Another module with `APIRouter` { #another-module-with-apirouter }
|
## Another module with `APIRouter` { #another-module-with-apirouter }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Translate with (German):
|
Translate with (German):
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Ein weiteres Modul mit `APIRouter` { #another-module-with-apirouter }
|
## Ein weiteres Modul mit `APIRouter` { #another-module-with-apirouter }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Do NOT translate with (German) – notice the added period:
|
Do NOT translate with (German) – notice the added period:
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Ein weiteres Modul mit `APIRouter`. { #another-module-with-apirouter }
|
## Ein weiteres Modul mit `APIRouter`. { #another-module-with-apirouter }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
3) Replace occurrences of literal « - » (a space followed by a hyphen followed by a space) with « – » (a space followed by a dash followed by a space) in the translated part of the heading.
|
- Replace occurrences of literal ` - ` (a space followed by a hyphen followed by a space) with ` – ` (a space followed by a dash followed by a space) in the translated part of the heading.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
# FastAPI in Containers - Docker { #fastapi-in-containers-docker }
|
# FastAPI in Containers - Docker { #fastapi-in-containers-docker }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Translate with (German) – notice the dash:
|
Translate with (German) – notice the dash:
|
||||||
|
|
||||||
«««
|
```
|
||||||
# FastAPI in Containern – Docker { #fastapi-in-containers-docker }
|
# FastAPI in Containern – Docker { #fastapi-in-containers-docker }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Do NOT translate with (German) – notice the hyphen:
|
Do NOT translate with (German) – notice the hyphen:
|
||||||
|
|
||||||
«««
|
```
|
||||||
# FastAPI in Containern - Docker { #fastapi-in-containers-docker }
|
# FastAPI in Containern - Docker { #fastapi-in-containers-docker }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
3.1) Do not apply rule 3 when there is no space before or no space after the hyphen.
|
- Do not apply rule 3 when there is no space before or no space after the hyphen.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
Source (English):
|
Source (English):
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Type hints and annotations { #type-hints-and-annotations }
|
## Type hints and annotations { #type-hints-and-annotations }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Translate with (German) – notice the hyphen:
|
Translate with (German) - notice the hyphen:
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Typhinweise und -annotationen { #type-hints-and-annotations }
|
## Typhinweise und -annotationen { #type-hints-and-annotations }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
Do NOT translate with (German) – notice the dash:
|
Do NOT translate with (German) - notice the dash:
|
||||||
|
|
||||||
«««
|
```
|
||||||
## Typhinweise und –annotationen { #type-hints-and-annotations }
|
## Typhinweise und –annotationen { #type-hints-and-annotations }
|
||||||
»»»
|
```
|
||||||
|
|
||||||
3.2) Do not apply rule 3 to the untranslated part of the heading inside curly brackets, which you shall not translate.
|
- Do not modify the hyphens in the content in headers inside of curly braces, which you shall not translate.
|
||||||
|
|
||||||
|
### German instructions, when to use and when not to use hyphens in words (written in first person, which is you).
|
||||||
### German instructions, when to use and when not to use hyphens in words (written in first person, which is you)
|
|
||||||
|
|
||||||
In der Regel versuche ich so weit wie möglich Worte zusammenzuschreiben, also ohne Bindestrich, es sei denn, es ist Konkretesding-Klassevondingen, etwa «Pydantic-Modell» (aber: «Datenbankmodell»), «Python-Modul» (aber: «Standardmodul»). Ich setze auch einen Bindestrich, wenn er die gleichen Buchstaben verbindet, etwa «Enum-Member», «Cloud-Dienst», «Template-Engine». Oder wenn das Wort sonst einfach zu lang wird, etwa, «Performance-Optimierung». Oder um etwas visuell besser zu dokumentieren, etwa «Pfadoperation-Dekorator», «Pfadoperation-Funktion».
|
In der Regel versuche ich so weit wie möglich Worte zusammenzuschreiben, also ohne Bindestrich, es sei denn, es ist Konkretesding-Klassevondingen, etwa «Pydantic-Modell» (aber: «Datenbankmodell»), «Python-Modul» (aber: «Standardmodul»). Ich setze auch einen Bindestrich, wenn er die gleichen Buchstaben verbindet, etwa «Enum-Member», «Cloud-Dienst», «Template-Engine». Oder wenn das Wort sonst einfach zu lang wird, etwa, «Performance-Optimierung». Oder um etwas visuell besser zu dokumentieren, etwa «Pfadoperation-Dekorator», «Pfadoperation-Funktion».
|
||||||
|
|
||||||
@@ -219,122 +203,122 @@ In der Regel versuche ich so weit wie möglich Worte zusammenzuschreiben, also o
|
|||||||
|
|
||||||
Ich versuche nicht, alles einzudeutschen. Das bezieht sich besonders auf Begriffe aus dem Bereich der Programmierung. Ich wandele zwar korrekt in Großschreibung um und setze Bindestriche, wo notwendig, aber ansonsten lasse ich solch ein Wort unverändert. Beispielsweise wird aus dem englischen Wort «string» in der deutschen Übersetzung «String», aber nicht «Zeichenkette». Oder aus dem englischen Wort «request body» wird in der deutschen Übersetzung «Requestbody», aber nicht «Anfragekörper». Oder aus dem englischen «response» wird im Deutschen «Response», aber nicht «Antwort».
|
Ich versuche nicht, alles einzudeutschen. Das bezieht sich besonders auf Begriffe aus dem Bereich der Programmierung. Ich wandele zwar korrekt in Großschreibung um und setze Bindestriche, wo notwendig, aber ansonsten lasse ich solch ein Wort unverändert. Beispielsweise wird aus dem englischen Wort «string» in der deutschen Übersetzung «String», aber nicht «Zeichenkette». Oder aus dem englischen Wort «request body» wird in der deutschen Übersetzung «Requestbody», aber nicht «Anfragekörper». Oder aus dem englischen «response» wird im Deutschen «Response», aber nicht «Antwort».
|
||||||
|
|
||||||
|
|
||||||
### List of English terms and their preferred German translations
|
### List of English terms and their preferred German translations
|
||||||
|
|
||||||
Below is a list of English terms and their preferred German translations, separated by a colon («:»). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them. In the below list, a term or a translation may be followed by an explanation in brackets, which explains when to translate the term this way. If a translation is preceded by «NOT», then that means: do NOT use this translation for this term. English nouns, starting with the word «the», have the German genus – «der», «die», «das» – prepended to their German translation, to help you to grammatically decline them in the translation. They are given in singular case, unless they have «(plural)» attached, which means they are given in plural case. Verbs are given in the full infinitive – starting with the word «to».
|
Below is a list of English terms and their preferred German translations, separated by a colon (:). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them. In the below list, a term or a translation may be followed by an explanation in brackets, which explains when to translate the term this way. If a translation is preceded by `NOT`, then that means: do NOT use this translation for this term. English nouns, starting with the word `the`, have the German genus – `der`, `die`, `das` – prepended to their German translation, to help you to grammatically decline them in the translation. They are given in singular case, unless they have `(plural)` attached, which means they are given in plural case. Verbs are given in the full infinitive – starting with the word `to`.
|
||||||
|
|
||||||
* «/// check»: «/// check | Testen»
|
* /// check: /// check | Testen
|
||||||
* «/// danger»: «/// danger | Gefahr»
|
* /// danger: /// danger | Gefahr
|
||||||
* «/// info»: «/// info | Info»
|
* /// info: /// info | Info
|
||||||
* «/// note | Technical Details»: «/// note | Technische Details»
|
* /// note | Technical Details: /// note | Technische Details
|
||||||
* «/// note»: «/// note | Hinweis»
|
* /// note: /// note | Hinweis
|
||||||
* «/// tip»: «/// tip | Tipp»
|
* /// tip: /// tip | Tipp
|
||||||
* «/// warning»: «/// warning | Achtung»
|
* /// warning: /// warning | Achtung
|
||||||
* «you»: «Sie»
|
* you: Sie
|
||||||
* «your»: «Ihr»
|
* your: Ihr
|
||||||
* «e.g»: «z. B.»
|
* e.g: z. B.
|
||||||
* «etc.»: «usw.»
|
* etc.: usw.
|
||||||
* «ref»: «Ref.»
|
* ref: Ref.
|
||||||
* «the Tutorial - User guide»: «das Tutorial – Benutzerhandbuch»
|
* the Tutorial - User guide: das Tutorial – Benutzerhandbuch
|
||||||
* «the Advanced User Guide»: «das Handbuch für fortgeschrittene Benutzer»
|
* the Advanced User Guide: das Handbuch für fortgeschrittene Benutzer
|
||||||
* «the SQLModel docs»: «die SQLModel-Dokumentation»
|
* the SQLModel docs: die SQLModel-Dokumentation
|
||||||
* «the docs»: «die Dokumentation» (use singular case)
|
* the docs: die Dokumentation (use singular case)
|
||||||
* «the env var»: «die Umgebungsvariable»
|
* the env var: die Umgebungsvariable
|
||||||
* «the `PATH` environment variable»: «die `PATH`-Umgebungsvariable»
|
* the `PATH` environment variable: die `PATH`-Umgebungsvariable
|
||||||
* «the `PATH`»: «der `PATH`»
|
* the `PATH`: der `PATH`
|
||||||
* «the `requirements.txt`»: «die `requirements.txt`»
|
* the `requirements.txt`: die `requirements.txt`
|
||||||
* «the API Router»: «der API-Router»
|
* the API Router: der API-Router
|
||||||
* «the Authorization-Header»: «der Autorisierungsheader»
|
* the Authorization-Header: der Autorisierungsheader
|
||||||
* «the `Authorization`-Header»: «der `Authorization`-Header»
|
* the `Authorization`-Header: der `Authorization`-Header
|
||||||
* «the background task»: «der Hintergrundtask»
|
* the background task: der Hintergrundtask
|
||||||
* «the button»: «der Button»
|
* the button: der Button
|
||||||
* «the cloud provider»: «der Cloudanbieter»
|
* the cloud provider: der Cloudanbieter
|
||||||
* «the CLI»: «Das CLI»
|
* the CLI: Das CLI
|
||||||
* «the command line interface»: «Das Kommandozeileninterface»
|
* the coverage: Die Testabdeckung
|
||||||
* «the default value»: «der Defaultwert»
|
* the command line interface: Das Kommandozeileninterface
|
||||||
* «the default value»: NOT «der Standardwert»
|
* the default value: der Defaultwert
|
||||||
* «the default declaration»: «die Default-Deklaration»
|
* the default value: NOT der Standardwert
|
||||||
* «the deployment»: «das Deployment»
|
* the default declaration: die Default-Deklaration
|
||||||
* «the dict»: «das Dict»
|
* the deployment: das Deployment
|
||||||
* «the dictionary»: «das Dictionary»
|
* the dict: das Dict
|
||||||
* «the enumeration»: «die Enumeration»
|
* the dictionary: das Dictionary
|
||||||
* «the enum»: «das Enum»
|
* the enumeration: die Enumeration
|
||||||
* «the engine»: «die Engine»
|
* the enum: das Enum
|
||||||
* «the error response»: «die Error-Response»
|
* the engine: die Engine
|
||||||
* «the event»: «das Event»
|
* the error response: die Error-Response
|
||||||
* «the exception»: «die Exception»
|
* the event: das Event
|
||||||
* «the exception handler»: «der Exceptionhandler»
|
* the exception: die Exception
|
||||||
* «the form model»: «das Formularmodell»
|
* the exception handler: der Exceptionhandler
|
||||||
* «the form body»: «der Formularbody»
|
* the form model: das Formularmodell
|
||||||
* «the header»: «der Header»
|
* the form body: der Formularbody
|
||||||
* «the headers» (plural): «die Header»
|
* the header: der Header
|
||||||
* «in headers» (plural): «in Headern»
|
* the headers (plural): die Header
|
||||||
* «the forwarded header»: «der Forwarded-Header»
|
* in headers (plural): in Headern
|
||||||
* «the lifespan event»: «das Lifespan-Event»
|
* the forwarded header: der Forwarded-Header
|
||||||
* «the lock»: «der Lock»
|
* the lifespan event: das Lifespan-Event
|
||||||
* «the locking»: «das Locking»
|
* the lock: der Lock
|
||||||
* «the mobile application»: «die Mobile-Anwendung»
|
* the locking: das Locking
|
||||||
* «the model object»: «das Modellobjekt»
|
* the mobile application: die Mobile-Anwendung
|
||||||
* «the mounting»: «das Mounten»
|
* the model object: das Modellobjekt
|
||||||
* «mounted»: «gemountet»
|
* the mounting: das Mounten
|
||||||
* «the origin»: «das Origin»
|
* mounted: gemountet
|
||||||
* «the override»: «Die Überschreibung»
|
* the origin: das Origin
|
||||||
* «the parameter»: «der Parameter»
|
* the override: Die Überschreibung
|
||||||
* «the parameters» (plural): «die Parameter»
|
* the parameter: der Parameter
|
||||||
* «the function parameter»: «der Funktionsparameter»
|
* the parameters (plural): die Parameter
|
||||||
* «the default parameter»: «der Defaultparameter»
|
* the function parameter: der Funktionsparameter
|
||||||
* «the body parameter»: «der Body-Parameter»
|
* the default parameter: der Defaultparameter
|
||||||
* «the request body parameter»: «der Requestbody-Parameter»
|
* the body parameter: der Body-Parameter
|
||||||
* «the path parameter»: «der Pfad-Parameter»
|
* the request body parameter: der Requestbody-Parameter
|
||||||
* «the query parameter»: «der Query-Parameter»
|
* the path parameter: der Pfad-Parameter
|
||||||
* «the cookie parameter»: «der Cookie-Parameter»
|
* the query parameter: der Query-Parameter
|
||||||
* «the header parameter»: «der Header-Parameter»
|
* the cookie parameter: der Cookie-Parameter
|
||||||
* «the form parameter»: «der Formular-Parameter»
|
* the header parameter: der Header-Parameter
|
||||||
* «the payload»: «die Payload»
|
* the form parameter: der Formular-Parameter
|
||||||
* «the performance»: NOT «die Performance»
|
* the payload: die Payload
|
||||||
* «the query»: «die Query»
|
* the performance: NOT die Performance
|
||||||
* «the recap»: «die Zusammenfassung»
|
* the query: die Query
|
||||||
* «the request» (what the client sends to the server): «der Request»
|
* the recap: die Zusammenfassung
|
||||||
* «the request body»: «der Requestbody»
|
* the request (what the client sends to the server): der Request
|
||||||
* «the request bodies» (plural): «die Requestbodys»
|
* the request body: der Requestbody
|
||||||
* «the response» (what the server sends back to the client): «die Response»
|
* the request bodies (plural): die Requestbodys
|
||||||
* «the return type»: «der Rückgabetyp»
|
* the response (what the server sends back to the client): die Response
|
||||||
* «the return value»: «der Rückgabewert»
|
* the return type: der Rückgabetyp
|
||||||
* «the startup» (the event of the app): «der Startup»
|
* the return value: der Rückgabewert
|
||||||
* «the shutdown» (the event of the app): «der Shutdown»
|
* the startup (the event of the app): der Startup
|
||||||
* «the startup event»: «das Startup-Event»
|
* the shutdown (the event of the app): der Shutdown
|
||||||
* «the shutdown event»: «das Shutdown-Event»
|
* the startup event: das Startup-Event
|
||||||
* «the startup» (of the server): «das Hochfahren»
|
* the shutdown event: das Shutdown-Event
|
||||||
* «the startup» (the company): «das Startup»
|
* the startup (of the server): das Hochfahren
|
||||||
* «the SDK»: «das SDK»
|
* the startup (the company): das Startup
|
||||||
* «the tag»: «der Tag»
|
* the SDK: das SDK
|
||||||
* «the type annotation»: «die Typannotation»
|
* the tag: der Tag
|
||||||
* «the type hint»: «der Typhinweis»
|
* the type annotation: die Typannotation
|
||||||
* «the wildcard»: «die Wildcard»
|
* the type hint: der Typhinweis
|
||||||
* «the worker class»: «die Workerklasse»
|
* the wildcard: die Wildcard
|
||||||
* «the worker class»: NOT «die Arbeiterklasse»
|
* the worker class: die Workerklasse
|
||||||
* «the worker process»: «der Workerprozess»
|
* the worker class: NOT die Arbeiterklasse
|
||||||
* «the worker process»: NOT «der Arbeiterprozess»
|
* the worker process: der Workerprozess
|
||||||
* «to commit»: «committen»
|
* the worker process: NOT der Arbeiterprozess
|
||||||
* «to deploy» (in the cloud): «deployen»
|
* to commit: committen
|
||||||
* «to modify»: «ändern»
|
* to deploy (in the cloud): deployen
|
||||||
* «to serve» (an application): «bereitstellen»
|
* to modify: ändern
|
||||||
* «to serve» (a response): «ausliefern»
|
* to serve (an application): bereitstellen
|
||||||
* «to serve»: NOT «bedienen»
|
* to serve (a response): ausliefern
|
||||||
* «to upgrade»: «aktualisieren»
|
* to serve: NOT bedienen
|
||||||
* «to wrap»: «wrappen»
|
* to upgrade: aktualisieren
|
||||||
* «to wrap»: NOT «hüllen»
|
* to wrap: wrappen
|
||||||
* «`foo` as a `type`»: «`foo` vom Typ `type`»
|
* to wrap: NOT hüllen
|
||||||
* «`foo` as a `type`»: «`foo`, ein `type`»
|
* `foo` as a `type`: `foo` vom Typ `type`
|
||||||
* «FastAPI's X»: «FastAPIs X»
|
* `foo` as a `type`: `foo`, ein `type`
|
||||||
* «Starlette's Y»: «Starlettes Y»
|
* FastAPI's X: FastAPIs X
|
||||||
* «X is case-sensitive»: «Groß-/Kleinschreibung ist relevant in X»
|
* Starlette's Y: Starlettes Y
|
||||||
* «X is case-insensitive»: «Groß-/Kleinschreibung ist nicht relevant in X»
|
* X is case-sensitive: Groß-/Kleinschreibung ist relevant in X
|
||||||
* «standard Python»: «Standard-Python»
|
* X is case-insensitive: Groß-/Kleinschreibung ist nicht relevant in X
|
||||||
* «deprecated»: «deprecatet»
|
* standard Python: Standard-Python
|
||||||
|
* deprecated: deprecatet
|
||||||
|
|
||||||
|
|
||||||
### Other rules
|
### Other rules
|
||||||
|
|
||||||
Preserve indentation. Keep emoticons. Encode in utf-8. Use Linux line breaks (LF).
|
Preserve indentation. Keep emojis. Encode in utf-8. Use Linux line breaks (LF).
|
||||||
|
|||||||
@@ -1,247 +0,0 @@
|
|||||||
# 🌖 📨 🗄
|
|
||||||
|
|
||||||
/// warning
|
|
||||||
|
|
||||||
👉 👍 🏧 ❔.
|
|
||||||
|
|
||||||
🚥 👆 ▶️ ⏮️ **FastAPI**, 👆 💪 🚫 💪 👉.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
👆 💪 📣 🌖 📨, ⏮️ 🌖 👔 📟, 🔉 🆎, 📛, ♒️.
|
|
||||||
|
|
||||||
👈 🌖 📨 🔜 🔌 🗄 🔗, 👫 🔜 😑 🛠️ 🩺.
|
|
||||||
|
|
||||||
✋️ 👈 🌖 📨 👆 ✔️ ⚒ 💭 👆 📨 `Response` 💖 `JSONResponse` 🔗, ⏮️ 👆 👔 📟 & 🎚.
|
|
||||||
|
|
||||||
## 🌖 📨 ⏮️ `model`
|
|
||||||
|
|
||||||
👆 💪 🚶♀️ 👆 *➡ 🛠️ 👨🎨* 🔢 `responses`.
|
|
||||||
|
|
||||||
⚫️ 📨 `dict`, 🔑 👔 📟 🔠 📨, 💖 `200`, & 💲 🎏 `dict`Ⓜ ⏮️ ℹ 🔠 👫.
|
|
||||||
|
|
||||||
🔠 👈 📨 `dict`Ⓜ 💪 ✔️ 🔑 `model`, ⚗ Pydantic 🏷, 💖 `response_model`.
|
|
||||||
|
|
||||||
**FastAPI** 🔜 ✊ 👈 🏷, 🏗 🚮 🎻 🔗 & 🔌 ⚫️ ☑ 🥉 🗄.
|
|
||||||
|
|
||||||
🖼, 📣 ➕1️⃣ 📨 ⏮️ 👔 📟 `404` & Pydantic 🏷 `Message`, 👆 💪 ✍:
|
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
|
|
||||||
|
|
||||||
/// note
|
|
||||||
|
|
||||||
✔️ 🤯 👈 👆 ✔️ 📨 `JSONResponse` 🔗.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// info
|
|
||||||
|
|
||||||
`model` 🔑 🚫 🍕 🗄.
|
|
||||||
|
|
||||||
**FastAPI** 🔜 ✊ Pydantic 🏷 ⚪️➡️ 📤, 🏗 `JSON Schema`, & 🚮 ⚫️ ☑ 🥉.
|
|
||||||
|
|
||||||
☑ 🥉:
|
|
||||||
|
|
||||||
* 🔑 `content`, 👈 ✔️ 💲 ➕1️⃣ 🎻 🎚 (`dict`) 👈 🔌:
|
|
||||||
* 🔑 ⏮️ 📻 🆎, ✅ `application/json`, 👈 🔌 💲 ➕1️⃣ 🎻 🎚, 👈 🔌:
|
|
||||||
* 🔑 `schema`, 👈 ✔️ 💲 🎻 🔗 ⚪️➡️ 🏷, 📥 ☑ 🥉.
|
|
||||||
* **FastAPI** 🚮 🔗 📥 🌐 🎻 🔗 ➕1️⃣ 🥉 👆 🗄 ↩️ ✅ ⚫️ 🔗. 👉 🌌, 🎏 🈸 & 👩💻 💪 ⚙️ 👈 🎻 🔗 🔗, 🚚 👻 📟 ⚡ 🧰, ♒️.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
🏗 📨 🗄 👉 *➡ 🛠️* 🔜:
|
|
||||||
|
|
||||||
```JSON hl_lines="3-12"
|
|
||||||
{
|
|
||||||
"responses": {
|
|
||||||
"404": {
|
|
||||||
"description": "Additional Response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/Message"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"200": {
|
|
||||||
"description": "Successful Response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/Item"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"422": {
|
|
||||||
"description": "Validation Error",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/HTTPValidationError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
🔗 🔗 ➕1️⃣ 🥉 🔘 🗄 🔗:
|
|
||||||
|
|
||||||
```JSON hl_lines="4-16"
|
|
||||||
{
|
|
||||||
"components": {
|
|
||||||
"schemas": {
|
|
||||||
"Message": {
|
|
||||||
"title": "Message",
|
|
||||||
"required": [
|
|
||||||
"message"
|
|
||||||
],
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"message": {
|
|
||||||
"title": "Message",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Item": {
|
|
||||||
"title": "Item",
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"value"
|
|
||||||
],
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"title": "Id",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"title": "Value",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ValidationError": {
|
|
||||||
"title": "ValidationError",
|
|
||||||
"required": [
|
|
||||||
"loc",
|
|
||||||
"msg",
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"loc": {
|
|
||||||
"title": "Location",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"msg": {
|
|
||||||
"title": "Message",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"title": "Error Type",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"HTTPValidationError": {
|
|
||||||
"title": "HTTPValidationError",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"detail": {
|
|
||||||
"title": "Detail",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/ValidationError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🌖 🔉 🆎 👑 📨
|
|
||||||
|
|
||||||
👆 💪 ⚙️ 👉 🎏 `responses` 🔢 🚮 🎏 🔉 🆎 🎏 👑 📨.
|
|
||||||
|
|
||||||
🖼, 👆 💪 🚮 🌖 📻 🆎 `image/png`, 📣 👈 👆 *➡ 🛠️* 💪 📨 🎻 🎚 (⏮️ 📻 🆎 `application/json`) ⚖️ 🇩🇴 🖼:
|
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
|
|
||||||
|
|
||||||
/// note
|
|
||||||
|
|
||||||
👀 👈 👆 ✔️ 📨 🖼 ⚙️ `FileResponse` 🔗.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// info
|
|
||||||
|
|
||||||
🚥 👆 ✔ 🎏 📻 🆎 🎯 👆 `responses` 🔢, FastAPI 🔜 🤔 📨 ✔️ 🎏 📻 🆎 👑 📨 🎓 (🔢 `application/json`).
|
|
||||||
|
|
||||||
✋️ 🚥 👆 ✔️ ✔ 🛃 📨 🎓 ⏮️ `None` 🚮 📻 🆎, FastAPI 🔜 ⚙️ `application/json` 🙆 🌖 📨 👈 ✔️ 👨💼 🏷.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
## 🌀 ℹ
|
|
||||||
|
|
||||||
👆 💪 🌀 📨 ℹ ⚪️➡️ 💗 🥉, 🔌 `response_model`, `status_code`, & `responses` 🔢.
|
|
||||||
|
|
||||||
👆 💪 📣 `response_model`, ⚙️ 🔢 👔 📟 `200` (⚖️ 🛃 1️⃣ 🚥 👆 💪), & ⤴️ 📣 🌖 ℹ 👈 🎏 📨 `responses`, 🔗 🗄 🔗.
|
|
||||||
|
|
||||||
**FastAPI** 🔜 🚧 🌖 ℹ ⚪️➡️ `responses`, & 🌀 ⚫️ ⏮️ 🎻 🔗 ⚪️➡️ 👆 🏷.
|
|
||||||
|
|
||||||
🖼, 👆 💪 📣 📨 ⏮️ 👔 📟 `404` 👈 ⚙️ Pydantic 🏷 & ✔️ 🛃 `description`.
|
|
||||||
|
|
||||||
& 📨 ⏮️ 👔 📟 `200` 👈 ⚙️ 👆 `response_model`, ✋️ 🔌 🛃 `example`:
|
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
|
|
||||||
|
|
||||||
⚫️ 🔜 🌐 🌀 & 🔌 👆 🗄, & 🎦 🛠️ 🩺:
|
|
||||||
|
|
||||||
<img src="/img/tutorial/additional-responses/image01.png">
|
|
||||||
|
|
||||||
## 🌀 🔢 📨 & 🛃 🕐
|
|
||||||
|
|
||||||
👆 💪 💚 ✔️ 🔁 📨 👈 ✔ 📚 *➡ 🛠️*, ✋️ 👆 💚 🌀 👫 ⏮️ 🛃 📨 💚 🔠 *➡ 🛠️*.
|
|
||||||
|
|
||||||
📚 💼, 👆 💪 ⚙️ 🐍 ⚒ "🏗" `dict` ⏮️ `**dict_to_unpack`:
|
|
||||||
|
|
||||||
```Python
|
|
||||||
old_dict = {
|
|
||||||
"old key": "old value",
|
|
||||||
"second old key": "second old value",
|
|
||||||
}
|
|
||||||
new_dict = {**old_dict, "new key": "new value"}
|
|
||||||
```
|
|
||||||
|
|
||||||
📥, `new_dict` 🔜 🔌 🌐 🔑-💲 👫 ⚪️➡️ `old_dict` ➕ 🆕 🔑-💲 👫:
|
|
||||||
|
|
||||||
```Python
|
|
||||||
{
|
|
||||||
"old key": "old value",
|
|
||||||
"second old key": "second old value",
|
|
||||||
"new key": "new value",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
👆 💪 ⚙️ 👈 ⚒ 🏤-⚙️ 🔢 📨 👆 *➡ 🛠️* & 🌀 👫 ⏮️ 🌖 🛃 🕐.
|
|
||||||
|
|
||||||
🖼:
|
|
||||||
|
|
||||||
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
|
|
||||||
|
|
||||||
## 🌖 ℹ 🔃 🗄 📨
|
|
||||||
|
|
||||||
👀 ⚫️❔ ⚫️❔ 👆 💪 🔌 📨, 👆 💪 ✅ 👉 📄 🗄 🔧:
|
|
||||||
|
|
||||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject" class="external-link" target="_blank">🗄 📨 🎚</a>, ⚫️ 🔌 `Response Object`.
|
|
||||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject" class="external-link" target="_blank">🗄 📨 🎚</a>, 👆 💪 🔌 🕳 ⚪️➡️ 👉 🔗 🔠 📨 🔘 👆 `responses` 🔢. ✅ `description`, `headers`, `content` (🔘 👉 👈 👆 📣 🎏 🔉 🆎 & 🎻 🔗), & `links`.
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# 🌖 👔 📟
|
|
||||||
|
|
||||||
🔢, **FastAPI** 🔜 📨 📨 ⚙️ `JSONResponse`, 🚮 🎚 👆 📨 ⚪️➡️ 👆 *➡ 🛠️* 🔘 👈 `JSONResponse`.
|
|
||||||
|
|
||||||
⚫️ 🔜 ⚙️ 🔢 👔 📟 ⚖️ 1️⃣ 👆 ⚒ 👆 *➡ 🛠️*.
|
|
||||||
|
|
||||||
## 🌖 👔 📟
|
|
||||||
|
|
||||||
🚥 👆 💚 📨 🌖 👔 📟 ↖️ ⚪️➡️ 👑 1️⃣, 👆 💪 👈 🛬 `Response` 🔗, 💖 `JSONResponse`, & ⚒ 🌖 👔 📟 🔗.
|
|
||||||
|
|
||||||
🖼, ➡️ 💬 👈 👆 💚 ✔️ *➡ 🛠️* 👈 ✔ ℹ 🏬, & 📨 🇺🇸🔍 👔 📟 2️⃣0️⃣0️⃣ "👌" 🕐❔ 🏆.
|
|
||||||
|
|
||||||
✋️ 👆 💚 ⚫️ 🚫 🆕 🏬. & 🕐❔ 🏬 🚫 🔀 ⏭, ⚫️ ✍ 👫, & 📨 🇺🇸🔍 👔 📟 2️⃣0️⃣1️⃣ "✍".
|
|
||||||
|
|
||||||
🏆 👈, 🗄 `JSONResponse`, & 📨 👆 🎚 📤 🔗, ⚒ `status_code` 👈 👆 💚:
|
|
||||||
|
|
||||||
{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *}
|
|
||||||
|
|
||||||
/// warning
|
|
||||||
|
|
||||||
🕐❔ 👆 📨 `Response` 🔗, 💖 🖼 🔛, ⚫️ 🔜 📨 🔗.
|
|
||||||
|
|
||||||
⚫️ 🏆 🚫 🎻 ⏮️ 🏷, ♒️.
|
|
||||||
|
|
||||||
⚒ 💭 ⚫️ ✔️ 📊 👆 💚 ⚫️ ✔️, & 👈 💲 ☑ 🎻 (🚥 👆 ⚙️ `JSONResponse`).
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
/// note | 📡 ℹ
|
|
||||||
|
|
||||||
👆 💪 ⚙️ `from starlette.responses import JSONResponse`.
|
|
||||||
|
|
||||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. 🎏 ⏮️ `status`.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
## 🗄 & 🛠️ 🩺
|
|
||||||
|
|
||||||
🚥 👆 📨 🌖 👔 📟 & 📨 🔗, 👫 🏆 🚫 🔌 🗄 🔗 (🛠️ 🩺), ↩️ FastAPI 🚫 ✔️ 🌌 💭 ⏪ ⚫️❔ 👆 🚶 📨.
|
|
||||||
|
|
||||||
✋️ 👆 💪 📄 👈 👆 📟, ⚙️: [🌖 📨](additional-responses.md){.internal-link target=_blank}.
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user