Compare commits

...

26 Commits

Author SHA1 Message Date
github-actions[bot]
91dba4484d 📝 Update release notes
[skip ci]
2026-05-28 10:49:01 +00:00
dependabot[bot]
99a1b1edee ⬆ Bump authlib from 1.6.11 to 1.7.2 (#15512)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2026-05-28 12:48:36 +02:00
github-actions[bot]
199415da85 📝 Update release notes
[skip ci]
2026-05-28 10:34:26 +00:00
dependabot[bot]
dcac2f0d95 ⬆ Bump pymdown-extensions from 10.21.2 to 10.21.3 (#15569)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com>
2026-05-28 12:34:00 +02:00
github-actions[bot]
334582bfe4 📝 Update release notes
[skip ci]
2026-05-28 10:29:52 +00:00
dependabot[bot]
2a1506d167 ⬆ Bump CodSpeedHQ/action from 4.14.0 to 4.15.1 (#15513)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com>
2026-05-28 12:29:24 +02:00
github-actions[bot]
136b55f3d8 📝 Update release notes
[skip ci]
2026-05-28 10:20:07 +00:00
dependabot[bot]
4a5f0cd370 ⬆ Bump python-multipart from 0.0.26 to 0.0.29 (#15595)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2026-05-28 12:19:23 +02:00
github-actions[bot]
2bd97a6013 📝 Update release notes
[skip ci]
2026-05-27 20:58:15 +00:00
Yurii Motov
a3558be5f8 🔒️ Improve GitHub actions security (#15607) 2026-05-27 22:57:52 +02:00
github-actions[bot]
c9343d2cf0 📝 Update release notes
[skip ci]
2026-05-27 20:53:41 +00:00
Yurii Motov
a53efbcae9 ⚰️ Remove ruff and coverage ignores for non-existing files (#15610)
Co-authored-by: AshNicolus <yashnema52@gmail.com>
2026-05-27 22:53:15 +02:00
github-actions[bot]
ad09734fa3 📝 Update release notes
[skip ci]
2026-05-27 20:23:09 +00:00
Yurii Motov
57535ef85b Use custom changing_dir instead of CLIRunner.isolated_filesystem to set working dir (#15616) 2026-05-27 22:22:44 +02:00
github-actions[bot]
dbfd55cea3 📝 Update release notes
[skip ci]
2026-05-27 10:47:52 +00:00
Yurii Motov
59d4a80fcf Add httpx2 test dependency to avoid deprecation warning (#15603) 2026-05-27 12:47:28 +02:00
github-actions[bot]
6cbdde2315 📝 Update release notes
[skip ci]
2026-05-24 13:03:53 +00:00
dependabot[bot]
1464678ba6 ⬆ Bump the python-packages group with 15 updates (#15594)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-24 15:03:23 +02:00
github-actions[bot]
1a84bbc00b 📝 Update release notes
[skip ci]
2026-05-24 11:07:04 +00:00
Yurii Motov
3fdc54edab 👷 Configure Dependabot to group updates and update weekly (#15560) 2026-05-24 13:06:37 +02:00
github-actions[bot]
09ba2cec98 📝 Update release notes
[skip ci]
2026-05-24 11:01:06 +00:00
Alexander Li
3e3d38930e ✏️ Use Annotated in inline example in docs/en/docs/tutorial/body-multiple-params.md (#15591) 2026-05-24 13:00:37 +02:00
github-actions[bot]
84f205c8f7 📝 Update release notes
[skip ci]
2026-05-24 10:57:12 +00:00
Ömer 🇹🇷
7baefe7144 📝 Remove "NGINX Unit" from the list of ASGI-servers in docs (#15475) 2026-05-24 12:56:40 +02:00
github-actions[bot]
2895c51ba8 📝 Update release notes
[skip ci]
2026-05-24 10:29:48 +00:00
zadevhub
21c46919fc 📝 Update docs/en/docs/tutorial/security/oauth2-jwt.md (#14781)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com>
2026-05-24 10:29:22 +00:00
32 changed files with 707 additions and 444 deletions

View File

@@ -4,26 +4,47 @@ updates:
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "weekly"
cooldown: cooldown:
default-days: 7 default-days: 7
commit-message: commit-message:
prefix: prefix:
labels:
- "internal"
- "dependencies"
- "github_actions"
groups:
github-actions:
patterns:
- "*"
# Python # Python
- package-ecosystem: "uv" - package-ecosystem: "uv"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "weekly"
cooldown: cooldown:
default-days: 7 default-days: 7
commit-message: commit-message:
prefix: prefix:
groups:
python-packages:
dependency-type: "development"
patterns:
- "*"
# pre-commit # pre-commit
- package-ecosystem: "pre-commit" - package-ecosystem: "pre-commit"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "weekly"
cooldown: cooldown:
default-days: 7 default-days: 7
commit-message: commit-message:
prefix: prefix:
labels:
- "internal"
- "dependencies"
- "pre-commit"
groups:
pre-commit:
patterns:
- "*"

View File

@@ -13,6 +13,7 @@ jobs:
add-to-project: add-to-project:
name: Add to project name: Add to project
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
with: with:

View File

@@ -16,6 +16,7 @@ jobs:
# Required permissions # Required permissions
permissions: permissions:
pull-requests: read pull-requests: read
timeout-minutes: 5
# Set job outputs to values from filter step # Set job outputs to values from filter step
outputs: outputs:
docs: ${{ steps.filter.outputs.docs }} docs: ${{ steps.filter.outputs.docs }}
@@ -42,6 +43,7 @@ jobs:
- changes - changes
if: ${{ needs.changes.outputs.docs == 'true' }} if: ${{ needs.changes.outputs.docs == 'true' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
outputs: outputs:
langs: ${{ steps.show-langs.outputs.langs }} langs: ${{ steps.show-langs.outputs.langs }}
steps: steps:
@@ -55,6 +57,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
@@ -73,6 +77,7 @@ jobs:
- langs - langs
if: ${{ needs.changes.outputs.docs == 'true' }} if: ${{ needs.changes.outputs.docs == 'true' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 7
strategy: strategy:
matrix: matrix:
lang: ${{ fromJson(needs.langs.outputs.langs) }} lang: ${{ fromJson(needs.langs.outputs.langs) }}
@@ -91,6 +96,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -33,6 +33,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -16,6 +16,7 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
statuses: write statuses: write
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -31,6 +32,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: false enable-cache: false
- name: Install GitHub Actions dependencies - name: Install GitHub Actions dependencies

View File

@@ -12,6 +12,7 @@ jobs:
contents: read contents: read
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Check if PRs have merge conflicts - name: Check if PRs have merge conflicts
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3 uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3

View File

@@ -15,6 +15,7 @@ permissions:
jobs: jobs:
check-author: check-author:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Check if author is org member or allowed bot - name: Check if author is org member or allowed bot
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0

View File

@@ -23,6 +23,7 @@ jobs:
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:

View File

@@ -13,6 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
pull-requests: write pull-requests: write
timeout-minutes: 7
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -28,6 +29,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -17,6 +17,7 @@ jobs:
contents: read contents: read
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0 - uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }} if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
@@ -28,6 +29,7 @@ jobs:
permissions: permissions:
pull-requests: read pull-requests: read
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65 - uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65
with: with:

View File

@@ -22,6 +22,7 @@ jobs:
latest-changes: latest-changes:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:

View File

@@ -24,6 +24,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
discussions: write discussions: write
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -39,6 +40,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -33,6 +33,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -15,6 +15,7 @@ env:
jobs: jobs:
pre-commit: pre-commit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -48,6 +49,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
@@ -84,6 +87,7 @@ jobs:
needs: needs:
- pre-commit - pre-commit
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:

View File

@@ -13,6 +13,7 @@ jobs:
permissions: permissions:
id-token: write id-token: write
contents: read contents: read
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -28,7 +29,10 @@ jobs:
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: "false"
- name: Build distribution - name: Build distribution
run: uv build run: uv build
- name: Publish - name: Publish

View File

@@ -12,6 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
statuses: write statuses: write
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
@@ -27,6 +28,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml

View File

@@ -18,6 +18,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -33,6 +34,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -14,6 +14,7 @@ permissions: {}
jobs: jobs:
test-redistribute: test-redistribute:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -57,6 +58,7 @@ jobs:
needs: needs:
- test-redistribute - test-redistribute
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Decide whether the needed jobs succeeded or failed - name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2 uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2

View File

@@ -25,6 +25,7 @@ jobs:
permissions: permissions:
pull-requests: read pull-requests: read
# Set job outputs to values from filter step # Set job outputs to values from filter step
timeout-minutes: 5
outputs: outputs:
src: ${{ steps.filter.outputs.src }} src: ${{ steps.filter.outputs.src }}
steps: steps:
@@ -50,6 +51,7 @@ jobs:
needs: needs:
- changes - changes
if: needs.changes.outputs.src == 'true' || github.ref == 'refs/heads/master' if: needs.changes.outputs.src == 'true' || github.ref == 'refs/heads/master'
timeout-minutes: 10
strategy: strategy:
matrix: matrix:
os: [ windows-latest, macos-latest ] os: [ windows-latest, macos-latest ]
@@ -81,6 +83,11 @@ jobs:
uv-resolution: highest uv-resolution: highest
codspeed: codspeed codspeed: codspeed
deprecated-tests: "no-deprecation" deprecated-tests: "no-deprecation"
- os: ubuntu-latest
python-version: "3.13"
uv-resolution: highest
deprecated-tests: "no-deprecation"
without-httpx2: true
- os: ubuntu-latest - os: ubuntu-latest
python-version: "3.14" python-version: "3.14"
coverage: coverage coverage: coverage
@@ -113,6 +120,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
@@ -129,15 +138,19 @@ jobs:
- name: Install deprecated libraries just for testing - name: Install deprecated libraries just for testing
if: matrix.deprecated-tests == 'test-deprecation' if: matrix.deprecated-tests == 'test-deprecation'
run: uv pip install orjson ujson run: uv pip install orjson ujson
- name: Uninstall httpx2 to run tests with httpx
if: matrix.without-httpx2 == 'true'
run: uv pip uninstall httpx2
- name: Reinstall SQLAlchemy without Cython extensions - name: Reinstall SQLAlchemy without Cython extensions
if: matrix.python-version == '3.14t' && matrix.os == 'ubuntu-latest' if: matrix.python-version == '3.14t' && matrix.os == 'ubuntu-latest'
run: "DISABLE_SQLALCHEMY_CEXT=1 uv pip install --force-reinstall --no-binary :all: sqlalchemy" run: "DISABLE_SQLALCHEMY_CEXT=1 uv pip install --force-reinstall --no-binary :all: sqlalchemy"
- run: mkdir coverage - run: mkdir coverage
- name: Test - name: Test
run: uv run --no-sync bash scripts/test-cov.sh run: uv run --no-sync bash scripts/test-cov.sh $PYTEST_OPTIONS
env: env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}-${{ matrix.deprecated-tests}} COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}-${{ matrix.deprecated-tests}}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}-${{ matrix.deprecated-tests}} CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}-${{ matrix.deprecated-tests}}
PYTEST_OPTIONS: ${{ (matrix.without-httpx2 == 'true') && '-W ignore::UserWarning' || '' }}
# Do not store coverage for all possible combinations to avoid file size max errors in Smokeshow # Do not store coverage for all possible combinations to avoid file size max errors in Smokeshow
- name: Store coverage files - name: Store coverage files
if: matrix.coverage == 'coverage' if: matrix.coverage == 'coverage'
@@ -152,6 +165,7 @@ jobs:
- changes - changes
if: needs.changes.outputs.src == 'true' || github.ref == 'refs/heads/master' if: needs.changes.outputs.src == 'true' || github.ref == 'refs/heads/master'
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
env: env:
UV_PYTHON: "3.13" UV_PYTHON: "3.13"
UV_RESOLUTION: highest UV_RESOLUTION: highest
@@ -170,6 +184,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
@@ -178,7 +194,7 @@ jobs:
- name: Install Dependencies - name: Install Dependencies
run: uv sync --no-dev --group tests --extra all run: uv sync --no-dev --group tests --extra all
- name: CodSpeed benchmarks - name: CodSpeed benchmarks
uses: CodSpeedHQ/action@658a901452bb54c799643e060733b7afe9121b8d # v4.14.0 uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # v4.15.1
with: with:
mode: simulation mode: simulation
run: uv run --no-sync pytest tests/benchmarks --codspeed run: uv run --no-sync pytest tests/benchmarks --codspeed
@@ -187,6 +203,7 @@ jobs:
needs: needs:
- test - test
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -201,6 +218,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
@@ -232,6 +251,7 @@ jobs:
- coverage-combine - coverage-combine
- benchmark - benchmark
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:

View File

@@ -13,6 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
timeout-minutes: 5
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
@@ -28,6 +29,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |

View File

@@ -60,6 +60,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
@@ -101,6 +103,8 @@ jobs:
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
version: "0.11.4" version: "0.11.4"
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml

24
.github/workflows/zizmor.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Zizmor
on:
push:
branches:
- main
workflow_dispatch:
permissions: {}
jobs:
zizmor:
name: Run zizmor
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Run zizmor
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3

View File

@@ -96,6 +96,6 @@ repos:
name: zizmor name: zizmor
language: python language: python
entry: uv run zizmor . entry: uv run zizmor .
files: ^\.github\/workflows\/ files: ^\.github/workflows/|^uv\.lock$
require_serial: true require_serial: true
pass_filenames: false pass_filenames: false

View File

@@ -56,7 +56,6 @@ There are several alternatives, including:
* [Hypercorn](https://hypercorn.readthedocs.io/): an ASGI server compatible with HTTP/2 and Trio among other features. * [Hypercorn](https://hypercorn.readthedocs.io/): an ASGI server compatible with HTTP/2 and Trio among other features.
* [Daphne](https://github.com/django/daphne): the ASGI server built for Django Channels. * [Daphne](https://github.com/django/daphne): the ASGI server built for Django Channels.
* [Granian](https://github.com/emmett-framework/granian): A Rust HTTP server for Python applications. * [Granian](https://github.com/emmett-framework/granian): A Rust HTTP server for Python applications.
* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit is a lightweight and versatile web application runtime.
## Server Machine and Server Program { #server-machine-and-server-program } ## Server Machine and Server Program { #server-machine-and-server-program }

View File

@@ -7,6 +7,25 @@ hide:
## Latest Changes ## Latest Changes
### Docs
* ✏️ Use `Annotated` in inline example in `docs/en/docs/tutorial/body-multiple-params.md`. PR [#15591](https://github.com/fastapi/fastapi/pull/15591) by [@TheArchons](https://github.com/TheArchons).
* 📝 Remove "NGINX Unit" from the list of ASGI-servers in docs. PR [#15475](https://github.com/fastapi/fastapi/pull/15475) by [@angryfoxx](https://github.com/angryfoxx).
* 📝 Update `docs/en/docs/tutorial/security/oauth2-jwt.md`. PR [#14781](https://github.com/fastapi/fastapi/pull/14781) by [@zadevhub](https://github.com/zadevhub).
### Internal
* ⬆ Bump authlib from 1.6.11 to 1.7.2. PR [#15512](https://github.com/fastapi/fastapi/pull/15512) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pymdown-extensions from 10.21.2 to 10.21.3. PR [#15569](https://github.com/fastapi/fastapi/pull/15569) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump CodSpeedHQ/action from 4.14.0 to 4.15.1. PR [#15513](https://github.com/fastapi/fastapi/pull/15513) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump python-multipart from 0.0.26 to 0.0.29. PR [#15595](https://github.com/fastapi/fastapi/pull/15595) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔒️ Improve GitHub actions security. PR [#15607](https://github.com/fastapi/fastapi/pull/15607) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⚰️ Remove ruff and coverage ignores for non-existing files. PR [#15610](https://github.com/fastapi/fastapi/pull/15610) by [@YuriiMotov](https://github.com/YuriiMotov).
* ✅ Use custom `changing_dir` instead of `CLIRunner.isolated_filesystem` to set working dir. PR [#15616](https://github.com/fastapi/fastapi/pull/15616) by [@YuriiMotov](https://github.com/YuriiMotov).
* ✅ Add `httpx2` test dependency to avoid deprecation warning. PR [#15603](https://github.com/fastapi/fastapi/pull/15603) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump the python-packages group with 15 updates. PR [#15594](https://github.com/fastapi/fastapi/pull/15594) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Configure Dependabot to group updates and update weekly. PR [#15560](https://github.com/fastapi/fastapi/pull/15560) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.136.3 (2026-05-23) ## 0.136.3 (2026-05-23)
### Refactors ### Refactors

View File

@@ -126,7 +126,7 @@ By default, **FastAPI** will then expect its body directly.
But if you want it to expect a JSON with a key `item` and inside of it the model contents, as it does when you declare extra body parameters, you can use the special `Body` parameter `embed`: But if you want it to expect a JSON with a key `item` and inside of it the model contents, as it does when you declare extra body parameters, you can use the special `Body` parameter `embed`:
```Python ```Python
item: Item = Body(embed=True) item: Annotated[Item, Body(embed=True)]
``` ```
as in: as in:

View File

@@ -18,7 +18,7 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
It is not encrypted, so, anyone could recover the information from the contents. It is not encrypted, so, anyone could recover the information from the contents.
But it's signed. So, when you receive a token that you emitted, you can verify that you actually emitted it. But it's signed. So, when you receive a token that you issued, you can verify that it was you who issued it.
That way, you can create a token with an expiration of, let's say, 1 week. And then when the user comes back the next day with the token, you know that user is still logged in to your system. That way, you can create a token with an expiration of, let's say, 1 week. And then when the user comes back the next day with the token, you know that user is still logged in to your system.

View File

@@ -146,6 +146,7 @@ docs = [
] ]
docs-tests = [ docs-tests = [
"httpx >=0.23.0,<1.0.0", "httpx >=0.23.0,<1.0.0",
"httpx2>=2.0.0",
"ruff >=0.14.14", "ruff >=0.14.14",
] ]
github-actions = [ github-actions = [
@@ -242,7 +243,6 @@ relative_files = true
context = '${CONTEXT}' context = '${CONTEXT}'
omit = [ omit = [
"tests/benchmarks/*", "tests/benchmarks/*",
"docs_src/response_model/tutorial003_04_py39.py",
"docs_src/response_model/tutorial003_04_py310.py", "docs_src/response_model/tutorial003_04_py310.py",
"docs_src/dependencies/tutorial013_an_py310.py", # temporary code example? "docs_src/dependencies/tutorial013_an_py310.py", # temporary code example?
"docs_src/dependencies/tutorial014_an_py310.py", # temporary code example? "docs_src/dependencies/tutorial014_an_py310.py", # temporary code example?
@@ -279,41 +279,21 @@ ignore = [
[tool.ruff.lint.per-file-ignores] [tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"] "__init__.py" = ["F401"]
"docs_src/custom_request_and_route/tutorial002_an_py310.py" = ["B904"] "docs_src/custom_request_and_route/tutorial002_an_py310.py" = ["B904"]
"docs_src/custom_request_and_route/tutorial002_an_py39.py" = ["B904"]
"docs_src/custom_request_and_route/tutorial002_py310.py" = ["B904"] "docs_src/custom_request_and_route/tutorial002_py310.py" = ["B904"]
"docs_src/custom_request_and_route/tutorial002_py39.py" = ["B904"]
"docs_src/custom_response/tutorial007_py310.py" = ["B007"] "docs_src/custom_response/tutorial007_py310.py" = ["B007"]
"docs_src/custom_response/tutorial007_py39.py" = ["B007"]
"docs_src/dataclasses/tutorial003_py39.py" = ["I001"]
"docs_src/dependencies/tutorial007_py310.py" = ["F821"] "docs_src/dependencies/tutorial007_py310.py" = ["F821"]
"docs_src/dependencies/tutorial007_py39.py" = ["F821"]
"docs_src/dependencies/tutorial008_an_py310.py" = ["F821"] "docs_src/dependencies/tutorial008_an_py310.py" = ["F821"]
"docs_src/dependencies/tutorial008_an_py39.py" = ["F821"]
"docs_src/dependencies/tutorial008_py310.py" = ["F821"] "docs_src/dependencies/tutorial008_py310.py" = ["F821"]
"docs_src/dependencies/tutorial008_py39.py" = ["F821"]
"docs_src/dependencies/tutorial008b_an_py310.py" = ["B904"] "docs_src/dependencies/tutorial008b_an_py310.py" = ["B904"]
"docs_src/dependencies/tutorial008b_an_py39.py" = ["B904"]
"docs_src/dependencies/tutorial008b_py310.py" = ["B904"] "docs_src/dependencies/tutorial008b_py310.py" = ["B904"]
"docs_src/dependencies/tutorial008b_py39.py" = ["B904"]
"docs_src/dependencies/tutorial009_py310.py" = ["F821"]
"docs_src/dependencies/tutorial009_py39.py" = ["F821"]
"docs_src/dependencies/tutorial010_py310.py" = ["F821"] "docs_src/dependencies/tutorial010_py310.py" = ["F821"]
"docs_src/dependencies/tutorial010_py39.py" = ["F821"]
"docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py" = ["B904"]
"docs_src/path_operation_advanced_configuration/tutorial007_py310.py" = ["B904"] "docs_src/path_operation_advanced_configuration/tutorial007_py310.py" = ["B904"]
"docs_src/path_operation_advanced_configuration/tutorial007_py39.py" = ["B904"]
"docs_src/query_params_str_validations/tutorial012_an_py310.py" = ["B006"] "docs_src/query_params_str_validations/tutorial012_an_py310.py" = ["B006"]
"docs_src/query_params_str_validations/tutorial012_an_py39.py" = ["B006"]
"docs_src/query_params_str_validations/tutorial013_an_py310.py" = ["B006"] "docs_src/query_params_str_validations/tutorial013_an_py310.py" = ["B006"]
"docs_src/query_params_str_validations/tutorial013_an_py39.py" = ["B006"]
"docs_src/security/tutorial004_an_py310.py" = ["B904"] "docs_src/security/tutorial004_an_py310.py" = ["B904"]
"docs_src/security/tutorial004_an_py39.py" = ["B904"]
"docs_src/security/tutorial004_py310.py" = ["B904"] "docs_src/security/tutorial004_py310.py" = ["B904"]
"docs_src/security/tutorial004_py39.py" = ["B904"]
"docs_src/security/tutorial005_an_py310.py" = ["B904"] "docs_src/security/tutorial005_an_py310.py" = ["B904"]
"docs_src/security/tutorial005_an_py39.py" = ["B904"]
"docs_src/security/tutorial005_py310.py" = ["B904"] "docs_src/security/tutorial005_py310.py" = ["B904"]
"docs_src/security/tutorial005_py39.py" = ["B904"]
"docs_src/json_base64_bytes/tutorial001_py310.py" = ["UP012"] "docs_src/json_base64_bytes/tutorial001_py310.py" = ["UP012"]
"docs_src/stream_json_lines/tutorial001_py310.py" = ["UP028"] "docs_src/stream_json_lines/tutorial001_py310.py" = ["UP028"]
"docs_src/stream_data/tutorial001_py310.py" = ["UP028"] "docs_src/stream_data/tutorial001_py310.py" = ["UP028"]

View File

@@ -1,5 +1,8 @@
import os
import shutil import shutil
import sys import sys
from collections.abc import Generator
from contextlib import contextmanager
from pathlib import Path from pathlib import Path
import pytest import pytest
@@ -23,11 +26,20 @@ def pytest_collection_modifyitems(config, items: list[pytest.Item]) -> None:
item.add_marker(skip_on_windows) item.add_marker(skip_on_windows)
@contextmanager
def changing_dir(directory: str | Path) -> Generator[None, None, None]:
initial_dir = os.getcwd()
os.chdir(directory)
try:
yield
finally:
os.chdir(initial_dir)
@pytest.fixture(name="runner") @pytest.fixture(name="runner")
def get_runner(): def get_runner(tmp_path: Path):
runner = CliRunner() with changing_dir(tmp_path):
with runner.isolated_filesystem(): yield CliRunner()
yield runner
@pytest.fixture(name="root_dir") @pytest.fixture(name="root_dir")

View File

@@ -1,6 +1,7 @@
import importlib import importlib
import pytest import pytest
from dirty_equals import IsOneOf
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from inline_snapshot import snapshot from inline_snapshot import snapshot
@@ -68,7 +69,9 @@ def test_header_param_model_invalid(client: TestClient):
"x_tag": [], "x_tag": [],
"host": "testserver", "host": "testserver",
"accept": "*/*", "accept": "*/*",
"accept-encoding": "gzip, deflate", "accept-encoding": IsOneOf(
"gzip, deflate", "gzip, deflate, zstd"
),
"connection": "keep-alive", "connection": "keep-alive",
"user-agent": "testclient", "user-agent": "testclient",
}, },

View File

@@ -1,6 +1,7 @@
import importlib import importlib
import pytest import pytest
from dirty_equals import IsOneOf
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from inline_snapshot import snapshot from inline_snapshot import snapshot
@@ -66,7 +67,9 @@ def test_header_param_model_no_underscore(client: TestClient):
"traceparent": "123", "traceparent": "123",
"x_tag": [], "x_tag": [],
"accept": "*/*", "accept": "*/*",
"accept-encoding": "gzip, deflate", "accept-encoding": IsOneOf(
"gzip, deflate", "gzip, deflate, zstd"
),
"connection": "keep-alive", "connection": "keep-alive",
"user-agent": "testclient", "user-agent": "testclient",
"save-data": "true", "save-data": "true",
@@ -105,7 +108,9 @@ def test_header_param_model_invalid(client: TestClient):
"x_tag": [], "x_tag": [],
"host": "testserver", "host": "testserver",
"accept": "*/*", "accept": "*/*",
"accept-encoding": "gzip, deflate", "accept-encoding": IsOneOf(
"gzip, deflate", "gzip, deflate, zstd"
),
"connection": "keep-alive", "connection": "keep-alive",
"user-agent": "testclient", "user-agent": "testclient",
}, },

944
uv.lock generated
View File

File diff suppressed because it is too large Load Diff