Compare commits

..

5 Commits

Author SHA1 Message Date
github-actions[bot]
dfadf80f48 🎨 Auto format 2026-01-22 11:22:53 +00:00
Yurii Motov
0e65c3167f Fix coverage 2026-01-22 12:22:20 +01:00
Yurii Motov
ef76935b10 Remove WSGIMiddleware from API reference 2026-01-22 12:18:57 +01:00
Yurii Motov
f55d2ee641 Add a2wsgi to test dependencies 2026-01-22 12:14:35 +01:00
Yurii Motov
c8f4a1b0d4 Update code example and docs page 2026-01-22 11:52:12 +01:00
16 changed files with 69 additions and 72 deletions

1
.github/labeler.yml vendored
View File

@@ -31,7 +31,6 @@ internal:
- .pre-commit-config.yaml
- pdm_build.py
- requirements*.txt
- uv.lock
- docs/en/data/sponsors.yml
- docs/en/overrides/main.html
- all-globs-to-all-files:

View File

@@ -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

View File

@@ -56,19 +56,19 @@ from app.routers import items
Die gleiche Dateistruktur mit Kommentaren:
```bash
```
.
├── app # "app" ist ein Python-Package
│   ├── __init__.py # diese Datei macht "app" zu einem "Python-Package"
│   ├── main.py # "main"-Modul, z. B. import app.main
│   ├── dependencies.py # "dependencies"-Modul, z. B. import app.dependencies
│   └── routers # "routers" ist ein "Python-Subpackage"
│   │ ├── __init__.py # macht "routers" zu einem "Python-Subpackage"
│   │ ├── items.py # "items"-Submodul, z. B. import app.routers.items
│   │ └── users.py # "users"-Submodul, z. B. import app.routers.users
│   └── internal # "internal" ist ein "Python-Subpackage"
│   ├── __init__.py # macht "internal" zu einem "Python-Subpackage"
│   └── admin.py # "admin"-Submodul, z. B. import app.internal.admin
├── app # app ist ein Python-Package
│   ├── __init__.py # diese Datei macht app zu einem Python-Package
│   ├── main.py # main-Modul, z. B. import app.main
│   ├── dependencies.py # dependencies-Modul, z. B. import app.dependencies
│   └── routers # routers ist ein Python-Subpackage
│   │ ├── __init__.py # macht routers zu einem Python-Subpackage
│   │ ├── items.py # items-Submodul, z. B. import app.routers.items
│   │ └── users.py # users-Submodul, z. B. import app.routers.users
│   └── internal # internal ist ein Python-Subpackage
│   ├── __init__.py # macht internal zu einem Python-Subpackage
│   └── admin.py # admin-Submodul, z. B. import app.internal.admin
```
## `APIRouter` { #apirouter }
@@ -479,7 +479,7 @@ $ fastapi dev app/main.py
</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:

View File

@@ -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.
Its 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 }

View File

@@ -60,7 +60,8 @@ FastAPI also includes these JavaScript-only `presets` settings:
```JavaScript
presets: [
SwaggerUIBundle.presets.apis
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
]
```

View File

@@ -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
```

View File

