Compare commits

...

9 Commits

Author SHA1 Message Date
Sebastián Ramírez
1e78a36b73 🔖 Release version 0.129.2 2026-02-21 18:24:59 +01:00
github-actions[bot]
f921de6495 📝 Update release notes
[skip ci]
2026-02-21 17:23:22 +00:00
Sebastián Ramírez
4ab8138554 ⬆️ Upgrade pytest (#14959) 2026-02-21 18:22:54 +01:00
github-actions[bot]
468d5173ed 📝 Update release notes
[skip ci]
2026-02-21 16:45:38 +00:00
Sebastián Ramírez
c9455d5400 👷 Fix CI, do not attempt to publish fastapi-slim (#14958) 2026-02-21 16:45:15 +00:00
github-actions[bot]
69ae1d0f28 📝 Update release notes
[skip ci]
2026-02-21 16:27:01 +00:00
Sebastián Ramírez
083b6ebe9e Drop support for fastapi-slim, no more versions will be released, use only "fastapi[standard]" or fastapi (#14957) 2026-02-21 16:26:38 +00:00
github-actions[bot]
1b9a351ee8 📝 Update release notes
[skip ci]
2026-02-21 16:16:27 +00:00
Sebastián Ramírez
f55ab7e020 🔧 Update pyproject.toml, remove unneeded lines (#14956) 2026-02-21 16:16:03 +00:00
8 changed files with 19 additions and 297 deletions

2
.github/labeler.yml vendored
View File

@@ -29,8 +29,6 @@ internal:
- scripts/**
- .gitignore
- .pre-commit-config.yaml
- pdm_build.py
- requirements*.txt
- uv.lock
- docs/en/data/sponsors.yml
- docs/en/overrides/main.html

View File

@@ -8,11 +8,6 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
strategy:
matrix:
package:
- fastapi
- fastapi-slim
permissions:
id-token: write
contents: read
@@ -26,14 +21,9 @@ jobs:
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build distribution
run: uv build
env:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
- name: Publish
run: uv publish

View File

@@ -7,6 +7,15 @@ hide:
## Latest Changes
## 0.129.2
### Internal
* ⬆️ Upgrade pytest. PR [#14959](https://github.com/fastapi/fastapi/pull/14959) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix CI, do not attempt to publish `fastapi-slim`. PR [#14958](https://github.com/fastapi/fastapi/pull/14958) by [@tiangolo](https://github.com/tiangolo).
* Drop support for `fastapi-slim`, no more versions will be released, use only `"fastapi[standard]"` or `fastapi`. PR [#14957](https://github.com/fastapi/fastapi/pull/14957) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update pyproject.toml, remove unneeded lines. PR [#14956](https://github.com/fastapi/fastapi/pull/14956) by [@tiangolo](https://github.com/tiangolo).
## 0.129.1
### Fixes

View File

@@ -1,2 +0,0 @@
def get_items(item_a: str, item_b: int, item_c: float, item_d: bool, item_e: bytes):
return item_a, item_b, item_c, item_d, item_e

View File

@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
__version__ = "0.129.1"
__version__ = "0.129.2"
from starlette import status as status

View File

@@ -1,40 +0,0 @@
import os
from typing import Any
from pdm.backend.hooks import Context
TIANGOLO_BUILD_PACKAGE = os.getenv("TIANGOLO_BUILD_PACKAGE")
def pdm_build_initialize(context: Context) -> None:
metadata = context.config.metadata
# Get main version
version = metadata["version"]
# Get custom config for the current package, from the env var
all_configs_config: dict[str, Any] = context.config.data["tool"]["tiangolo"][
"_internal-slim-build"
]["packages"]
if TIANGOLO_BUILD_PACKAGE not in all_configs_config:
return
config = all_configs_config[TIANGOLO_BUILD_PACKAGE]
project_config: dict[str, Any] = config["project"]
# Override main [project] configs with custom configs for this package
for key, value in project_config.items():
metadata[key] = value
# Get custom build config for the current package
build_config: dict[str, Any] = (
config.get("tool", {}).get("pdm", {}).get("build", {})
)
# Override PDM build config with custom build config for this package
for key, value in build_config.items():
context.config.build_config[key] = value
# Get main dependencies
dependencies: list[str] = metadata.get("dependencies", [])
# Sync versions in dependencies
new_dependencies = []
for dep in dependencies:
new_dep = f"{dep}>={version}"
new_dependencies.append(new_dep)
metadata["dependencies"] = new_dependencies

View File

@@ -57,7 +57,6 @@ Issues = "https://github.com/fastapi/fastapi/issues"
Changelog = "https://fastapi.tiangolo.com/release-notes/"
[project.optional-dependencies]
standard = [
"fastapi-cli[standard] >=0.0.8",
# For the test client
@@ -171,7 +170,7 @@ tests = [
"mypy >=1.14.1",
"pwdlib[argon2] >=0.2.1",
"pyjwt >=2.9.0",
"pytest >=7.1.3,<9.0.0",
"pytest >=9.0.0",
"pytest-codspeed >=4.2.0",
"pyyaml >=5.3.1,<7.0.0",
"sqlmodel >=0.0.31",
@@ -199,32 +198,6 @@ source-includes = [
"docs/en/docs/img/favicon.png",
]
[tool.tiangolo._internal-slim-build.packages.fastapi-slim.project]
name = "fastapi-slim"
readme = "fastapi-slim/README.md"
dependencies = [
"fastapi",
]
optional-dependencies = {}
scripts = {}
[tool.tiangolo._internal-slim-build.packages.fastapi-slim.tool.pdm.build]
# excludes needs to explicitly exclude the top level python packages,
# otherwise PDM includes them by default
# A "*" glob pattern can't be used here because in PDM internals, the patterns are put
# in a set (unordered, order varies) and each excluded file is assigned one of the
# glob patterns that matches, as the set is unordered, the matched pattern could be "*"
# independent of the order here. And then the internal code would give it a lower score
# than the one for a default included file.
# By not using "*" and explicitly excluding the top level packages, they get a higher
# score than the default inclusion
excludes = ["fastapi", "tests", "pdm_build.py"]
# source-includes needs to explicitly define some value because PDM will check the
# truthy value of the list, and if empty, will include some defaults, including "tests",
# an empty string doesn't match anything, but makes the list truthy, so that PDM
# doesn't override it during the build.
source-includes = [""]
[tool.mypy]
plugins = ["pydantic.mypy"]
strict = true
@@ -245,25 +218,16 @@ disallow_incomplete_defs = false
disallow_untyped_defs = false
disallow_untyped_calls = false
[tool.pytest.ini_options]
[tool.pytest]
minversion = "9.0"
addopts = [
"--strict-config",
"--strict-markers",
"--ignore=docs_src",
]
xfail_strict = true
junit_family = "xunit2"
strict_xfail = true
filterwarnings = [
"error",
# see https://trio.readthedocs.io/en/stable/history.html#trio-0-22-0-2022-09-28
"ignore:You seem to already have a custom.*:RuntimeWarning:trio",
# TODO: remove after upgrading SQLAlchemy to a version that includes the following changes
# https://github.com/sqlalchemy/sqlalchemy/commit/59521abcc0676e936b31a523bd968fc157fef0c2
'ignore:datetime\.datetime\.utcfromtimestamp\(\) is deprecated and scheduled for removal in a future version\..*:DeprecationWarning:sqlalchemy',
# Trio 24.1.0 raises a warning from attrs
# Ref: https://github.com/python-trio/trio/pull/3054
# Remove once there's a new version of Trio
'ignore:The `hash` argument is deprecated*:DeprecationWarning:trio',
]
[tool.coverage.run]
@@ -280,7 +244,6 @@ dynamic_context = "test_function"
omit = [
"docs_src/response_model/tutorial003_04_py39.py",
"docs_src/response_model/tutorial003_04_py310.py",
"docs_src/dependencies/tutorial008_an_py39.py", # difficult to mock
"docs_src/dependencies/tutorial013_an_py310.py", # temporary code example?
"docs_src/dependencies/tutorial014_an_py310.py", # temporary code example?
# Pydantic v1 migration, no longer tested
@@ -288,202 +251,6 @@ omit = [
"docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py",
"docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py",
"docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py",
# TODO: remove all the ignores below when all translations use the new Python 3.10 files
"docs_src/additional_responses/tutorial001_py39.py",
"docs_src/additional_responses/tutorial003_py39.py",
"docs_src/advanced_middleware/tutorial001_py39.py",
"docs_src/advanced_middleware/tutorial002_py39.py",
"docs_src/advanced_middleware/tutorial003_py39.py",
"docs_src/app_testing/app_a_py39/main.py",
"docs_src/app_testing/app_a_py39/test_main.py",
"docs_src/app_testing/tutorial001_py39.py",
"docs_src/app_testing/tutorial002_py39.py",
"docs_src/app_testing/tutorial003_py39.py",
"docs_src/app_testing/tutorial004_py39.py",
"docs_src/async_tests/app_a_py39/main.py",
"docs_src/async_tests/app_a_py39/test_main.py",
"docs_src/authentication_error_status_code/tutorial001_an_py39.py",
"docs_src/background_tasks/tutorial001_py39.py",
"docs_src/behind_a_proxy/tutorial001_01_py39.py",
"docs_src/behind_a_proxy/tutorial001_py39.py",
"docs_src/behind_a_proxy/tutorial002_py39.py",
"docs_src/behind_a_proxy/tutorial003_py39.py",
"docs_src/behind_a_proxy/tutorial004_py39.py",
"docs_src/bigger_applications/app_an_py39/dependencies.py",
"docs_src/bigger_applications/app_an_py39/internal/admin.py",
"docs_src/bigger_applications/app_an_py39/main.py",
"docs_src/bigger_applications/app_an_py39/routers/items.py",
"docs_src/bigger_applications/app_an_py39/routers/users.py",
"docs_src/bigger_applications/app_py39/dependencies.py",
"docs_src/bigger_applications/app_py39/main.py",
"docs_src/body_nested_models/tutorial008_py39.py",
"docs_src/body_nested_models/tutorial009_py39.py",
"docs_src/conditional_openapi/tutorial001_py39.py",
"docs_src/configure_swagger_ui/tutorial001_py39.py",
"docs_src/configure_swagger_ui/tutorial002_py39.py",
"docs_src/configure_swagger_ui/tutorial003_py39.py",
"docs_src/cors/tutorial001_py39.py",
"docs_src/custom_docs_ui/tutorial001_py39.py",
"docs_src/custom_docs_ui/tutorial002_py39.py",
"docs_src/custom_response/tutorial001_py39.py",
"docs_src/custom_response/tutorial001b_py39.py",
"docs_src/custom_response/tutorial002_py39.py",
"docs_src/custom_response/tutorial003_py39.py",
"docs_src/custom_response/tutorial004_py39.py",
"docs_src/custom_response/tutorial005_py39.py",
"docs_src/custom_response/tutorial006_py39.py",
"docs_src/custom_response/tutorial006b_py39.py",
"docs_src/custom_response/tutorial006c_py39.py",
"docs_src/custom_response/tutorial007_py39.py",
"docs_src/custom_response/tutorial008_py39.py",
"docs_src/custom_response/tutorial009_py39.py",
"docs_src/custom_response/tutorial009b_py39.py",
"docs_src/custom_response/tutorial009c_py39.py",
"docs_src/custom_response/tutorial010_py39.py",
"docs_src/debugging/tutorial001_py39.py",
"docs_src/dependencies/tutorial006_an_py39.py",
"docs_src/dependencies/tutorial006_py39.py",
"docs_src/dependencies/tutorial007_py39.py",
"docs_src/dependencies/tutorial008_py39.py",
"docs_src/dependencies/tutorial008b_an_py39.py",
"docs_src/dependencies/tutorial008b_py39.py",
"docs_src/dependencies/tutorial008c_an_py39.py",
"docs_src/dependencies/tutorial008c_py39.py",
"docs_src/dependencies/tutorial008d_an_py39.py",
"docs_src/dependencies/tutorial008d_py39.py",
"docs_src/dependencies/tutorial008e_an_py39.py",
"docs_src/dependencies/tutorial008e_py39.py",
"docs_src/dependencies/tutorial010_py39.py",
"docs_src/dependencies/tutorial011_an_py39.py",
"docs_src/dependencies/tutorial011_py39.py",
"docs_src/dependencies/tutorial012_an_py39.py",
"docs_src/dependencies/tutorial012_py39.py",
"docs_src/events/tutorial001_py39.py",
"docs_src/events/tutorial002_py39.py",
"docs_src/events/tutorial003_py39.py",
"docs_src/extending_openapi/tutorial001_py39.py",
"docs_src/extra_models/tutorial004_py39.py",
"docs_src/extra_models/tutorial005_py39.py",
"docs_src/first_steps/tutorial001_py39.py",
"docs_src/first_steps/tutorial003_py39.py",
"docs_src/generate_clients/tutorial001_py39.py",
"docs_src/generate_clients/tutorial002_py39.py",
"docs_src/generate_clients/tutorial003_py39.py",
"docs_src/generate_clients/tutorial004_py39.py",
"docs_src/graphql_/tutorial001_py39.py",
"docs_src/handling_errors/tutorial001_py39.py",
"docs_src/handling_errors/tutorial002_py39.py",
"docs_src/handling_errors/tutorial003_py39.py",
"docs_src/handling_errors/tutorial004_py39.py",
"docs_src/handling_errors/tutorial005_py39.py",
"docs_src/handling_errors/tutorial006_py39.py",
"docs_src/metadata/tutorial001_1_py39.py",
"docs_src/metadata/tutorial001_py39.py",
"docs_src/metadata/tutorial002_py39.py",
"docs_src/metadata/tutorial003_py39.py",
"docs_src/metadata/tutorial004_py39.py",
"docs_src/middleware/tutorial001_py39.py",
"docs_src/openapi_webhooks/tutorial001_py39.py",
"docs_src/path_operation_advanced_configuration/tutorial001_py39.py",
"docs_src/path_operation_advanced_configuration/tutorial002_py39.py",
"docs_src/path_operation_advanced_configuration/tutorial003_py39.py",
"docs_src/path_operation_advanced_configuration/tutorial005_py39.py",
"docs_src/path_operation_advanced_configuration/tutorial006_py39.py",
"docs_src/path_operation_advanced_configuration/tutorial007_py39.py",
"docs_src/path_operation_configuration/tutorial002b_py39.py",
"docs_src/path_operation_configuration/tutorial006_py39.py",
"docs_src/path_params/tutorial001_py39.py",
"docs_src/path_params/tutorial002_py39.py",
"docs_src/path_params/tutorial003_py39.py",
"docs_src/path_params/tutorial003b_py39.py",
"docs_src/path_params/tutorial004_py39.py",
"docs_src/path_params/tutorial005_py39.py",
"docs_src/path_params_numeric_validations/tutorial002_an_py39.py",
"docs_src/path_params_numeric_validations/tutorial002_py39.py",
"docs_src/path_params_numeric_validations/tutorial003_an_py39.py",
"docs_src/path_params_numeric_validations/tutorial003_py39.py",
"docs_src/path_params_numeric_validations/tutorial004_an_py39.py",
"docs_src/path_params_numeric_validations/tutorial004_py39.py",
"docs_src/path_params_numeric_validations/tutorial005_an_py39.py",
"docs_src/path_params_numeric_validations/tutorial005_py39.py",
"docs_src/path_params_numeric_validations/tutorial006_an_py39.py",
"docs_src/path_params_numeric_validations/tutorial006_py39.py",
"docs_src/python_types/tutorial001_py39.py",
"docs_src/python_types/tutorial002_py39.py",
"docs_src/python_types/tutorial003_py39.py",
"docs_src/python_types/tutorial004_py39.py",
"docs_src/python_types/tutorial005_py39.py",
"docs_src/python_types/tutorial006_py39.py",
"docs_src/python_types/tutorial007_py39.py",
"docs_src/python_types/tutorial008_py39.py",
"docs_src/python_types/tutorial008b_py39.py",
"docs_src/python_types/tutorial009_py39.py",
"docs_src/python_types/tutorial009b_py39.py",
"docs_src/python_types/tutorial009c_py39.py",
"docs_src/python_types/tutorial010_py39.py",
"docs_src/python_types/tutorial013_py39.py",
"docs_src/query_params/tutorial001_py39.py",
"docs_src/query_params/tutorial005_py39.py",
"docs_src/query_params_str_validations/tutorial005_an_py39.py",
"docs_src/query_params_str_validations/tutorial005_py39.py",
"docs_src/query_params_str_validations/tutorial006_an_py39.py",
"docs_src/query_params_str_validations/tutorial006_py39.py",
"docs_src/query_params_str_validations/tutorial012_an_py39.py",
"docs_src/query_params_str_validations/tutorial012_py39.py",
"docs_src/query_params_str_validations/tutorial013_an_py39.py",
"docs_src/query_params_str_validations/tutorial013_py39.py",
"docs_src/request_files/tutorial001_03_an_py39.py",
"docs_src/request_files/tutorial001_03_py39.py",
"docs_src/request_files/tutorial001_an_py39.py",
"docs_src/request_files/tutorial001_py39.py",
"docs_src/request_files/tutorial002_an_py39.py",
"docs_src/request_files/tutorial002_py39.py",
"docs_src/request_files/tutorial003_an_py39.py",
"docs_src/request_files/tutorial003_py39.py",
"docs_src/request_form_models/tutorial001_an_py39.py",
"docs_src/request_form_models/tutorial001_py39.py",
"docs_src/request_form_models/tutorial002_an_py39.py",
"docs_src/request_form_models/tutorial002_py39.py",
"docs_src/request_forms/tutorial001_an_py39.py",
"docs_src/request_forms/tutorial001_py39.py",
"docs_src/request_forms_and_files/tutorial001_an_py39.py",
"docs_src/request_forms_and_files/tutorial001_py39.py",
"docs_src/response_change_status_code/tutorial001_py39.py",
"docs_src/response_cookies/tutorial001_py39.py",
"docs_src/response_cookies/tutorial002_py39.py",
"docs_src/response_directly/tutorial002_py39.py",
"docs_src/response_headers/tutorial001_py39.py",
"docs_src/response_headers/tutorial002_py39.py",
"docs_src/response_model/tutorial003_02_py39.py",
"docs_src/response_model/tutorial003_03_py39.py",
"docs_src/response_status_code/tutorial001_py39.py",
"docs_src/response_status_code/tutorial002_py39.py",
"docs_src/security/tutorial001_an_py39.py",
"docs_src/security/tutorial001_py39.py",
"docs_src/security/tutorial006_an_py39.py",
"docs_src/security/tutorial006_py39.py",
"docs_src/security/tutorial007_an_py39.py",
"docs_src/security/tutorial007_py39.py",
"docs_src/settings/app01_py39/config.py",
"docs_src/settings/app01_py39/main.py",
"docs_src/settings/app02_an_py39/config.py",
"docs_src/settings/app02_an_py39/main.py",
"docs_src/settings/app02_an_py39/test_main.py",
"docs_src/settings/app02_py39/config.py",
"docs_src/settings/app02_py39/main.py",
"docs_src/settings/app02_py39/test_main.py",
"docs_src/settings/app03_an_py39/config.py",
"docs_src/settings/app03_an_py39/main.py",
"docs_src/settings/app03_py39/config.py",
"docs_src/settings/app03_py39/main.py",
"docs_src/settings/tutorial001_py39.py",
"docs_src/static_files/tutorial001_py39.py",
"docs_src/sub_applications/tutorial001_py39.py",
"docs_src/templates/tutorial001_py39.py",
"docs_src/using_request_directly/tutorial001_py39.py",
"docs_src/websockets/tutorial001_py39.py",
"docs_src/websockets/tutorial003_py39.py",
"docs_src/wsgi/tutorial001_py39.py",
]
[tool.coverage.report]

10
uv.lock generated
View File

@@ -1276,7 +1276,7 @@ dev = [
{ name = "pydantic-ai", specifier = ">=0.4.10" },
{ name = "pygithub", specifier = ">=2.8.1" },
{ name = "pyjwt", specifier = ">=2.9.0" },
{ name = "pytest", specifier = ">=7.1.3,<9.0.0" },
{ name = "pytest", specifier = ">=9.0.0" },
{ name = "pytest-codspeed", specifier = ">=4.2.0" },
{ name = "python-slugify", specifier = ">=8.0.4" },
{ name = "pyyaml", specifier = ">=5.3.1,<7.0.0" },
@@ -1329,7 +1329,7 @@ tests = [
{ name = "mypy", specifier = ">=1.14.1" },
{ name = "pwdlib", extras = ["argon2"], specifier = ">=0.2.1" },
{ name = "pyjwt", specifier = ">=2.9.0" },
{ name = "pytest", specifier = ">=7.1.3,<9.0.0" },
{ name = "pytest", specifier = ">=9.0.0" },
{ name = "pytest-codspeed", specifier = ">=4.2.0" },
{ name = "pyyaml", specifier = ">=5.3.1,<7.0.0" },
{ name = "ruff", specifier = ">=0.14.14" },
@@ -4330,7 +4330,7 @@ wheels = [
[[package]]
name = "pytest"
version = "8.4.2"
version = "9.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
@@ -4341,9 +4341,9 @@ dependencies = [
{ name = "pygments" },
{ name = "tomli", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
{ url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" },
]
[[package]]