From dc3278654f13614d255edca66954326966f6620d Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 14:54:23 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Use=20`WSGIMiddleware`=20from=20?= =?UTF-8?q?`a2wsgi`=20instead=20of=20deprecated=20`fastapi.middleware.wsgi?= =?UTF-8?q?.WSGIMiddleware`=20(#14756)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- docs/en/docs/advanced/wsgi.md | 20 ++++++++++++++++++-- docs/en/docs/reference/middleware.md | 8 -------- docs_src/wsgi/tutorial001_py39.py | 2 +- fastapi/middleware/wsgi.py | 4 +++- pyproject.toml | 2 +- uv.lock | 16 ++++++++++++++++ 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/docs/en/docs/advanced/wsgi.md b/docs/en/docs/advanced/wsgi.md index 07147df0a8..aa68617cf4 100644 --- a/docs/en/docs/advanced/wsgi.md +++ b/docs/en/docs/advanced/wsgi.md @@ -6,13 +6,29 @@ For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI applicat ## Using `WSGIMiddleware` { #using-wsgimiddleware } -You need to import `WSGIMiddleware`. +/// info + +This requires installing `a2wsgi` for example with `pip install a2wsgi`. + +/// + +You need to import `WSGIMiddleware` from `a2wsgi`. Then wrap the WSGI (e.g. Flask) app with the middleware. And then mount that under a path. -{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *} +{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *} + +/// note + +Previously, it was recommended to use `WSGIMiddleware` from `fastapi.middleware.wsgi`, but it is now deprecated. + +It’s advised to use the `a2wsgi` package instead. The usage remains the same. + +Just ensure that you have the `a2wsgi` package installed and import `WSGIMiddleware` correctly from `a2wsgi`. + +/// ## Check it { #check-it } diff --git a/docs/en/docs/reference/middleware.md b/docs/en/docs/reference/middleware.md index 3c666ccdaa..48ff85158d 100644 --- a/docs/en/docs/reference/middleware.md +++ b/docs/en/docs/reference/middleware.md @@ -35,11 +35,3 @@ It can be imported from `fastapi`: ```python from fastapi.middleware.trustedhost import TrustedHostMiddleware ``` - -::: fastapi.middleware.wsgi.WSGIMiddleware - -It can be imported from `fastapi`: - -```python -from fastapi.middleware.wsgi import WSGIMiddleware -``` diff --git a/docs_src/wsgi/tutorial001_py39.py b/docs_src/wsgi/tutorial001_py39.py index 7f27a85a19..8eeceb829e 100644 --- a/docs_src/wsgi/tutorial001_py39.py +++ b/docs_src/wsgi/tutorial001_py39.py @@ -1,5 +1,5 @@ +from a2wsgi import WSGIMiddleware from fastapi import FastAPI -from fastapi.middleware.wsgi import WSGIMiddleware from flask import Flask, request from markupsafe import escape diff --git a/fastapi/middleware/wsgi.py b/fastapi/middleware/wsgi.py index c4c6a797d2..69e4dcab96 100644 --- a/fastapi/middleware/wsgi.py +++ b/fastapi/middleware/wsgi.py @@ -1 +1,3 @@ -from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware # noqa +from starlette.middleware.wsgi import ( + WSGIMiddleware as WSGIMiddleware, +) # pragma: no cover # noqa diff --git a/pyproject.toml b/pyproject.toml index dea61c6a10..0f6bf1e4ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -178,6 +178,7 @@ tests = [ "strawberry-graphql>=0.200.0,<1.0.0", "types-orjson==3.6.2", "types-ujson==5.10.0.20240515", + "a2wsgi>=1.9.0,<=2.0.0", ] translations = [ "gitpython==3.1.46", @@ -231,7 +232,6 @@ xfail_strict = true junit_family = "xunit2" filterwarnings = [ "error", - 'ignore:starlette.middleware.wsgi is deprecated and will be removed in a future release\..*:DeprecationWarning:starlette', # 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 diff --git a/uv.lock b/uv.lock index 2df0b256b8..931a27021b 100644 --- a/uv.lock +++ b/uv.lock @@ -7,6 +7,18 @@ resolution-markers = [ "python_full_version < '3.10'", ] +[[package]] +name = "a2wsgi" +version = "1.10.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/cb/822c56fbea97e9eee201a2e434a80437f6750ebcb1ed307ee3a0a7505b14/a2wsgi-1.10.10.tar.gz", hash = "sha256:a5bcffb52081ba39df0d5e9a884fc6f819d92e3a42389343ba77cbf809fe1f45", size = 18799, upload-time = "2025-06-18T09:00:10.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/d5/349aba3dc421e73cbd4958c0ce0a4f1aa3a738bc0d7de75d2f40ed43a535/a2wsgi-1.10.10-py3-none-any.whl", hash = "sha256:d2b21379479718539dc15fce53b876251a0efe7615352dfe49f6ad1bc507848d", size = 17389, upload-time = "2025-06-18T09:00:09.676Z" }, +] + [[package]] name = "ag-ui-protocol" version = "0.1.10" @@ -1058,6 +1070,7 @@ standard-no-fastapi-cloud-cli = [ [package.dev-dependencies] dev = [ + { name = "a2wsgi" }, { name = "anyio", extra = ["trio"] }, { name = "black" }, { name = "cairosvg" }, @@ -1131,6 +1144,7 @@ github-actions = [ { name = "smokeshow" }, ] tests = [ + { name = "a2wsgi" }, { name = "anyio", extra = ["trio"] }, { name = "coverage", version = "7.10.7", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.10'" }, { name = "coverage", version = "7.13.1", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.10'" }, @@ -1197,6 +1211,7 @@ provides-extras = ["standard", "standard-no-fastapi-cloud-cli", "all"] [package.metadata.requires-dev] dev = [ + { name = "a2wsgi", specifier = ">=1.9.0,<=2.0.0" }, { name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" }, { name = "black", specifier = "==25.1.0" }, { name = "cairosvg", specifier = "==2.8.2" }, @@ -1266,6 +1281,7 @@ github-actions = [ { name = "smokeshow", specifier = ">=0.5.0" }, ] tests = [ + { name = "a2wsgi", specifier = ">=1.9.0,<=2.0.0" }, { name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" }, { name = "coverage", extras = ["toml"], specifier = ">=6.5.0,<8.0" }, { name = "dirty-equals", specifier = "==0.9.0" },