@@ -18,8 +18,6 @@ hide:
### Translations
* 🌐 Update translations for de (update-outdated). PR [#14690](https://github.com/fastapi/fastapi/pull/14690) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update LLM prompt for Russian translations. PR [#14733](https://github.com/fastapi/fastapi/pull/14733) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for ru (update-outdated). PR [#14693](https://github.com/fastapi/fastapi/pull/14693) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (update-outdated). PR [#14724](https://github.com/fastapi/fastapi/pull/14724) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update Korean LLM prompt. PR [#14740](https://github.com/fastapi/fastapi/pull/14740) by [@hard-coders](https://github.com/hard-coders).
@@ -36,7 +34,6 @@ hide:
### Internal
* 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#14759](https://github.com/fastapi/fastapi/pull/14759) by [@svlandeg](https://github.com/svlandeg).
* 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors, LambdaTest changes to TestMu AI. PR [#14734](https://github.com/fastapi/fastapi/pull/14734) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump actions/cache from 4 to 5. PR [#14511](https://github.com/fastapi/fastapi/pull/14511) by [@dependabot[bot]](https://github.com/apps/dependabot).

View File

@@ -90,12 +90,5 @@ For the following technical terms, use these specific translations to ensure con
* serve (meaning providing access to something): «отдавать» (or `предоставлять доступ к`)
* recap (noun): резюме
* utility function: вспомогательная функция
* fast to code: позволяет быстро писать код
* Tutorial - User Guide: Учебник - Руководство пользователя
* submodule: подмодуль
* subpackage: подпакет
* router: роутер
* building, deploying, accessing (when describing features of FastAPI Cloud): созданиe образа, развертывание и доступ
* type checker tool: инструмент проверки типов
Do not add whitespace in `т.д.`, `т.п.`.

View File

@@ -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

View File

@@ -1 +1,3 @@
from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware # noqa
from starlette.middleware.wsgi import (
WSGIMiddleware as WSGIMiddleware,
) # pragma: no cover # noqa

View File

@@ -54,14 +54,6 @@ def get_swagger_ui_html(
"""
),
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
swagger_extra_js_urls: Annotated[
Optional[list[str]],
Doc(
"""
The URLs of additional JavaScript files to include.
"""
),
] = None,
swagger_css_url: Annotated[
str,
Doc(
@@ -106,14 +98,6 @@ def get_swagger_ui_html(
"""
),
] = None,
swagger_extra_presets: Annotated[
Optional[list[str]],
Doc(
"""
Extra presets to add to Swagger UI.
"""
),
] = None,
) -> HTMLResponse:
"""
Generate and return the HTML that loads Swagger UI for the interactive
@@ -130,13 +114,6 @@ def get_swagger_ui_html(
if swagger_ui_parameters:
current_swagger_ui_parameters.update(swagger_ui_parameters)
js_urls = [swagger_js_url]
if swagger_extra_js_urls:
js_urls.extend(swagger_extra_js_urls)
scripts_str = "\n ".join(
f'<script src="{js_url}"></script>' for js_url in js_urls
)
html = f"""
<!DOCTYPE html>
<html>
@@ -148,7 +125,7 @@ def get_swagger_ui_html(
<body>
<div id="swagger-ui">
</div>
{scripts_str}
<script src="{swagger_js_url}"></script>
<!-- `SwaggerUIBundle` is now available on the page -->
<script>
const ui = SwaggerUIBundle({{
@@ -161,18 +138,12 @@ def get_swagger_ui_html(
if oauth2_redirect_url:
html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"
presets = ["SwaggerUIBundle.presets.apis"]
if swagger_extra_presets:
presets.extend(swagger_extra_presets)
presets_str = ",\n ".join(presets)
html += f"""
html += """
presets: [
{presets_str},
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
"""
html += " })"
})"""
if init_oauth:
html += f"""

View File

@@ -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.45",

View File

@@ -18,6 +18,9 @@ def test_swagger_ui():
assert "SwaggerUIBundle.presets.apis," in response.text, (
"default configs should be preserved"
)
assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
"default configs should be preserved"
)
assert '"layout": "BaseLayout",' in response.text, (
"default configs should be preserved"
)

View File

@@ -21,6 +21,9 @@ def test_swagger_ui():
assert "SwaggerUIBundle.presets.apis," in response.text, (
"default configs should be preserved"
)
assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
"default configs should be preserved"
)
assert '"layout": "BaseLayout",' in response.text, (
"default configs should be preserved"
)

View File

@@ -24,6 +24,9 @@ def test_swagger_ui():
assert "SwaggerUIBundle.presets.apis," in response.text, (
"default configs should be preserved"
)
assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
"default configs should be preserved"
)
assert '"layout": "BaseLayout",' in response.text, (
"default configs should be preserved"
)

16
uv.lock generated
View File

@@ -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" },