Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18a95756ed | ||
|
|
95d1a394e6 |
+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:** 11614be9021aa4ac078d4d0693a8b5250a1010d8
|
||||||
**Sync Date:** 2025-12-07
|
**Sync Date:** 2026-03-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. 🙇
|
|
||||||
+10
-10
@@ -15,7 +15,7 @@ So verwenden:
|
|||||||
|
|
||||||
Die Tests:
|
Die Tests:
|
||||||
|
|
||||||
## Codeschnipsel { #code-snippets}
|
## Codeschnipsel { #code-snippets }
|
||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ Siehe Abschnitt `### Content of code snippets` im allgemeinen Prompt in `scripts
|
|||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
|
|
||||||
Gestern schrieb mein Freund: „Wenn man unkorrekt korrekt schreibt, hat man es unkorrekt geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚unkorrekt‘ ist unkorrekterweise nicht ‚„unkorrekt“‘“.
|
Gestern schrieb mein Freund: „Wenn man ‚incorrectly‘ korrekt schreibt, hat man es falsch geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚incorrectly‘ ist inkorrekterweise nicht ‚„incorrectly“‘“.
|
||||||
|
|
||||||
/// note | Hinweis
|
/// note | Hinweis
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ Siehe Abschnitt `### Links` im allgemeinen Prompt in `scripts/translate.py`.
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
## HTML „abbr“-Elemente { #html-abbr-elements }
|
## HTML-„abbr“-Elemente { #html-abbr-elements }
|
||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
|
|
||||||
@@ -202,11 +202,6 @@ Hier einige Dinge, die in HTML-„abbr“-Elemente gepackt sind (einige sind erf
|
|||||||
* <abbr title="XML Web Token">XWT</abbr>
|
* <abbr title="XML Web Token">XWT</abbr>
|
||||||
* <abbr title="Paralleles Server-Gateway-Interface">PSGI</abbr>
|
* <abbr title="Paralleles Server-Gateway-Interface">PSGI</abbr>
|
||||||
|
|
||||||
### Das abbr gibt eine Erklärung { #the-abbr-gives-an-explanation }
|
|
||||||
|
|
||||||
* <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</abbr>
|
|
||||||
* <abbr title="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</abbr>
|
|
||||||
|
|
||||||
### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
||||||
|
|
||||||
* <abbr title="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
|
* <abbr title="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
|
||||||
@@ -224,6 +219,11 @@ Siehe Abschnitt `### HTML abbr elements` im allgemeinen Prompt in `scripts/trans
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
|
## HTML „dfn“-Elemente { #html-dfn-elements }
|
||||||
|
|
||||||
|
* <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
|
||||||
|
* <dfn title="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</dfn>
|
||||||
|
|
||||||
## Überschriften { #headings }
|
## Überschriften { #headings }
|
||||||
|
|
||||||
//// tab | Test
|
//// tab | Test
|
||||||
@@ -248,7 +248,7 @@ Die einzige strenge Regel für Überschriften ist, dass das LLM den Hash-Teil in
|
|||||||
|
|
||||||
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
|
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
|
||||||
|
|
||||||
Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
|
Für einige sprachsspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|||||||
@@ -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_py310.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_py310.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 }
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Nicht die Klasse selbst (die bereits aufrufbar ist), sondern eine Instanz dieser
|
|||||||
|
|
||||||
Dazu deklarieren wir eine Methode `__call__`:
|
Dazu deklarieren wir eine Methode `__call__`:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
|
||||||
|
|
||||||
In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zusätzlichen Parametern und Unterabhängigkeiten zu suchen, und das ist es auch, was später aufgerufen wird, um einen Wert an den Parameter in Ihrer *Pfadoperation-Funktion* zu übergeben.
|
In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zusätzlichen Parametern und Unterabhängigkeiten zu suchen, und das ist es auch, was später aufgerufen wird, um einen Wert an den Parameter in Ihrer *Pfadoperation-Funktion* zu übergeben.
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zus
|
|||||||
|
|
||||||
Und jetzt können wir `__init__` verwenden, um die Parameter der Instanz zu deklarieren, die wir zum „Parametrisieren“ der Abhängigkeit verwenden können:
|
Und jetzt können wir `__init__` verwenden, um die Parameter der Instanz zu deklarieren, die wir zum „Parametrisieren“ der Abhängigkeit verwenden können:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
|
||||||
|
|
||||||
In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmern, wir werden es direkt in unserem Code verwenden.
|
In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmern, wir werden es direkt in unserem Code verwenden.
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmer
|
|||||||
|
|
||||||
Wir könnten eine Instanz dieser Klasse erstellen mit:
|
Wir könnten eine Instanz dieser Klasse erstellen mit:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
|
||||||
|
|
||||||
Und auf diese Weise können wir unsere Abhängigkeit „parametrisieren“, die jetzt `"bar"` enthält, als das Attribut `checker.fixed_content`.
|
Und auf diese Weise können wir unsere Abhängigkeit „parametrisieren“, die jetzt `"bar"` enthält, als das Attribut `checker.fixed_content`.
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ checker(q="somequery")
|
|||||||
|
|
||||||
... und übergibt, was immer das als Wert dieser Abhängigkeit in unserer *Pfadoperation-Funktion* zurückgibt, als den Parameter `fixed_content_included`:
|
... und übergibt, was immer das als Wert dieser Abhängigkeit in unserer *Pfadoperation-Funktion* zurückgibt, als den Parameter `fixed_content_included`:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
|
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Fortgeschrittene Python-Typen { #advanced-python-types }
|
||||||
|
|
||||||
|
Hier sind einige zusätzliche Ideen, die beim Arbeiten mit Python-Typen nützlich sein könnten.
|
||||||
|
|
||||||
|
## `Union` oder `Optional` verwenden { #using-union-or-optional }
|
||||||
|
|
||||||
|
Wenn Ihr Code aus irgendeinem Grund nicht `|` verwenden kann, z. B. wenn es nicht in einer Typannotation ist, sondern in etwas wie `response_model=`, können Sie anstelle des senkrechten Strichs (`|`) `Union` aus `typing` verwenden.
|
||||||
|
|
||||||
|
Zum Beispiel könnten Sie deklarieren, dass etwas ein `str` oder `None` sein könnte:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
|
def say_hi(name: Union[str, None]):
|
||||||
|
print(f"Hi {name}!")
|
||||||
|
```
|
||||||
|
|
||||||
|
`typing` hat außerdem eine Abkürzung, um zu deklarieren, dass etwas `None` sein könnte, mit `Optional`.
|
||||||
|
|
||||||
|
Hier ist ein Tipp aus meiner sehr **subjektiven** Perspektive:
|
||||||
|
|
||||||
|
* 🚨 Vermeiden Sie die Verwendung von `Optional[SomeType]`
|
||||||
|
* Verwenden Sie stattdessen ✨ **`Union[SomeType, None]`** ✨.
|
||||||
|
|
||||||
|
Beides ist äquivalent und unter der Haube identisch, aber ich würde `Union` statt `Optional` empfehlen, weil das Wort „**optional**“ implizieren könnte, dass der Wert optional ist; tatsächlich bedeutet es jedoch „es kann `None` sein“, selbst wenn es nicht optional ist und weiterhin erforderlich bleibt.
|
||||||
|
|
||||||
|
Ich finde, `Union[SomeType, None]` ist expliziter in dem, was es bedeutet.
|
||||||
|
|
||||||
|
Es geht nur um Wörter und Namen. Aber diese Wörter können beeinflussen, wie Sie und Ihr Team über den Code denken.
|
||||||
|
|
||||||
|
Als Beispiel nehmen wir diese Funktion:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
def say_hi(name: Optional[str]):
|
||||||
|
print(f"Hey {name}!")
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Parameter `name` ist als `Optional[str]` definiert, aber er ist **nicht optional**, Sie können die Funktion nicht ohne den Parameter aufrufen:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
say_hi() # Oh nein, das löst einen Fehler aus! 😱
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Parameter `name` ist **weiterhin erforderlich** (nicht *optional*), weil er keinen Defaultwert hat. Dennoch akzeptiert `name` den Wert `None`:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
say_hi(name=None) # Das funktioniert, None ist gültig 🎉
|
||||||
|
```
|
||||||
|
|
||||||
|
Die gute Nachricht ist: In den meisten Fällen können Sie einfach `|` verwenden, um Unions von Typen zu definieren:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def say_hi(name: str | None):
|
||||||
|
print(f"Hey {name}!")
|
||||||
|
```
|
||||||
|
|
||||||
|
Sie müssen sich also normalerweise keine Gedanken über Namen wie `Optional` und `Union` machen. 😎
|
||||||
@@ -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_py310/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_py310/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_py310/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_py310/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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.py hl[2,4] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Verwendung von Datenklassen { #using-dataclasses }
|
# Datenklassen verwenden { #using-dataclasses }
|
||||||
|
|
||||||
FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden können, um <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> zu deklarieren.
|
FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden können, um <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> zu deklarieren.
|
||||||
|
|
||||||
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`.
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.da
|
|||||||
|
|
||||||
6. Hier geben wir ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> zurück, das `items` enthält, welches eine Liste von Datenklassen ist.
|
6. Hier geben wir ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> zurück, das `items` enthält, welches eine Liste von Datenklassen ist.
|
||||||
|
|
||||||
FastAPI ist weiterhin in der Lage, die Daten nach JSON zu <abbr title="Konvertieren der Daten in ein übertragbares Format">serialisieren</abbr>.
|
FastAPI ist weiterhin in der Lage, die Daten nach JSON zu <dfn title="Konvertieren der Daten in ein übertragbares Format">Serialisieren</dfn>.
|
||||||
|
|
||||||
7. Hier verwendet das `response_model` als Typannotation eine Liste von `Author`-Datenklassen.
|
7. Hier verwendet das `response_model` als Typannotation eine Liste von `Author`-Datenklassen.
|
||||||
|
|
||||||
|
|||||||
@@ -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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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`.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Da **FastAPI** auf der **OpenAPI**-Spezifikation basiert, können dessen APIs in einem standardisierten Format beschrieben werden, das viele Tools verstehen.
|
Da **FastAPI** auf der **OpenAPI**-Spezifikation basiert, können dessen APIs in einem standardisierten Format beschrieben werden, das viele Tools verstehen.
|
||||||
|
|
||||||
Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr title="Software Development Kit – Software-Entwicklungspaket">**SDKs**</abbr>) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben.
|
Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr title="Software Development Kits - Software-Entwicklungspakete">**SDKs**</abbr>) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben.
|
||||||
|
|
||||||
In diesem Leitfaden erfahren Sie, wie Sie ein **TypeScript-SDK** für Ihr FastAPI-Backend generieren.
|
In diesem Leitfaden erfahren Sie, wie Sie ein **TypeScript-SDK** für Ihr FastAPI-Backend generieren.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Einige dieser Lösungen sind möglicherweise auch Open Source oder bieten kosten
|
|||||||
|
|
||||||
Beginnen wir mit einer einfachen FastAPI-Anwendung:
|
Beginnen wir mit einer einfachen FastAPI-Anwendung:
|
||||||
|
|
||||||
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
|
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
|
||||||
|
|
||||||
Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, die sie für die <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>- und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-<abbr title="Die eigentlichen Nutzdaten, abzüglich der Metadaten">Payload</abbr> verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden.
|
Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, die sie für die <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>- und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-<abbr title="Die eigentlichen Nutzdaten, abzüglich der Metadaten">Payload</abbr> verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden.
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ In vielen Fällen wird Ihre FastAPI-App größer sein und Sie werden wahrscheinl
|
|||||||
|
|
||||||
Zum Beispiel könnten Sie einen Abschnitt für **Items (Artikel)** und einen weiteren Abschnitt für **Users (Benutzer)** haben, und diese könnten durch Tags getrennt sein:
|
Zum Beispiel könnten Sie einen Abschnitt für **Items (Artikel)** und einen weiteren Abschnitt für **Users (Benutzer)** haben, und diese könnten durch Tags getrennt sein:
|
||||||
|
|
||||||
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
|
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
|
||||||
|
|
||||||
### Einen TypeScript-Client mit Tags generieren { #generate-a-typescript-client-with-tags }
|
### Einen TypeScript-Client mit Tags generieren { #generate-a-typescript-client-with-tags }
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur
|
|||||||
|
|
||||||
Anschließend können Sie diese benutzerdefinierte Funktion als `generate_unique_id_function`-Parameter an **FastAPI** übergeben:
|
Anschließend können Sie diese benutzerdefinierte Funktion als `generate_unique_id_function`-Parameter an **FastAPI** übergeben:
|
||||||
|
|
||||||
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
|
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
|
||||||
|
|
||||||
### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren { #generate-a-typescript-client-with-custom-operation-ids }
|
### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren { #generate-a-typescript-client-with-custom-operation-ids }
|
||||||
|
|
||||||
@@ -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_py310.py *}
|
||||||
|
|
||||||
//// tab | Node.js
|
//// tab | Node.js
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dan
|
|||||||
|
|
||||||
Damit würden die Operation-IDs von Dingen wie `items-get_items` in `get_items` umbenannt, sodass der Client-Generator einfachere Methodennamen generieren kann.
|
Damit würden die Operation-IDs von Dingen wie `items-get_items` in `get_items` umbenannt, sodass der Client-Generator einfachere Methodennamen generieren kann.
|
||||||
|
|
||||||
### Einen TypeScript-Client mit der modifizierten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi }
|
### Einen TypeScript-Client mit der vorverarbeiteten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi }
|
||||||
|
|
||||||
Da das Endergebnis nun in einer `openapi.json`-Datei vorliegt, müssen Sie Ihren Eingabeort aktualisieren:
|
Da das Endergebnis nun in einer `openapi.json`-Datei vorliegt, müssen Sie Ihren Eingabeort aktualisieren:
|
||||||
|
|
||||||
|
|||||||
@@ -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_py310.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_py310.py hl[2,6:8] *}
|
||||||
|
|
||||||
Die folgenden Argumente werden unterstützt:
|
Die folgenden Argumente werden unterstützt:
|
||||||
|
|
||||||
@@ -74,11 +74,11 @@ Wenn ein eingehender Request nicht korrekt validiert wird, wird eine `400`-<abbr
|
|||||||
|
|
||||||
## `GZipMiddleware` { #gzipmiddleware }
|
## `GZipMiddleware` { #gzipmiddleware }
|
||||||
|
|
||||||
Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`-Header enthalten.
|
Verarbeitet GZip-Responses für alle Requests, die „gzip“ im `Accept-Encoding`-Header enthalten.
|
||||||
|
|
||||||
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_py310.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
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Das wird normalerweise als **Web<abbr title="Haken, Einhängepunkt">hook</abbr>*
|
|||||||
|
|
||||||
## Webhooks-Schritte { #webhooks-steps }
|
## Webhooks-Schritte { #webhooks-steps }
|
||||||
|
|
||||||
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Body des Requests**.
|
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Requestbody**.
|
||||||
|
|
||||||
Sie definieren auch auf irgendeine Weise, in welchen **Momenten** Ihre App diese Requests oder Events senden wird.
|
Sie definieren auch auf irgendeine Weise, in welchen **Momenten** Ihre App diese Requests oder Events senden wird.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Die gesamte **Logik** zur Registrierung der URLs für Webhooks und der Code zum
|
|||||||
|
|
||||||
## Webhooks mit **FastAPI** und OpenAPI dokumentieren { #documenting-webhooks-with-fastapi-and-openapi }
|
## Webhooks mit **FastAPI** und OpenAPI dokumentieren { #documenting-webhooks-with-fastapi-and-openapi }
|
||||||
|
|
||||||
Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die Request**bodys** definieren, die Ihre App senden würde.
|
Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die **Requestbodys** definieren, die Ihre App senden würde.
|
||||||
|
|
||||||
Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. Möglicherweise können diese sogar einen Teil ihres eigenen API-Codes automatisch generieren.
|
Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. Möglicherweise können diese sogar einen Teil ihres eigenen API-Codes automatisch generieren.
|
||||||
|
|
||||||
@@ -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_py310.py hl[9:12,15:20] *}
|
||||||
|
|
||||||
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_py310.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_py310.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_py310.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_py310.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.
|
||||||
|
|
||||||
@@ -135,13 +135,13 @@ Das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash
|
|||||||
|
|
||||||
Sie können dem automatisch generierten Schema also zusätzliche Daten hinzufügen.
|
Sie können dem automatisch generierten Schema also zusätzliche Daten hinzufügen.
|
||||||
|
|
||||||
Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit Ihrem eigenen Code zu lesen und zu validieren, ohne die automatischen Funktionen von FastAPI mit Pydantic zu verwenden, aber Sie könnten den Request trotzdem im OpenAPI-Schema definieren wollen.
|
Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit Ihrem eigenen Code zu lesen und zu validieren, ohne FastAPIs automatische Funktionen mit Pydantic zu verwenden, aber Sie könnten den Request trotzdem im OpenAPI-Schema definieren wollen.
|
||||||
|
|
||||||
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_py310.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 <dfn title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertiert">geparst</dfn>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
|
||||||
|
|
||||||
Dennoch können wir das zu erwartende Schema für den Requestbody deklarieren.
|
Dennoch können wir das zu erwartende Schema für den Requestbody deklarieren.
|
||||||
|
|
||||||
@@ -151,49 +151,17 @@ Mit demselben Trick könnten Sie ein Pydantic-Modell verwenden, um das JSON-Sche
|
|||||||
|
|
||||||
Und Sie könnten dies auch tun, wenn der Datentyp im Request nicht JSON ist.
|
Und Sie könnten dies auch tun, wenn der Datentyp im Request nicht JSON ist.
|
||||||
|
|
||||||
In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
|
In der folgenden Anwendung verwenden wir beispielsweise weder FastAPIs integrierte Funktionalität 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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.py hl[10:12] *}
|
||||||
|
|
||||||
/// note | Technische Details
|
/// note | Technische Details
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Wenn Sie dann den Benutzernamen und das Passwort eingeben, sendet der Browser di
|
|||||||
* Diese gibt ein Objekt vom Typ `HTTPBasicCredentials` zurück:
|
* Diese gibt ein Objekt vom Typ `HTTPBasicCredentials` zurück:
|
||||||
* Es enthält den gesendeten `username` und das gesendete `password`.
|
* Es enthält den gesendeten `username` und das gesendete `password`.
|
||||||
|
|
||||||
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
|
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
|
||||||
|
|
||||||
Wenn Sie versuchen, die URL zum ersten Mal zu öffnen (oder in der Dokumentation auf den Button „Execute“ zu klicken), wird der Browser Sie nach Ihrem Benutzernamen und Passwort fragen:
|
Wenn Sie versuchen, die URL zum ersten Mal zu öffnen (oder in der Dokumentation auf den Button „Execute“ zu klicken), wird der Browser Sie nach Ihrem Benutzernamen und Passwort fragen:
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Um dies zu lösen, konvertieren wir zunächst den `username` und das `password`
|
|||||||
|
|
||||||
Dann können wir `secrets.compare_digest()` verwenden, um sicherzustellen, dass `credentials.username` `"stanleyjobson"` und `credentials.password` `"swordfish"` ist.
|
Dann können wir `secrets.compare_digest()` verwenden, um sicherzustellen, dass `credentials.username` `"stanleyjobson"` und `credentials.password` `"swordfish"` ist.
|
||||||
|
|
||||||
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
|
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
|
||||||
|
|
||||||
Dies wäre das gleiche wie:
|
Dies wäre das gleiche wie:
|
||||||
|
|
||||||
@@ -104,4 +104,4 @@ So ist Ihr Anwendungscode, dank der Verwendung von `secrets.compare_digest()`, v
|
|||||||
|
|
||||||
Nachdem Sie festgestellt haben, dass die Anmeldeinformationen falsch sind, geben Sie eine `HTTPException` mit dem Statuscode 401 zurück (derselbe, der auch zurückgegeben wird, wenn keine Anmeldeinformationen angegeben werden) und fügen den Header `WWW-Authenticate` hinzu, damit der Browser die Anmeldeaufforderung erneut anzeigt:
|
Nachdem Sie festgestellt haben, dass die Anmeldeinformationen falsch sind, geben Sie eine `HTTPException` mit dem Statuscode 401 zurück (derselbe, der auch zurückgegeben wird, wenn keine Anmeldeinformationen angegeben werden) und fügen den Header `WWW-Authenticate` hinzu, damit der Browser die Anmeldeaufforderung erneut anzeigt:
|
||||||
|
|
||||||
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
|
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
|
||||||
|
|||||||
@@ -46,12 +46,6 @@ $ pip install "fastapi[all]"
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
/// info | Info
|
|
||||||
|
|
||||||
In Pydantic v1 war es im Hauptpackage enthalten. Jetzt wird es als unabhängiges Package verteilt, sodass Sie wählen können, ob Sie es installieren möchten oder nicht, falls Sie die Funktionalität nicht benötigen.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
### Das `Settings`-Objekt erstellen { #create-the-settings-object }
|
### Das `Settings`-Objekt erstellen { #create-the-settings-object }
|
||||||
|
|
||||||
Importieren Sie `BaseSettings` aus Pydantic und erstellen Sie eine Unterklasse, ganz ähnlich wie bei einem Pydantic-Modell.
|
Importieren Sie `BaseSettings` aus Pydantic und erstellen Sie eine Unterklasse, ganz ähnlich wie bei einem Pydantic-Modell.
|
||||||
@@ -60,23 +54,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_py310.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 +70,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_py310.py hl[18:20] *}
|
||||||
|
|
||||||
### Den Server ausführen { #run-the-server }
|
### Den Server ausführen { #run-the-server }
|
||||||
|
|
||||||
@@ -126,11 +104,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_py310/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_py310/main.py hl[3,11:13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -148,7 +126,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_py310/config.py hl[10] *}
|
||||||
|
|
||||||
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
|
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
|
||||||
|
|
||||||
@@ -156,7 +134,7 @@ Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erste
|
|||||||
|
|
||||||
Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurückgibt.
|
Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurückgibt.
|
||||||
|
|
||||||
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
|
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -168,13 +146,13 @@ Im Moment nehmen Sie an, dass `get_settings()` eine normale Funktion ist.
|
|||||||
|
|
||||||
Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einfordern und es überall dort verwenden, wo wir es brauchen.
|
Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einfordern und es überall dort verwenden, wo wir es brauchen.
|
||||||
|
|
||||||
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
|
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
|
||||||
|
|
||||||
### Einstellungen und Tests { #settings-and-testing }
|
### Einstellungen und Tests { #settings-and-testing }
|
||||||
|
|
||||||
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
|
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_py310/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 +193,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_py310/config.py hl[9] *}
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
|
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
@@ -225,26 +201,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 }
|
||||||
@@ -270,7 +226,7 @@ würden wir dieses Objekt für jeden Request erstellen und die `.env`-Datei für
|
|||||||
|
|
||||||
Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Objekt nur einmal erstellt, nämlich beim ersten Aufruf. ✔️
|
Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Objekt nur einmal erstellt, nämlich beim ersten Aufruf. ✔️
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
|
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
|
||||||
|
|
||||||
Dann wird bei allen nachfolgenden Aufrufen von `get_settings()`, in den Abhängigkeiten für darauffolgende Requests, dasselbe Objekt zurückgegeben, das beim ersten Aufruf zurückgegeben wurde, anstatt den Code von `get_settings()` erneut auszuführen und ein neues `Settings`-Objekt zu erstellen.
|
Dann wird bei allen nachfolgenden Aufrufen von `get_settings()`, in den Abhängigkeiten für darauffolgende Requests, dasselbe Objekt zurückgegeben, das beim ersten Aufruf zurückgegeben wurde, anstatt den Code von `get_settings()` erneut auszuführen und ein neues `Settings`-Objekt zu erstellen.
|
||||||
|
|
||||||
|
|||||||
@@ -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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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.
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ In WebSocket-Endpunkten können Sie Folgendes aus `fastapi` importieren und verw
|
|||||||
|
|
||||||
Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfadoperationen*:
|
Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfadoperationen*:
|
||||||
|
|
||||||
{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
|
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
|
||||||
|
|
||||||
/// info | Info
|
/// info | Info
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ Damit können Sie den WebSocket verbinden und dann Nachrichten senden und empfan
|
|||||||
|
|
||||||
Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_text()` eine `WebSocketDisconnect`-Exception aus, die Sie dann wie in folgendem Beispiel abfangen und behandeln können.
|
Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_text()` eine `WebSocketDisconnect`-Exception aus, die Sie dann wie in folgendem Beispiel abfangen und behandeln können.
|
||||||
|
|
||||||
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
|
{* ../../docs_src/websockets_/tutorial003_py310.py hl[79:81] *}
|
||||||
|
|
||||||
Zum Ausprobieren:
|
Zum Ausprobieren:
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,29 @@ Dazu können Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wr
|
|||||||
|
|
||||||
## `WSGIMiddleware` verwenden { #using-wsgimiddleware }
|
## `WSGIMiddleware` verwenden { #using-wsgimiddleware }
|
||||||
|
|
||||||
Sie müssen `WSGIMiddleware` importieren.
|
/// info | Info
|
||||||
|
|
||||||
|
Dafür muss `a2wsgi` installiert sein, z. B. mit `pip install a2wsgi`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Sie müssen `WSGIMiddleware` aus `a2wsgi` importieren.
|
||||||
|
|
||||||
Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
|
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_py310.py hl[1,3,23] *}
|
||||||
|
|
||||||
|
/// note | Hinweis
|
||||||
|
|
||||||
|
Früher wurde empfohlen, `WSGIMiddleware` aus `fastapi.middleware.wsgi` zu verwenden, dies ist jetzt deprecatet.
|
||||||
|
|
||||||
|
Stattdessen wird empfohlen, das Paket `a2wsgi` zu verwenden. Die Nutzung bleibt gleich.
|
||||||
|
|
||||||
|
Stellen Sie lediglich sicher, dass das Paket `a2wsgi` installiert ist und importieren Sie `WSGIMiddleware` korrekt aus `a2wsgi`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
## Es testen { #check-it }
|
## Es testen { #check-it }
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Es ist das beliebteste Python-Framework und genießt großes Vertrauen. Es wird
|
|||||||
|
|
||||||
Es ist relativ eng mit relationalen Datenbanken (wie MySQL oder PostgreSQL) gekoppelt, daher ist es nicht sehr einfach, eine NoSQL-Datenbank (wie Couchbase, MongoDB, Cassandra, usw.) als Hauptspeicherengine zu verwenden.
|
Es ist relativ eng mit relationalen Datenbanken (wie MySQL oder PostgreSQL) gekoppelt, daher ist es nicht sehr einfach, eine NoSQL-Datenbank (wie Couchbase, MongoDB, Cassandra, usw.) als Hauptspeicherengine zu verwenden.
|
||||||
|
|
||||||
Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie <abbr title="Internet of Things – Internet der Dinge">IoT</abbr>-Geräten) verwendet werden, um mit ihm zu kommunizieren.
|
Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie <abbr title="Internet of Things - Internet der Dinge">IoT</abbr>-Geräten) verwendet werden, um mit ihm zu kommunizieren.
|
||||||
|
|
||||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
|
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ Aus diesem Grund heißt es auf der offiziellen Website:
|
|||||||
|
|
||||||
> Requests ist eines der am häufigsten heruntergeladenen Python-Packages aller Zeiten
|
> Requests ist eines der am häufigsten heruntergeladenen Python-Packages aller Zeiten
|
||||||
|
|
||||||
Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu machen, würden Sie schreiben:
|
Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-<abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu machen, würden Sie schreiben:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
response = requests.get("http://example.com/some/url")
|
response = requests.get("http://example.com/some/url")
|
||||||
@@ -137,7 +137,7 @@ Es gibt mehrere Flask REST Frameworks, aber nachdem ich die Zeit und Arbeit inve
|
|||||||
|
|
||||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
|
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
|
||||||
|
|
||||||
Eine der von API-Systemen benötigten Hauptfunktionen ist die Daten-<abbr title="Auch „Marshalling“, „Konvertierung“ genannt">„Serialisierung“</abbr>, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw.
|
Eine der von API-Systemen benötigten Hauptfunktionen ist die Daten-<dfn title="auch genannt: Marshalling, Konvertierung">„Serialisierung“</dfn>, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw.
|
||||||
|
|
||||||
Eine weitere wichtige Funktion, benötigt von APIs, ist die Datenvalidierung, welche sicherstellt, dass die Daten unter gegebenen Umständen gültig sind. Zum Beispiel, dass ein Feld ein `int` ist und kein zufälliger String. Das ist besonders nützlich für hereinkommende Daten.
|
Eine weitere wichtige Funktion, benötigt von APIs, ist die Datenvalidierung, welche sicherstellt, dass die Daten unter gegebenen Umständen gültig sind. Zum Beispiel, dass ein Feld ein `int` ist und kein zufälliger String. Das ist besonders nützlich für hereinkommende Daten.
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ Ohne ein Datenvalidierungssystem müssten Sie alle Prüfungen manuell im Code du
|
|||||||
|
|
||||||
Für diese Funktionen wurde Marshmallow entwickelt. Es ist eine großartige Bibliothek und ich habe sie schon oft genutzt.
|
Für diese Funktionen wurde Marshmallow entwickelt. Es ist eine großartige Bibliothek und ich habe sie schon oft genutzt.
|
||||||
|
|
||||||
Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein <abbr title="die Definition, wie Daten geformt sein sollen">Schema</abbr> zu definieren, müssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden.
|
Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein <dfn title="die Definition, wie Daten geformt sein sollen">Schema</dfn> zu definieren, müssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden.
|
||||||
|
|
||||||
/// check | Inspirierte **FastAPI**
|
/// check | Inspirierte **FastAPI**
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ Code zu verwenden, um „Schemas“ zu definieren, welche Datentypen und Validie
|
|||||||
|
|
||||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
|
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
|
||||||
|
|
||||||
Eine weitere wichtige Funktion, die von APIs benötigt wird, ist das <abbr title="Lesen und Konvertieren nach Python-Daten">Parsen</abbr> von Daten aus eingehenden Requests.
|
Eine weitere wichtige Funktion, die von APIs benötigt wird, ist das <dfn title="Lesen und Konvertieren nach Python-Daten">Parsen</dfn> von Daten aus eingehenden Requests.
|
||||||
|
|
||||||
Webargs wurde entwickelt, um dieses für mehrere Frameworks, einschließlich Flask, bereitzustellen.
|
Webargs wurde entwickelt, um dieses für mehrere Frameworks, einschließlich Flask, bereitzustellen.
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ Aus diesem Grund basiert **FastAPI** auf Starlette, da dieses das schnellste ver
|
|||||||
|
|
||||||
Falcon ist ein weiteres leistungsstarkes Python-Framework. Es ist minimalistisch konzipiert und dient als Grundlage für andere Frameworks wie Hug.
|
Falcon ist ein weiteres leistungsstarkes Python-Framework. Es ist minimalistisch konzipiert und dient als Grundlage für andere Frameworks wie Hug.
|
||||||
|
|
||||||
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">„Response“</abbr>. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht möglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren.
|
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbr title="Response - Antwort: Daten, die der Server zum anfragenden Client zurücksendet">„Response“</abbr>. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht möglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren.
|
||||||
|
|
||||||
Daher müssen Datenvalidierung, Serialisierung und Dokumentation im Code und nicht automatisch erfolgen. Oder sie müssen als Framework oberhalb von Falcon implementiert werden, so wie Hug. Dieselbe Unterscheidung findet auch in anderen Frameworks statt, die vom Design von Falcon inspiriert sind und ein Requestobjekt und ein Responseobjekt als Parameter haben.
|
Daher müssen Datenvalidierung, Serialisierung und Dokumentation im Code und nicht automatisch erfolgen. Oder sie müssen als Framework oberhalb von Falcon implementiert werden, so wie Hug. Dieselbe Unterscheidung findet auch in anderen Frameworks statt, die vom Design von Falcon inspiriert sind und ein Requestobjekt und ein Responseobjekt als Parameter haben.
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ Die gesamte Datenvalidierung, Datenserialisierung und automatische Modelldokumen
|
|||||||
|
|
||||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
||||||
|
|
||||||
Starlette ist ein leichtgewichtiges <abbr title="Der neue Standard für die Erstellung asynchroner Python-Webanwendungen">ASGI</abbr>-Framework/Toolkit, welches sich ideal für die Erstellung hochperformanter asynchroner Dienste eignet.
|
Starlette ist ein leichtgewichtiges <dfn title="Der neue Standard für die Erstellung asynchroner Python-Webanwendungen">ASGI</dfn>-Framework/Toolkit, welches sich ideal für die Erstellung hochperformanter asynchroner Dienste eignet.
|
||||||
|
|
||||||
Es ist sehr einfach und intuitiv. Es ist so konzipiert, dass es leicht erweiterbar ist und über modulare Komponenten verfügt.
|
Es ist sehr einfach und intuitiv. Es ist so konzipiert, dass es leicht erweiterbar ist und über modulare Komponenten verfügt.
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Die Hierarchie ist wie folgt:
|
|||||||
* Sie würden eine Anwendung nicht direkt in Uvicorn schreiben. Das würde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten müsste. Und wenn Sie das täten, hätte Ihre endgültige Anwendung den gleichen Overhead wie bei der Verwendung eines Frameworks und der Minimierung Ihres Anwendungscodes und der Fehler.
|
* Sie würden eine Anwendung nicht direkt in Uvicorn schreiben. Das würde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten müsste. Und wenn Sie das täten, hätte Ihre endgültige Anwendung den gleichen Overhead wie bei der Verwendung eines Frameworks und der Minimierung Ihres Anwendungscodes und der Fehler.
|
||||||
* Wenn Sie Uvicorn vergleichen, vergleichen Sie es mit Anwendungsservern wie Daphne, Hypercorn, uWSGI, usw.
|
* Wenn Sie Uvicorn vergleichen, vergleichen Sie es mit Anwendungsservern wie Daphne, Hypercorn, uWSGI, usw.
|
||||||
* **Starlette**:
|
* **Starlette**:
|
||||||
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette intern Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgeführt werden muss.
|
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgeführt werden muss.
|
||||||
* Aber es bietet Ihnen die Werkzeuge, um einfache Webanwendungen zu erstellen, mit Routing basierend auf Pfaden, usw.
|
* Aber es bietet Ihnen die Werkzeuge, um einfache Webanwendungen zu erstellen, mit Routing basierend auf Pfaden, usw.
|
||||||
* Wenn Sie Starlette vergleichen, vergleichen Sie es mit Webframeworks (oder Mikroframeworks) wie Sanic, Flask, Django, usw.
|
* Wenn Sie Starlette vergleichen, vergleichen Sie es mit Webframeworks (oder Mikroframeworks) wie Sanic, Flask, Django, usw.
|
||||||
* **FastAPI**:
|
* **FastAPI**:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# FastAPI bei Cloudanbietern deployen { #deploy-fastapi-on-cloud-providers }
|
# FastAPI bei Cloudanbietern deployen { #deploy-fastapi-on-cloud-providers }
|
||||||
|
|
||||||
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung bereitzustellen.
|
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung zu deployen.
|
||||||
|
|
||||||
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Deployment von FastAPI an.
|
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Deployment von FastAPI an.
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Sie haben es eilig und kennen sich bereits aus? Springen Sie zum [`Dockerfile` u
|
|||||||
<summary>Dockerfile-Vorschau 👀</summary>
|
<summary>Dockerfile-Vorschau 👀</summary>
|
||||||
|
|
||||||
```Dockerfile
|
```Dockerfile
|
||||||
FROM python:3.9
|
FROM python:3.14
|
||||||
|
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
@@ -145,8 +145,6 @@ Es gibt andere Formate und Tools zum Definieren und Installieren von Paketabhän
|
|||||||
* Erstellen Sie eine `main.py`-Datei mit:
|
* Erstellen Sie eine `main.py`-Datei mit:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -158,7 +156,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: Union[str, None] = None):
|
def read_item(item_id: int, q: str | None = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -168,7 +166,7 @@ Erstellen Sie nun im selben Projektverzeichnis eine Datei `Dockerfile` mit:
|
|||||||
|
|
||||||
```{ .dockerfile .annotate }
|
```{ .dockerfile .annotate }
|
||||||
# (1)!
|
# (1)!
|
||||||
FROM python:3.9
|
FROM python:3.14
|
||||||
|
|
||||||
# (2)!
|
# (2)!
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
@@ -392,7 +390,7 @@ Wenn Ihr FastAPI eine einzelne Datei ist, zum Beispiel `main.py` ohne ein `./app
|
|||||||
Dann müssten Sie nur noch die entsprechenden Pfade ändern, um die Datei im `Dockerfile` zu kopieren:
|
Dann müssten Sie nur noch die entsprechenden Pfade ändern, um die Datei im `Dockerfile` zu kopieren:
|
||||||
|
|
||||||
```{ .dockerfile .annotate hl_lines="10 13" }
|
```{ .dockerfile .annotate hl_lines="10 13" }
|
||||||
FROM python:3.9
|
FROM python:3.14
|
||||||
|
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
@@ -456,7 +454,7 @@ Ohne die Verwendung von Containern kann es umständlich und schwierig sein, Anwe
|
|||||||
|
|
||||||
## Replikation – Anzahl der Prozesse { #replication-number-of-processes }
|
## Replikation – Anzahl der Prozesse { #replication-number-of-processes }
|
||||||
|
|
||||||
Wenn Sie einen <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und auf irgendeine Weise zusammenarbeiten.">Cluster</abbr> von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, möchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden.
|
Wenn Sie einen <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und auf irgendeine Weise zusammenarbeiten.">Cluster</dfn> von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, möchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden.
|
||||||
|
|
||||||
Diese verteilten Containerverwaltungssysteme wie Kubernetes verfügen normalerweise über eine integrierte Möglichkeit, die **Replikation von Containern** zu handhaben und gleichzeitig **Load Balancing** für die eingehenden <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zu unterstützen. Alles auf **Cluster-Ebene**.
|
Diese verteilten Containerverwaltungssysteme wie Kubernetes verfügen normalerweise über eine integrierte Möglichkeit, die **Replikation von Containern** zu handhaben und gleichzeitig **Load Balancing** für die eingehenden <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zu unterstützen. Alles auf **Cluster-Ebene**.
|
||||||
|
|
||||||
@@ -501,7 +499,7 @@ Natürlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit mehrer
|
|||||||
In diesen Fällen können Sie die `--workers` Befehlszeilenoption verwenden, um die Anzahl der zu startenden Worker festzulegen:
|
In diesen Fällen können Sie die `--workers` Befehlszeilenoption verwenden, um die Anzahl der zu startenden Worker festzulegen:
|
||||||
|
|
||||||
```{ .dockerfile .annotate }
|
```{ .dockerfile .annotate }
|
||||||
FROM python:3.9
|
FROM python:3.14
|
||||||
|
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
@@ -572,7 +570,7 @@ Wenn Sie ein einfaches Setup mit einem **einzelnen Container** haben, welcher da
|
|||||||
|
|
||||||
### Docker-Basisimage { #base-docker-image }
|
### Docker-Basisimage { #base-docker-image }
|
||||||
|
|
||||||
Es gab ein offizielles FastAPI-Docker-Image: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Dieses ist jedoch jetzt veraltet. ⛔️
|
Es gab ein offizielles FastAPI-Docker-Image: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Dieses ist jedoch jetzt deprecatet. ⛔️
|
||||||
|
|
||||||
Sie sollten wahrscheinlich **nicht** dieses Basis-Docker-Image (oder ein anderes ähnliches) verwenden.
|
Sie sollten wahrscheinlich **nicht** dieses Basis-Docker-Image (oder ein anderes ähnliches) verwenden.
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ Hier ist ein Beispiel, wie eine HTTPS-API aussehen könnte, Schritt für Schritt
|
|||||||
|
|
||||||
Alles beginnt wahrscheinlich damit, dass Sie einen **Domainnamen erwerben**. Anschließend konfigurieren Sie ihn in einem DNS-Server (wahrscheinlich beim selben Cloudanbieter).
|
Alles beginnt wahrscheinlich damit, dass Sie einen **Domainnamen erwerben**. Anschließend konfigurieren Sie ihn in einem DNS-Server (wahrscheinlich beim selben Cloudanbieter).
|
||||||
|
|
||||||
Sie würden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine <abbr title="Sie ändert sich nicht">feste</abbr> **öffentliche IP-Adresse**.
|
Sie würden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine <dfn title="Ändert sich im Laufe der Zeit nicht. Nicht dynamisch.">feste</dfn> **öffentliche IP-Adresse**.
|
||||||
|
|
||||||
In dem oder den DNS-Server(n) würden Sie einen Eintrag (einen „`A record`“) konfigurieren, um mit **Ihrer Domain** auf die öffentliche **IP-Adresse Ihres Servers** zu verweisen.
|
In dem oder den DNS-Server(n) würden Sie einen Eintrag (einen „`A record`“) konfigurieren, um mit **Ihrer Domain** auf die öffentliche **IP-Adresse Ihres Servers** zu verweisen.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Das Deployment einer **FastAPI**-Anwendung ist relativ einfach.
|
|||||||
|
|
||||||
## Was bedeutet Deployment { #what-does-deployment-mean }
|
## Was bedeutet Deployment { #what-does-deployment-mean }
|
||||||
|
|
||||||
<abbr title="Bereitstellen der Anwendung">**Deployment**</abbr> bedeutet, die notwendigen Schritte durchzuführen, um die Anwendung **für die Endbenutzer verfügbar** zu machen.
|
<abbr title="Bereitstellen der Anwendung">**Deployment**</abbr> bedeutet, die notwendigen Schritte durchzuführen, um die Anwendung **für die Benutzer verfügbar** zu machen.
|
||||||
|
|
||||||
Bei einer **Web-API** bedeutet das normalerweise, diese auf einem **entfernten Rechner** zu platzieren, mit einem **Serverprogramm**, welches gute Leistung, Stabilität, usw. bietet, damit Ihre **Benutzer** auf die Anwendung effizient und ohne Unterbrechungen oder Probleme **zugreifen** können.
|
Bei einer **Web-API** bedeutet das normalerweise, diese auf einem **entfernten Rechner** zu platzieren, mit einem **Serverprogramm**, welches gute Leistung, Stabilität, usw. bietet, damit Ihre **Benutzer** auf die Anwendung effizient und ohne Unterbrechungen oder Probleme **zugreifen** können.
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ In der Liste der Deployment-Konzepte von oben würde die Verwendung von Workern
|
|||||||
|
|
||||||
* **Sicherheit – HTTPS**
|
* **Sicherheit – HTTPS**
|
||||||
* **Beim Hochfahren ausführen**
|
* **Beim Hochfahren ausführen**
|
||||||
* **Neustarts**
|
* ***Neustarts***
|
||||||
* Replikation (die Anzahl der laufenden Prozesse)
|
* Replikation (die Anzahl der laufenden Prozesse)
|
||||||
* **Arbeitsspeicher**
|
* **Arbeitsspeicher**
|
||||||
* **Schritte vor dem Start**
|
* **Schritte vor dem Start**
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
### Basiert auf offenen Standards { #based-on-open-standards }
|
### Basiert auf offenen Standards { #based-on-open-standards }
|
||||||
|
|
||||||
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für die Erstellung von APIs, inklusive Deklarationen von <abbr title="auch bekannt als: Endpunkte, Routen">Pfad</abbr>-<abbr title="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</abbr>, Parametern, <abbr title="Anfragekörper">Requestbodys</abbr>, Sicherheit, usw.
|
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für die Erstellung von APIs, inklusive Deklarationen von <dfn title="auch bekannt als: Endpunkte, Routen">Pfad</dfn>-<dfn title="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</dfn>, Parametern, <abbr title="Anfragekörper">Requestbodys</abbr>, Sicherheit, usw.
|
||||||
* Automatische Dokumentation der Datenmodelle mit <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (da OpenAPI selbst auf JSON Schema basiert).
|
* Automatische Dokumentation der Datenmodelle mit <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (da OpenAPI selbst auf JSON Schema basiert).
|
||||||
* Um diese Standards herum entworfen, nach sorgfältigem Studium. Statt einer nachträglichen Schicht darüber.
|
* Um diese Standards herum entworfen, nach sorgfältigem Studium. Statt einer nachträglichen Schicht darüber.
|
||||||
* Dies ermöglicht auch automatische **Client-Code-Generierung** in vielen Sprachen.
|
* Dies ermöglicht auch automatische **Client-Code-Generierung** in vielen Sprachen.
|
||||||
@@ -136,7 +136,7 @@ Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in Ihre Sy
|
|||||||
|
|
||||||
### Dependency Injection { #dependency-injection }
|
### Dependency Injection { #dependency-injection }
|
||||||
|
|
||||||
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <abbr title='auch bekannt als „Komponenten“, „Resourcen“, „Dienste“, „Dienstanbieter“'><strong>Dependency Injection</strong></abbr> System.
|
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <dfn title='auch bekannt als: "Komponenten", "Resourcen", "Dienste", "Dienstanbieter"'><strong>Dependency Injection</strong></dfn> System.
|
||||||
|
|
||||||
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierarchie oder ein **„Graph“ von Abhängigkeiten** entsteht.
|
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierarchie oder ein **„Graph“ von Abhängigkeiten** entsteht.
|
||||||
* Alles **automatisch gehandhabt** durch das Framework.
|
* Alles **automatisch gehandhabt** durch das Framework.
|
||||||
@@ -153,8 +153,8 @@ Jede Integration wurde so entworfen, dass sie so einfach zu nutzen ist (mit Abh
|
|||||||
|
|
||||||
### Getestet { #tested }
|
### Getestet { #tested }
|
||||||
|
|
||||||
* 100 % <abbr title="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</abbr>.
|
* 100 % <dfn title="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</dfn>.
|
||||||
* 100 % <abbr title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</abbr>.
|
* 100 % <dfn title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</dfn>.
|
||||||
* Verwendet in Produktionsanwendungen.
|
* Verwendet in Produktionsanwendungen.
|
||||||
|
|
||||||
## Starlette Merkmale { #starlette-features }
|
## Starlette Merkmale { #starlette-features }
|
||||||
@@ -179,7 +179,7 @@ Mit **FastAPI** bekommen Sie alles von **Starlette** (da FastAPI nur Starlette a
|
|||||||
|
|
||||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Das bedeutet, wenn Sie eigenen Pydantic Quellcode haben, funktioniert der.
|
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Das bedeutet, wenn Sie eigenen Pydantic Quellcode haben, funktioniert der.
|
||||||
|
|
||||||
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbr title="Object-Relational Mapper – Objektrelationaler Abbilder">ORM</abbr>s, <abbr title="Object-Document Mapper – Objekt-Dokument-Abbilder">ODM</abbr>s für Datenbanken.
|
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbr title="Object-Relational Mapper - Objektrelationaler Mapper">ORM</abbr>s, <abbr title="Object-Document Mapper - Objekt-Dokument-Mapper">ODM</abbr>s für Datenbanken.
|
||||||
|
|
||||||
Daher können Sie in vielen Fällen das Objekt eines Requests **direkt zur Datenbank** schicken, weil alles automatisch validiert wird.
|
Daher können Sie in vielen Fällen das Objekt eines Requests **direkt zur Datenbank** schicken, weil alles automatisch validiert wird.
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für d
|
|||||||
* **Kein Kopfzerbrechen**:
|
* **Kein Kopfzerbrechen**:
|
||||||
* Keine neue Schemadefinition-Mikrosprache zu lernen.
|
* Keine neue Schemadefinition-Mikrosprache zu lernen.
|
||||||
* Wenn Sie Pythons Typen kennen, wissen Sie, wie man Pydantic verwendet.
|
* Wenn Sie Pythons Typen kennen, wissen Sie, wie man Pydantic verwendet.
|
||||||
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrated Development Environment – Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<abbr title="Ein Programm, das Fehler im Quellcode sucht">Linter</abbr>/Gehirn**:
|
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrated Development Environment - Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<dfn title="Ein Programm, das Fehler im Quellcode sucht">Linter</dfn>/Gehirn**:
|
||||||
* Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und Ihre Intuition sollten alle einwandfrei mit Ihren validierten Daten funktionieren.
|
* Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und Ihre Intuition sollten alle einwandfrei mit Ihren validierten Daten funktionieren.
|
||||||
* Validierung von **komplexen Strukturen**:
|
* Validierung von **komplexen Strukturen**:
|
||||||
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, etc.
|
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, etc.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich <a href
|
|||||||
|
|
||||||
Dann habe ich zu dessen Code beigetragen, um es vollständig mit JSON Schema kompatibel zu machen, und so verschiedene Möglichkeiten zum Definieren von einschränkenden Deklarationen (Constraints) zu unterstützen, und die Editorunterstützung (Typprüfungen, Codevervollständigung) zu verbessern, basierend auf den Tests in mehreren Editoren.
|
Dann habe ich zu dessen Code beigetragen, um es vollständig mit JSON Schema kompatibel zu machen, und so verschiedene Möglichkeiten zum Definieren von einschränkenden Deklarationen (Constraints) zu unterstützen, und die Editorunterstützung (Typprüfungen, Codevervollständigung) zu verbessern, basierend auf den Tests in mehreren Editoren.
|
||||||
|
|
||||||
Während der Entwicklung habe ich auch zu <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a> beigetragen, der anderen Schlüsselanforderung.
|
Während der Entwicklung habe ich auch zu <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a> beigetragen, die andere Schlüsselanforderung.
|
||||||
|
|
||||||
## Entwicklung { #development }
|
## Entwicklung { #development }
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Aber falls Ihre Clients aus irgendeinem Grund vom alten Verhalten abhängen, kö
|
|||||||
|
|
||||||
Sie können beispielsweise eine Unterklasse von `HTTPBearer` erstellen, die einen Fehler `403 Forbidden` zurückgibt, statt des Default-`401 Unauthorized`-Fehlers:
|
Sie können beispielsweise eine Unterklasse von `HTTPBearer` erstellen, die einen Fehler `403 Forbidden` zurückgibt, statt des Default-`401 Unauthorized`-Fehlers:
|
||||||
|
|
||||||
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
|
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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_py310.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. 🤓
|
|
||||||
|
|||||||
+25
-25
@@ -40,7 +40,7 @@ Seine Schlüssel-Merkmale sind:
|
|||||||
* **Schnell**: Sehr hohe Performanz, auf Augenhöhe mit **NodeJS** und **Go** (dank Starlette und Pydantic). [Eines der schnellsten verfügbaren Python-Frameworks](#performance).
|
* **Schnell**: Sehr hohe Performanz, auf Augenhöhe mit **NodeJS** und **Go** (dank Starlette und Pydantic). [Eines der schnellsten verfügbaren Python-Frameworks](#performance).
|
||||||
* **Schnell zu entwickeln**: Erhöhen Sie die Geschwindigkeit bei der Entwicklung von Features um etwa 200 % bis 300 %. *
|
* **Schnell zu entwickeln**: Erhöhen Sie die Geschwindigkeit bei der Entwicklung von Features um etwa 200 % bis 300 %. *
|
||||||
* **Weniger Bugs**: Verringern Sie die von Menschen (Entwicklern) verursachten Fehler um etwa 40 %. *
|
* **Weniger Bugs**: Verringern Sie die von Menschen (Entwicklern) verursachten Fehler um etwa 40 %. *
|
||||||
* **Intuitiv**: Hervorragende Editor-Unterstützung. <abbr title="auch bekannt als Auto-Complete, Autovervollständigung, IntelliSense">Code-Vervollständigung</abbr> überall. Weniger Zeit mit Debuggen verbringen.
|
* **Intuitiv**: Hervorragende Editor-Unterstützung. <dfn title="auch bekannt als Auto-Complete, Autovervollständigung, IntelliSense">Code-Vervollständigung</dfn> überall. Weniger Zeit mit Debuggen verbringen.
|
||||||
* **Einfach**: So konzipiert, dass es einfach zu benutzen und zu erlernen ist. Weniger Zeit mit dem Lesen von Dokumentation verbringen.
|
* **Einfach**: So konzipiert, dass es einfach zu benutzen und zu erlernen ist. Weniger Zeit mit dem Lesen von Dokumentation verbringen.
|
||||||
* **Kurz**: Minimieren Sie die Verdoppelung von Code. Mehrere Features aus jeder Parameterdeklaration. Weniger Bugs.
|
* **Kurz**: Minimieren Sie die Verdoppelung von Code. Mehrere Features aus jeder Parameterdeklaration. Weniger Bugs.
|
||||||
* **Robust**: Erhalten Sie produktionsreifen Code. Mit automatischer, interaktiver Dokumentation.
|
* **Robust**: Erhalten Sie produktionsreifen Code. Mit automatischer, interaktiver Dokumentation.
|
||||||
@@ -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>
|
||||||
@@ -155,8 +161,6 @@ $ pip install "fastapi[standard]"
|
|||||||
Erstellen Sie eine Datei `main.py` mit:
|
Erstellen Sie eine Datei `main.py` mit:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -168,7 +172,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: Union[str, None] = None):
|
def read_item(item_id: int, q: str | None = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -177,9 +181,7 @@ def read_item(item_id: int, q: Union[str, None] = None):
|
|||||||
|
|
||||||
Wenn Ihr Code `async` / `await` verwendet, benutzen Sie `async def`:
|
Wenn Ihr Code `async` / `await` verwendet, benutzen Sie `async def`:
|
||||||
|
|
||||||
```Python hl_lines="9 14"
|
```Python hl_lines="7 12"
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -191,7 +193,7 @@ async def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
async def read_item(item_id: int, q: str | None = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -233,7 +235,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,15 +278,13 @@ 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.
|
||||||
|
|
||||||
Deklarieren Sie den Body mit Standard-Python-Typen, dank Pydantic.
|
Deklarieren Sie den Body mit Standard-Python-Typen, dank Pydantic.
|
||||||
|
|
||||||
```Python hl_lines="4 9-12 25-27"
|
```Python hl_lines="2 7-10 23-25"
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ app = FastAPI()
|
|||||||
class Item(BaseModel):
|
class Item(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
price: float
|
price: float
|
||||||
is_offer: Union[bool, None] = None
|
is_offer: bool | None = None
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -303,7 +303,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: Union[str, None] = None):
|
def read_item(item_id: int, q: str | None = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
|
|
||||||
|
|
||||||
@@ -326,7 +326,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:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -363,12 +363,12 @@ item: Item
|
|||||||
... und mit dieser einen Deklaration erhalten Sie:
|
... und mit dieser einen Deklaration erhalten Sie:
|
||||||
|
|
||||||
* Editor-Unterstützung, einschließlich:
|
* Editor-Unterstützung, einschließlich:
|
||||||
* Code-Vervollständigung.
|
* Vervollständigung.
|
||||||
* Typprüfungen.
|
* Typprüfungen.
|
||||||
* Validierung von Daten:
|
* Validierung von Daten:
|
||||||
* Automatische und eindeutige Fehler, wenn die Daten ungültig sind.
|
* Automatische und eindeutige Fehler, wenn die Daten ungültig sind.
|
||||||
* Validierung sogar für tief verschachtelte JSON-Objekte.
|
* Validierung sogar für tief verschachtelte JSON-Objekte.
|
||||||
* <abbr title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</abbr> von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von:
|
* <dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</dfn> von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von:
|
||||||
* JSON.
|
* JSON.
|
||||||
* Pfad-Parametern.
|
* Pfad-Parametern.
|
||||||
* Query-Parametern.
|
* Query-Parametern.
|
||||||
@@ -376,7 +376,7 @@ item: Item
|
|||||||
* Headern.
|
* Headern.
|
||||||
* Formularen.
|
* Formularen.
|
||||||
* Dateien.
|
* Dateien.
|
||||||
* <abbr title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</abbr> von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON):
|
* <dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</dfn> von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON):
|
||||||
* Konvertieren von Python-Typen (`str`, `int`, `float`, `bool`, `list`, usw.).
|
* Konvertieren von Python-Typen (`str`, `int`, `float`, `bool`, `list`, usw.).
|
||||||
* `datetime`-Objekte.
|
* `datetime`-Objekte.
|
||||||
* `UUID`-Objekte.
|
* `UUID`-Objekte.
|
||||||
@@ -439,7 +439,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 **<dfn title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</dfn>**.
|
||||||
* 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 +452,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 +494,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 }
|
||||||
|
|
||||||
@@ -524,7 +524,7 @@ Verwendet von Starlette:
|
|||||||
|
|
||||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> – erforderlich, wenn Sie den `TestClient` verwenden möchten.
|
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> – erforderlich, wenn Sie den `TestClient` verwenden möchten.
|
||||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> – erforderlich, wenn Sie die Default-Template-Konfiguration verwenden möchten.
|
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> – erforderlich, wenn Sie die Default-Template-Konfiguration verwenden möchten.
|
||||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> – erforderlich, wenn Sie Formulare mittels `request.form()` <abbr title="Konvertieren des Strings, der aus einem HTTP-Request stammt, nach Python-Daten">„parsen“</abbr> möchten.
|
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> – erforderlich, wenn Sie Formulare mittels `request.form()` <dfn title="Konvertieren des Strings, der aus einem HTTP-Request stammt, nach Python-Daten">„parsen“</dfn> möchten.
|
||||||
|
|
||||||
Verwendet von FastAPI:
|
Verwendet von FastAPI:
|
||||||
|
|
||||||
|
|||||||
@@ -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)-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.
|
||||||
|
|||||||
+40
-268
@@ -1,8 +1,8 @@
|
|||||||
# Einführung in Python-Typen { #python-types-intro }
|
# Einführung in Python-Typen { #python-types-intro }
|
||||||
|
|
||||||
Python hat Unterstützung für optionale <abbr title="englisch: Type hints">„Typhinweise“</abbr> (auch <abbr title="englisch: Type annotations">„Typannotationen“</abbr> genannt).
|
Python hat Unterstützung für optionale „Typhinweise“ (auch „Typannotationen“ genannt).
|
||||||
|
|
||||||
Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den <abbr title="zum Beispiel: str, int, float, bool">Typ</abbr> einer Variablen zu deklarieren.
|
Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den <dfn title="zum Beispiel: str, int, float, bool">Typ</dfn> einer Variablen zu deklarieren.
|
||||||
|
|
||||||
Durch das Deklarieren von Typen für Ihre Variablen können Editoren und Tools bessere Unterstützung bieten.
|
Durch das Deklarieren von Typen für Ihre Variablen können Editoren und Tools bessere Unterstützung bieten.
|
||||||
|
|
||||||
@@ -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_py310.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.
|
* <dfn title="Fügt sie zu einer Einheit zusammen. Mit dem Inhalt des einen nach dem anderen.">Verkettet</dfn> sie mit einem Leerzeichen in der Mitte.
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
|
{* ../../docs_src/python_types/tutorial001_py310.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_py310.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_py310.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_py310.py hl[2] *}
|
||||||
|
|
||||||
## Deklarieren von Typen { #declaring-types }
|
## Deklarieren von Typen { #declaring-types }
|
||||||
|
|
||||||
@@ -133,84 +133,55 @@ Zum Beispiel diese:
|
|||||||
* `bool`
|
* `bool`
|
||||||
* `bytes`
|
* `bytes`
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
|
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
|
||||||
|
|
||||||
### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters }
|
### `typing`-Modul { #typing-module }
|
||||||
|
|
||||||
Es gibt Datenstrukturen, die andere Werte enthalten können, wie etwa `dict`, `list`, `set` und `tuple`. Die inneren Werte können auch ihren eigenen Typ haben.
|
Für einige zusätzliche Anwendungsfälle müssen Sie möglicherweise Dinge aus dem Standardmodul `typing` importieren. Zum Beispiel, wenn Sie deklarieren möchten, dass etwas „jeden Typ“ haben kann, können Sie `Any` aus `typing` verwenden:
|
||||||
|
|
||||||
Diese Typen mit inneren Typen werden „**generische**“ Typen genannt. Es ist möglich, sie mit ihren inneren Typen zu deklarieren.
|
```python
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
Um diese Typen und die inneren Typen zu deklarieren, können Sie Pythons Standardmodul `typing` verwenden. Es existiert speziell für die Unterstützung dieser Typhinweise.
|
|
||||||
|
|
||||||
#### Neuere Python-Versionen { #newer-versions-of-python }
|
def some_function(data: Any):
|
||||||
|
print(data)
|
||||||
|
```
|
||||||
|
|
||||||
Die Syntax, welche `typing` verwendet, ist **kompatibel** mit allen Versionen, von Python 3.6 aufwärts zu den neuesten, inklusive Python 3.9, Python 3.10, usw.
|
### Generische Typen { #generic-types }
|
||||||
|
|
||||||
Mit der Weiterentwicklung von Python kommen **neuere Versionen** heraus, mit verbesserter Unterstützung für Typannotationen, und in vielen Fällen müssen Sie gar nicht mehr das `typing`-Modul importieren, um Typannotationen zu schreiben.
|
Einige Typen können „Typ-Parameter“ in eckigen Klammern annehmen, um ihre inneren Typen zu definieren, z. B. eine „Liste von Strings“ würde als `list[str]` deklariert.
|
||||||
|
|
||||||
Wenn Sie eine neuere Python-Version für Ihr Projekt wählen können, werden Sie aus dieser zusätzlichen Vereinfachung Nutzen ziehen können.
|
Diese Typen, die Typ-Parameter annehmen können, werden **generische Typen** oder **Generics** genannt.
|
||||||
|
|
||||||
In der gesamten Dokumentation gibt es Beispiele, welche kompatibel mit unterschiedlichen Python-Versionen sind (wenn es Unterschiede gibt).
|
Sie können dieselben eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
|
||||||
|
|
||||||
Zum Beispiel bedeutet „**Python 3.6+**“, dass das Beispiel kompatibel mit Python 3.6 oder höher ist (inklusive 3.7, 3.8, 3.9, 3.10, usw.). Und „**Python 3.9+**“ bedeutet, es ist kompatibel mit Python 3.9 oder höher (inklusive 3.10, usw.).
|
* `list`
|
||||||
|
* `tuple`
|
||||||
Wenn Sie über die **neueste Version von Python** verfügen, verwenden Sie die Beispiele für die neueste Version, diese werden die **beste und einfachste Syntax** haben, zum Beispiel, „**Python 3.10+**“.
|
* `set`
|
||||||
|
* `dict`
|
||||||
|
|
||||||
#### Liste { #list }
|
#### Liste { #list }
|
||||||
|
|
||||||
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_py310.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 +196,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_py310.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 +211,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_py310.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:
|
||||||
|
|
||||||
@@ -276,47 +219,23 @@ Das bedeutet:
|
|||||||
* Die Schlüssel dieses `dict` sind vom Typ `str` (z. B. die Namen der einzelnen Artikel).
|
* Die Schlüssel dieses `dict` sind vom Typ `str` (z. B. die Namen der einzelnen Artikel).
|
||||||
* Die Werte dieses `dict` sind vom Typ `float` (z. B. der Preis jedes Artikels).
|
* Die Werte dieses `dict` sind vom Typ `float` (z. B. der Preis jedes Artikels).
|
||||||
|
|
||||||
#### <abbr title="Union – Verbund, Einheit‚ Vereinigung: Eines von Mehreren">Union</abbr> { #union }
|
#### Union { #union }
|
||||||
|
|
||||||
Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** sein kann, zum Beispiel ein `int` oder ein `str`.
|
Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** sein kann, zum Beispiel ein `int` oder ein `str`.
|
||||||
|
|
||||||
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.
|
Um das zu definieren, verwenden Sie den <dfn title="auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant">vertikalen Balken (`|`)</dfn>, um beide Typen zu trennen.
|
||||||
|
|
||||||
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.
|
Das wird „Union“ genannt, weil die Variable etwas aus der Vereinigung dieser beiden Typmengen sein kann.
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
|
||||||
|
|
||||||
```Python hl_lines="1"
|
```Python hl_lines="1"
|
||||||
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
||||||
```
|
```
|
||||||
|
|
||||||
////
|
Das bedeutet, dass `item` ein `int` oder ein `str` sein könnte.
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
|
||||||
{!> ../../docs_src/python_types/tutorial008b.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
In beiden Fällen bedeutet das, dass `item` ein `int` oder ein `str` sein kann.
|
|
||||||
|
|
||||||
#### Vielleicht `None` { #possibly-none }
|
#### Vielleicht `None` { #possibly-none }
|
||||||
|
|
||||||
Sie können deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` sein kann.
|
Sie können deklarieren, dass ein Wert einen Typ haben könnte, wie `str`, dass er aber auch `None` sein könnte.
|
||||||
|
|
||||||
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"
|
|
||||||
{!../../docs_src/python_types/tutorial009.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein könnte.
|
|
||||||
|
|
||||||
`Optional[Something]` ist tatsächlich eine Abkürzung für `Union[Something, None]`, diese beiden sind äquivalent.
|
|
||||||
|
|
||||||
Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
|
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
//// tab | Python 3.10+
|
||||||
|
|
||||||
@@ -326,108 +245,7 @@ Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
Wenn Sie `str | None` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer ein `str` ist, obwohl er auch `None` sein könnte.
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
|
||||||
{!> ../../docs_src/python_types/tutorial009.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+ Alternative
|
|
||||||
|
|
||||||
```Python hl_lines="1 4"
|
|
||||||
{!> ../../docs_src/python_types/tutorial009b.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
#### `Union` oder `Optional` verwenden? { #using-union-or-optional }
|
|
||||||
|
|
||||||
Wenn Sie eine Python-Version unterhalb 3.10 verwenden, hier ist mein sehr **subjektiver** Standpunkt dazu:
|
|
||||||
|
|
||||||
* 🚨 Vermeiden Sie `Optional[SomeType]`
|
|
||||||
* Stattdessen ✨ **verwenden Sie `Union[SomeType, None]`** ✨.
|
|
||||||
|
|
||||||
Beide sind äquivalent und im Hintergrund dasselbe, aber ich empfehle `Union` statt `Optional`, weil das Wort „**optional**“ impliziert, dass dieser Wert, zum Beispiel als Funktionsparameter, optional ist. Tatsächlich bedeutet es aber nur „Der Wert kann `None` sein“, selbst wenn der Wert nicht optional ist und benötigt wird.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Nehmen wir zum Beispiel diese Funktion:
|
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial009c.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:
|
|
||||||
|
|
||||||
```Python
|
|
||||||
say_hi() # Oh, nein, das löst einen Fehler aus! 😱
|
|
||||||
```
|
|
||||||
|
|
||||||
Der `name` Parameter wird **immer noch benötigt** (nicht *optional*), weil er keinen Default-Wert hat. `name` akzeptiert aber dennoch `None` als Wert:
|
|
||||||
|
|
||||||
```Python
|
|
||||||
say_hi(name=None) # Das funktioniert, None ist gültig 🎉
|
|
||||||
```
|
|
||||||
|
|
||||||
Die gute Nachricht ist, dass Sie sich darüber keine Sorgen mehr machen müssen, wenn Sie Python 3.10 verwenden, da Sie einfach `|` verwenden können, um Vereinigungen von Typen zu definieren:
|
|
||||||
|
|
||||||
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
|
|
||||||
|
|
||||||
Und dann müssen Sie sich nicht mehr um Namen wie `Optional` und `Union` kümmern. 😎
|
|
||||||
|
|
||||||
#### Generische Typen { #generic-types }
|
|
||||||
|
|
||||||
Diese Typen, die Typ-Parameter in eckigen Klammern akzeptieren, werden **generische Typen** oder **Generics** genannt.
|
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
|
||||||
|
|
||||||
Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
|
|
||||||
|
|
||||||
* `list`
|
|
||||||
* `tuple`
|
|
||||||
* `set`
|
|
||||||
* `dict`
|
|
||||||
|
|
||||||
Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
|
||||||
|
|
||||||
* `Union`
|
|
||||||
* `Optional` (so wie unter Python 3.8)
|
|
||||||
* ... 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.
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
|
||||||
|
|
||||||
Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
|
|
||||||
|
|
||||||
* `list`
|
|
||||||
* `tuple`
|
|
||||||
* `set`
|
|
||||||
* `dict`
|
|
||||||
|
|
||||||
Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
|
||||||
|
|
||||||
* `Union`
|
|
||||||
* `Optional`
|
|
||||||
* ... und andere.
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
//// tab | Python 3.8+
|
|
||||||
|
|
||||||
* `List`
|
|
||||||
* `Tuple`
|
|
||||||
* `Set`
|
|
||||||
* `Dict`
|
|
||||||
* `Union`
|
|
||||||
* `Optional`
|
|
||||||
* ... und andere.
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
### Klassen als Typen { #classes-as-types }
|
### Klassen als Typen { #classes-as-types }
|
||||||
|
|
||||||
@@ -435,11 +253,11 @@ 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_py310.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_py310.py hl[6] *}
|
||||||
|
|
||||||
Und wiederum bekommen Sie die volle Editor-Unterstützung:
|
Und wiederum bekommen Sie die volle Editor-Unterstützung:
|
||||||
|
|
||||||
@@ -463,29 +281,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
|
||||||
|
|
||||||
@@ -497,37 +293,13 @@ Um mehr über <a href="https://docs.pydantic.dev/" class="external-link" target=
|
|||||||
|
|
||||||
Viel mehr von all dem werden Sie in praktischer Anwendung im [Tutorial – Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank} sehen.
|
Viel mehr von all dem werden Sie in praktischer Anwendung im [Tutorial – Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank} sehen.
|
||||||
|
|
||||||
/// tip | Tipp
|
|
||||||
|
|
||||||
Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None]` ohne einen Defaultwert verwenden. Sie können darüber in der Pydantic Dokumentation unter <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Erforderliche optionale Felder</a> mehr erfahren.
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
## Typhinweise mit Metadaten-Annotationen { #type-hints-with-metadata-annotations }
|
## Typhinweise mit Metadaten-Annotationen { #type-hints-with-metadata-annotations }
|
||||||
|
|
||||||
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 <dfn title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</dfn>** in Typhinweisen unterzubringen, mittels `Annotated`.
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
Sie können `Annotated` 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_py310.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. ✈️
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/// details | 🌐 Übersetzung durch KI und Menschen
|
||||||
|
|
||||||
|
Diese Übersetzung wurde von KI erstellt, angeleitet von Menschen. 🤝
|
||||||
|
|
||||||
|
Sie könnte Fehler enthalten, etwa Missverständnisse des ursprünglichen Sinns oder unnatürliche Formulierungen, usw. 🤖
|
||||||
|
|
||||||
|
Sie können diese Übersetzung verbessern, indem Sie [uns helfen, die KI-LLM besser anzuleiten](https://fastapi.tiangolo.com/de/contributing/#translations).
|
||||||
|
|
||||||
|
[Englische Version](ENGLISH_VERSION_URL)
|
||||||
|
|
||||||
|
///
|
||||||
@@ -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_py310.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_py310.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_py310.py hl[14] *}
|
||||||
|
|
||||||
`.add_task()` erhält als Argumente:
|
`.add_task()` erhält als Argumente:
|
||||||
|
|
||||||
|
|||||||
@@ -56,19 +56,19 @@ from app.routers import items
|
|||||||
|
|
||||||
Die gleiche Dateistruktur mit Kommentaren:
|
Die gleiche Dateistruktur mit Kommentaren:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
.
|
.
|
||||||
├── app # „app“ ist ein Python-Package
|
├── app # "app" ist ein Python-Package
|
||||||
│ ├── __init__.py # diese Datei macht „app“ zu einem „Python-Package“
|
│ ├── __init__.py # diese Datei macht "app" zu einem "Python-Package"
|
||||||
│ ├── main.py # „main“-Modul, z. B. import app.main
|
│ ├── main.py # "main"-Modul, z. B. import app.main
|
||||||
│ ├── dependencies.py # „dependencies“-Modul, z. B. import app.dependencies
|
│ ├── dependencies.py # "dependencies"-Modul, z. B. import app.dependencies
|
||||||
│ └── routers # „routers“ ist ein „Python-Subpackage“
|
│ └── routers # "routers" ist ein "Python-Subpackage"
|
||||||
│ │ ├── __init__.py # macht „routers“ zu einem „Python-Subpackage“
|
│ │ ├── __init__.py # macht "routers" zu einem "Python-Subpackage"
|
||||||
│ │ ├── items.py # „items“-Submodul, z. B. import app.routers.items
|
│ │ ├── items.py # "items"-Submodul, z. B. import app.routers.items
|
||||||
│ │ └── users.py # „users“-Submodul, z. B. import app.routers.users
|
│ │ └── users.py # "users"-Submodul, z. B. import app.routers.users
|
||||||
│ └── internal # „internal“ ist ein „Python-Subpackage“
|
│ └── internal # "internal" ist ein "Python-Subpackage"
|
||||||
│ ├── __init__.py # macht „internal“ zu einem „Python-Subpackage“
|
│ ├── __init__.py # macht "internal" zu einem "Python-Subpackage"
|
||||||
│ └── admin.py # „admin“-Submodul, z. B. import app.internal.admin
|
│ └── admin.py # "admin"-Submodul, z. B. import app.internal.admin
|
||||||
```
|
```
|
||||||
|
|
||||||
## `APIRouter` { #apirouter }
|
## `APIRouter` { #apirouter }
|
||||||
@@ -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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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_py310/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.
|
||||||
|
|
||||||
@@ -531,7 +479,7 @@ $ fastapi dev app/main.py
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
Und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||||
|
|
||||||
Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Submodule, mit den richtigen Pfaden (und Präfixen) und den richtigen Tags:
|
Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Submodule, mit den richtigen Pfaden (und Präfixen) und den richtigen Tags:
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Beachten Sie, wie jedes Attribut eines Modells mit einem Typ, Defaultwert und `F
|
|||||||
|
|
||||||
Sie können zusätzliche Information in `Field`, `Query`, `Body`, usw. deklarieren. Und es wird im generierten JSON-Schema untergebracht.
|
Sie können zusätzliche Information in `Field`, `Query`, `Body`, usw. deklarieren. Und es wird im generierten JSON-Schema untergebracht.
|
||||||
|
|
||||||
Sie werden später mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren.
|
Sie werden später in der Dokumentation mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren.
|
||||||
|
|
||||||
/// warning | Achtung
|
/// warning | Achtung
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Body – Mehrere Parameter { #body-multiple-parameters }
|
# Body – Mehrere Parameter { #body-multiple-parameters }
|
||||||
|
|
||||||
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbr title="Anfragekörper">Requestbody</abbr>-Deklarationen an.
|
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbr title="Requestbody">Requestbody</abbr>-Deklarationen an.
|
||||||
|
|
||||||
## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters }
|
## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters }
|
||||||
|
|
||||||
@@ -100,12 +100,6 @@ Natürlich können Sie auch, wann immer Sie das brauchen, weitere Query-Paramete
|
|||||||
|
|
||||||
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben:
|
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben:
|
||||||
|
|
||||||
```Python
|
|
||||||
q: Union[str, None] = None
|
|
||||||
```
|
|
||||||
|
|
||||||
Oder in Python 3.10 und darüber:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
q: str | None = None
|
q: str | None = None
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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,19 +157,13 @@ 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]
|
||||||
```
|
```
|
||||||
|
|
||||||
so wie in:
|
so wie in:
|
||||||
|
|
||||||
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
|
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
|
||||||
|
|
||||||
## Editor-Unterstützung überall { #editor-support-everywhere }
|
## Editor-Unterstützung überall { #editor-support-everywhere }
|
||||||
|
|
||||||
@@ -220,7 +193,7 @@ Das schauen wir uns mal an.
|
|||||||
|
|
||||||
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat:
|
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat:
|
||||||
|
|
||||||
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
|
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -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` 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.
|
||||||
|
|
||||||
|
|||||||
@@ -46,17 +46,17 @@ Aber selbst wenn Sie die **Daten ausfüllen** und auf „Ausführen“ klicken,
|
|||||||
|
|
||||||
In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) möchten Sie möglicherweise die Cookies, die Sie empfangen möchten, **einschränken**.
|
In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) möchten Sie möglicherweise die Cookies, die Sie empfangen möchten, **einschränken**.
|
||||||
|
|
||||||
Ihre API hat jetzt die Macht, ihre eigene <abbr title="Das ist ein Scherz, nur für den Fall. Es hat nichts mit Cookie-Einwilligungen zu tun, aber es ist witzig, dass selbst die API jetzt die armen Cookies ablehnen kann. Haben Sie einen Keks. 🍪">Cookie-Einwilligung</abbr> zu kontrollieren. 🤪🍪
|
Ihre API hat jetzt die Macht, ihre eigene <dfn title="Das ist ein Scherz, nur für den Fall. Es hat nichts mit Cookie-Einwilligungen zu tun, aber es ist witzig, dass selbst die API jetzt die armen Cookies ablehnen kann. Haben Sie einen Keks. 🍪">Cookie-Einwilligung</dfn> zu kontrollieren. 🤪🍪
|
||||||
|
|
||||||
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>**.
|
||||||
|
|
||||||
Arme Cookie-Banner, wie sie sich mühen, Ihre Einwilligung zu erhalten, dass die <abbr title="Das ist ein weiterer Scherz. Beachten Sie mich nicht. Trinken Sie einen Kaffee zu Ihrem Keks. ☕">API sie ablehnen darf</abbr>. 🍪
|
Arme Cookie-Banner, wie sie sich mühen, Ihre Einwilligung zu erhalten, dass die <dfn title="Das ist ein weiterer Scherz. Beachten Sie mich nicht. Trinken Sie einen Kaffee zu Ihrem Keks. ☕">API sie ablehnen darf</dfn>. 🍪
|
||||||
|
|
||||||
Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` <abbr title="Santa beschwert sich über den Mangel an Cookies. 🎅 Okay, keine Cookie-Witze mehr.">Cookie nicht erlaubt ist</abbr>:
|
Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` <dfn title="Santa missbilligt den Mangel an Cookies. 🎅 Okay, keine Cookie-Witze mehr.">Cookie nicht erlaubt ist</dfn>:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -73,4 +73,4 @@ Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem We
|
|||||||
|
|
||||||
## Zusammenfassung { #summary }
|
## Zusammenfassung { #summary }
|
||||||
|
|
||||||
Sie können **Pydantic-Modelle** verwenden, um <abbr title="Nehmen Sie einen letzten Keks, bevor Sie gehen. 🍪">**Cookies**</abbr> in **FastAPI** zu deklarieren. 😎
|
Sie können **Pydantic-Modelle** verwenden, um <dfn title="Nehmen Sie einen letzten Keks, bevor Sie gehen. 🍪">**Cookies**</dfn> in **FastAPI** zu deklarieren. 😎
|
||||||
|
|||||||
@@ -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_py310.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_py310.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.10+
|
||||||
|
|
||||||
```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.10+ 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.10+
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
commons: Annotated[CommonQueryParams, ...
|
commons: Annotated[CommonQueryParams, ...
|
||||||
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
|
|||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
//// tab | Python 3.8+ nicht annotiert
|
//// tab | Python 3.10+ 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.10+
|
||||||
|
|
||||||
```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.10+ 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.10+
|
||||||
|
|
||||||
```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.10+ 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.10+
|
||||||
|
|
||||||
```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.10+ 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.10+
|
||||||
|
|
||||||
```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.10+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ Oder die Abhängigkeit gibt keinen Wert zurück.
|
|||||||
|
|
||||||
Aber Sie müssen sie trotzdem ausführen/auflösen.
|
Aber Sie müssen sie trotzdem ausführen/auflösen.
|
||||||
|
|
||||||
In diesen Fällen können Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list`e von `dependencies` zum *Pfadoperation-Dekorator* hinzufügen.
|
In diesen Fällen können Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list` von `dependencies` zum *Pfadoperation-Dekorator* hinzufügen.
|
||||||
|
|
||||||
## `dependencies` zum *Pfadoperation-Dekorator* hinzufügen { #add-dependencies-to-the-path-operation-decorator }
|
## `dependencies` zum *Pfadoperation-Dekorator* hinzufügen { #add-dependencies-to-the-path-operation-decorator }
|
||||||
|
|
||||||
Der *Pfadoperation-Dekorator* erhält ein optionales Argument `dependencies`.
|
Der *Pfadoperation-Dekorator* erhält ein optionales Argument `dependencies`.
|
||||||
|
|
||||||
Es sollte eine `list`e von `Depends()` sein:
|
Es sollte eine `list` von `Depends()` sein:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
|
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
|
||||||
|
|
||||||
Diese Abhängigkeiten werden auf die gleiche Weise wie normale Abhängigkeiten ausgeführt/aufgelöst. Aber ihr Wert (falls sie einen zurückgeben) wird nicht an Ihre *Pfadoperation-Funktion* übergeben.
|
Diese Abhängigkeiten werden auf die gleiche Weise wie normale Abhängigkeiten ausgeführt/aufgelöst. Aber ihr Wert (falls sie einen zurückgeben) wird nicht an Ihre *Pfadoperation-Funktion* übergeben.
|
||||||
|
|
||||||
@@ -44,13 +44,13 @@ Sie können dieselben Abhängigkeits-*Funktionen* verwenden, die Sie normalerwei
|
|||||||
|
|
||||||
Sie können Anforderungen für einen <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> (wie Header) oder andere Unterabhängigkeiten deklarieren:
|
Sie können Anforderungen für einen <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> (wie Header) oder andere Unterabhängigkeiten deklarieren:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
|
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
|
||||||
|
|
||||||
### Exceptions auslösen { #raise-exceptions }
|
### Exceptions auslösen { #raise-exceptions }
|
||||||
|
|
||||||
Die Abhängigkeiten können Exceptions `raise`n, genau wie normale Abhängigkeiten:
|
Die Abhängigkeiten können Exceptions `raise`n, genau wie normale Abhängigkeiten:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
|
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
|
||||||
|
|
||||||
### Rückgabewerte { #return-values }
|
### Rückgabewerte { #return-values }
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ Und sie können Werte zurückgeben oder nicht, die Werte werden nicht verwendet.
|
|||||||
|
|
||||||
Sie können also eine normale Abhängigkeit (die einen Wert zurückgibt), die Sie bereits an anderer Stelle verwenden, wiederverwenden, und auch wenn der Wert nicht verwendet wird, wird die Abhängigkeit ausgeführt:
|
Sie können also eine normale Abhängigkeit (die einen Wert zurückgibt), die Sie bereits an anderer Stelle verwenden, wiederverwenden, und auch wenn der Wert nicht verwendet wird, wird die Abhängigkeit ausgeführt:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
|
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
|
||||||
|
|
||||||
## Abhängigkeiten für eine Gruppe von *Pfadoperationen* { #dependencies-for-a-group-of-path-operations }
|
## Abhängigkeiten für eine Gruppe von *Pfadoperationen* { #dependencies-for-a-group-of-path-operations }
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Abhängigkeiten mit `yield` { #dependencies-with-yield }
|
# Abhängigkeiten mit `yield` { #dependencies-with-yield }
|
||||||
|
|
||||||
FastAPI unterstützt Abhängigkeiten, die nach Abschluss einige <abbr title="Manchmal auch genannt „Exit Code“, „Cleanup Code“, „Teardown Code“, „Closing Code“, „Kontextmanager Exit Code“, usw.">zusätzliche Schritte ausführen</abbr>.
|
FastAPI unterstützt Abhängigkeiten, die einige <dfn title="manchmal auch genannt: „Exit Code“, „Cleanup Code“, „Teardown Code“, „Closing Code“, „Kontextmanager Exit Code“, usw.">zusätzliche Schritte nach Abschluss</dfn> ausführen.
|
||||||
|
|
||||||
Verwenden Sie dazu `yield` statt `return` und schreiben Sie die zusätzlichen Schritte / den zusätzlichen Code danach.
|
Verwenden Sie dazu `yield` statt `return` und schreiben Sie die zusätzlichen Schritte / den zusätzlichen Code danach.
|
||||||
|
|
||||||
@@ -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_py310.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_py310.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_py310.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_py310.py hl[3,5] *}
|
||||||
|
|
||||||
## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
|
## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ Sie können Unterabhängigkeiten und „Bäume“ von Unterabhängigkeiten belie
|
|||||||
|
|
||||||
Beispielsweise kann `dependency_c` von `dependency_b` und `dependency_b` von `dependency_a` abhängen:
|
Beispielsweise kann `dependency_c` von `dependency_b` und `dependency_b` von `dependency_a` abhängen:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
|
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
|
||||||
|
|
||||||
Und alle können `yield` verwenden.
|
Und alle können `yield` verwenden.
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ In diesem Fall benötigt `dependency_c` zum Ausführen seines Exit-Codes, dass d
|
|||||||
|
|
||||||
Und wiederum benötigt `dependency_b` den Wert von `dependency_a` (hier `dep_a` genannt) für seinen Exit-Code.
|
Und wiederum benötigt `dependency_b` den Wert von `dependency_a` (hier `dep_a` genannt) für seinen Exit-Code.
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
|
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
|
||||||
|
|
||||||
Auf die gleiche Weise könnten Sie einige Abhängigkeiten mit `yield` und einige andere Abhängigkeiten mit `return` haben, und alle können beliebig voneinander abhängen.
|
Auf die gleiche Weise könnten Sie einige Abhängigkeiten mit `yield` und einige andere Abhängigkeiten mit `return` haben, und alle können beliebig voneinander abhängen.
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ Aber es ist für Sie da, wenn Sie es brauchen. 🤓
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
|
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
|
||||||
|
|
||||||
Wenn Sie Exceptions abfangen und darauf basierend eine benutzerdefinierte Response erstellen möchten, erstellen Sie einen [benutzerdefinierten Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
|
Wenn Sie Exceptions abfangen und darauf basierend eine benutzerdefinierte Response erstellen möchten, erstellen Sie einen [benutzerdefinierten Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ Wenn Sie Exceptions abfangen und darauf basierend eine benutzerdefinierte Respon
|
|||||||
|
|
||||||
Wenn Sie eine Exception mit `except` in einer Abhängigkeit mit `yield` abfangen und sie nicht erneut auslösen (oder eine neue Exception auslösen), kann FastAPI nicht feststellen, dass es eine Exception gab, genau so wie es bei normalem Python der Fall wäre:
|
Wenn Sie eine Exception mit `except` in einer Abhängigkeit mit `yield` abfangen und sie nicht erneut auslösen (oder eine neue Exception auslösen), kann FastAPI nicht feststellen, dass es eine Exception gab, genau so wie es bei normalem Python der Fall wäre:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
|
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
|
||||||
|
|
||||||
In diesem Fall sieht der Client eine *HTTP 500 Internal Server Error*-Response, wie es sein sollte, da wir keine `HTTPException` oder Ähnliches auslösen, aber der Server hat **keine Logs** oder einen anderen Hinweis darauf, was der Fehler war. 😱
|
In diesem Fall sieht der Client eine *HTTP 500 Internal Server Error*-Response, wie es sein sollte, da wir keine `HTTPException` oder Ähnliches auslösen, aber der Server hat **keine Logs** oder einen anderen Hinweis darauf, was der Fehler war. 😱
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ Wenn Sie eine Exception in einer Abhängigkeit mit `yield` abfangen, sollten Sie
|
|||||||
|
|
||||||
Sie können dieselbe Exception mit `raise` erneut auslösen:
|
Sie können dieselbe Exception mit `raise` erneut auslösen:
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
|
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
|
||||||
|
|
||||||
Jetzt erhält der Client dieselbe *HTTP 500 Internal Server Error*-Response, aber der Server enthält unseren benutzerdefinierten `InternalError` in den Logs. 😎
|
Jetzt erhält der Client dieselbe *HTTP 500 Internal Server Error*-Response, aber der Server enthält unseren benutzerdefinierten `InternalError` in den Logs. 😎
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ Normalerweise wird der Exit-Code von Abhängigkeiten mit `yield` ausgeführt **n
|
|||||||
|
|
||||||
Wenn Sie aber wissen, dass Sie die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* nicht mehr benötigen, können Sie `Depends(scope="function")` verwenden, um FastAPI mitzuteilen, dass es die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* schließen soll, jedoch **bevor** die **Response gesendet wird**.
|
Wenn Sie aber wissen, dass Sie die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* nicht mehr benötigen, können Sie `Depends(scope="function")` verwenden, um FastAPI mitzuteilen, dass es die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* schließen soll, jedoch **bevor** die **Response gesendet wird**.
|
||||||
|
|
||||||
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
|
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
|
||||||
|
|
||||||
`Depends()` erhält einen `scope`-Parameter, der sein kann:
|
`Depends()` erhält einen `scope`-Parameter, der sein kann:
|
||||||
|
|
||||||
@@ -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_py310.py hl[1:9,13] *}
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ 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_py310.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.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Abhängigkeiten { #dependencies }
|
# Abhängigkeiten { #dependencies }
|
||||||
|
|
||||||
**FastAPI** hat ein sehr mächtiges, aber intuitives **<abbr title="auch bekannt als: Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>** System.
|
**FastAPI** hat ein sehr mächtiges, aber intuitives **<dfn title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Abhängigkeitsinjektion</dfn>** System.
|
||||||
|
|
||||||
Es ist so konzipiert, sehr einfach zu verwenden zu sein und es jedem Entwickler sehr leicht zu machen, andere Komponenten mit **FastAPI** zu integrieren.
|
Es ist so konzipiert, sehr einfach zu verwenden zu sein und es jedem Entwickler sehr leicht zu machen, andere Komponenten mit **FastAPI** zu integrieren.
|
||||||
|
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
|
|||||||
|
|
||||||
Wenn eine Ihrer Abhängigkeiten mehrmals für dieselbe *Pfadoperation* deklariert wird, beispielsweise wenn mehrere Abhängigkeiten eine gemeinsame Unterabhängigkeit haben, wird **FastAPI** diese Unterabhängigkeit nur einmal pro <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> aufrufen.
|
Wenn eine Ihrer Abhängigkeiten mehrmals für dieselbe *Pfadoperation* deklariert wird, beispielsweise wenn mehrere Abhängigkeiten eine gemeinsame Unterabhängigkeit haben, wird **FastAPI** diese Unterabhängigkeit nur einmal pro <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> aufrufen.
|
||||||
|
|
||||||
Und es speichert den zurückgegebenen Wert in einem <abbr title="Mechanismus, der bereits berechnete/generierte Werte zwischenspeichert, um sie später wiederzuverwenden, anstatt sie erneut zu berechnen.">„Cache“</abbr> und übergibt diesen gecachten Wert an alle „Dependanten“, die ihn in diesem spezifischen Request benötigen, anstatt die Abhängigkeit mehrmals für denselben Request aufzurufen.
|
Und es speichert den zurückgegebenen Wert in einem <dfn title="Hilfsprogramm/System zum Speichern berechneter/erzeugter Werte, um sie wiederzuverwenden, anstatt sie erneut zu berechnen.">„Cache“</dfn> und übergibt diesen gecachten Wert an alle „Dependanten“, die ihn in diesem spezifischen Request benötigen, anstatt die Abhängigkeit mehrmals für denselben Request aufzurufen.
|
||||||
|
|
||||||
In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (möglicherweise mehrmals) in 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.10+
|
||||||
|
|
||||||
```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.10+ nicht annotiert
|
||||||
|
|
||||||
/// tip | Tipp
|
/// tip | Tipp
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user