diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c430854265..8a839a928a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,13 +46,6 @@ jobs: python-version: [ "3.14" ] pydantic-version: [ "pydantic>=2.0.2,<3.0.0" ] include: - - os: macos-latest - python-version: "3.8" - pydantic-version: "pydantic>=1.10.0,<2.0.0" - - os: windows-latest - python-version: "3.8" - pydantic-version: "pydantic>=2.0.2,<3.0.0" - coverage: coverage - os: ubuntu-latest python-version: "3.9" pydantic-version: "pydantic>=1.10.0,<2.0.0" @@ -101,10 +94,6 @@ jobs: run: uv pip install -r requirements-tests.txt - name: Install Pydantic run: uv pip install "${{ matrix.pydantic-version }}" - # 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 @@ -131,7 +120,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: - python-version: '3.8' + python-version: '3.11' - name: Setup uv uses: astral-sh/setup-uv@v7 with: diff --git a/docs/de/docs/advanced/additional-responses.md b/docs/de/docs/advanced/additional-responses.md index 29a0a14777..0f9b122516 100644 --- a/docs/de/docs/advanced/additional-responses.md +++ b/docs/de/docs/advanced/additional-responses.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: -{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *} +{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *} /// 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: -{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *} +{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *} Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt: diff --git a/docs/de/docs/advanced/async-tests.md b/docs/de/docs/advanced/async-tests.md index ad82452052..7206f136fd 100644 --- a/docs/de/docs/advanced/async-tests.md +++ b/docs/de/docs/advanced/async-tests.md @@ -32,11 +32,11 @@ Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [Größ Die Datei `main.py` hätte als Inhalt: -{* ../../docs_src/async_tests/main.py *} +{* ../../docs_src/async_tests/app_a_py39/main.py *} 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_py39/test_main.py *} ## 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: -{* ../../docs_src/async_tests/test_main.py hl[7] *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *} /// 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. -{* ../../docs_src/async_tests/test_main.py hl[9:12] *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *} Das ist das Äquivalent zu: diff --git a/docs/de/docs/advanced/behind-a-proxy.md b/docs/de/docs/advanced/behind-a-proxy.md index 183d0beeef..1c74590503 100644 --- a/docs/de/docs/advanced/behind-a-proxy.md +++ b/docs/de/docs/advanced/behind-a-proxy.md @@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*" Angenommen, Sie definieren eine *Pfadoperation* `/items/`: -{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *} 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. -{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *} Und der Proxy würde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den Request 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. -{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *} Wenn Sie Uvicorn dann starten mit: @@ -220,7 +220,7 @@ wäre die Dictionary 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`. -{* ../../docs_src/events/tutorial003.py hl[14:19] *} +{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *} 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. -{* ../../docs_src/events/tutorial003.py hl[1,13] *} +{* ../../docs_src/events/tutorial003_py39.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: @@ -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. -{* ../../docs_src/events/tutorial003.py hl[22] *} +{* ../../docs_src/events/tutorial003_py39.py hl[22] *} ## Alternative Events (deprecatet) { #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`: -{* ../../docs_src/events/tutorial001.py hl[8] *} +{* ../../docs_src/events/tutorial001_py39.py hl[8] *} 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`: -{* ../../docs_src/events/tutorial002.py hl[6] *} +{* ../../docs_src/events/tutorial002_py39.py hl[6] *} Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`. diff --git a/docs/de/docs/advanced/generate-clients.md b/docs/de/docs/advanced/generate-clients.md index d8836295b6..659343f5bc 100644 --- a/docs/de/docs/advanced/generate-clients.md +++ b/docs/de/docs/advanced/generate-clients.md @@ -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**: -{* ../../docs_src/generate_clients/tutorial004.py *} +{* ../../docs_src/generate_clients/tutorial004_py39.py *} //// tab | Node.js diff --git a/docs/de/docs/advanced/middleware.md b/docs/de/docs/advanced/middleware.md index 8396a626b6..ccc6a64c3b 100644 --- a/docs/de/docs/advanced/middleware.md +++ b/docs/de/docs/advanced/middleware.md @@ -57,13 +57,13 @@ Erzwingt, dass alle eingehenden geparst, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen. diff --git a/docs/de/docs/advanced/response-change-status-code.md b/docs/de/docs/advanced/response-change-status-code.md index b079e241d1..b209c2d671 100644 --- a/docs/de/docs/advanced/response-change-status-code.md +++ b/docs/de/docs/advanced/response-change-status-code.md @@ -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* Response-Objekt festlegen. -{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} +{* ../../docs_src/response_change_status_code/tutorial001_py39.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.). diff --git a/docs/de/docs/advanced/response-cookies.md b/docs/de/docs/advanced/response-cookies.md index 02fe99c26a..87e636cfaf 100644 --- a/docs/de/docs/advanced/response-cookies.md +++ b/docs/de/docs/advanced/response-cookies.md @@ -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* Response-Objekt setzen. -{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *} +{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *} 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: -{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *} /// tip | Tipp diff --git a/docs/de/docs/advanced/response-directly.md b/docs/de/docs/advanced/response-directly.md index 06ec2c32ed..0a28a6d0e2 100644 --- a/docs/de/docs/advanced/response-directly.md +++ b/docs/de/docs/advanced/response-directly.md @@ -54,7 +54,7 @@ Nehmen wir an, Sie möchten eine Response-Objekt festlegen. -{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *} +{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *} 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: -{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *} /// note | Technische Details diff --git a/docs/de/docs/advanced/settings.md b/docs/de/docs/advanced/settings.md index 03263a28b0..ebacf76f42 100644 --- a/docs/de/docs/advanced/settings.md +++ b/docs/de/docs/advanced/settings.md @@ -62,7 +62,7 @@ Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für //// tab | Pydantic v2 -{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *} +{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *} //// @@ -74,7 +74,7 @@ In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydan /// -{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *} +{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *} //// @@ -92,7 +92,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: -{* ../../docs_src/settings/tutorial001.py hl[18:20] *} +{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *} ### Den Server ausführen { #run-the-server } @@ -126,11 +126,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: -{* ../../docs_src/settings/app01/config.py *} +{* ../../docs_src/settings/app01_py39/config.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_py39/main.py hl[3,11:13] *} /// tip | Tipp diff --git a/docs/de/docs/advanced/sub-applications.md b/docs/de/docs/advanced/sub-applications.md index d634aac23b..081574d0a9 100644 --- a/docs/de/docs/advanced/sub-applications.md +++ b/docs/de/docs/advanced/sub-applications.md @@ -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*: -{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *} +{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *} ### 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“: -{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *} +{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *} ### 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: -{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *} +{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *} ### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs } diff --git a/docs/de/docs/advanced/templates.md b/docs/de/docs/advanced/templates.md index 65c7998b8a..97a45e6126 100644 --- a/docs/de/docs/advanced/templates.md +++ b/docs/de/docs/advanced/templates.md @@ -27,7 +27,7 @@ $ pip install jinja2 * Deklarieren Sie einen `Request`-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“-Dictionary 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_py39.py hl[4,11,15:18] *} /// note | Hinweis diff --git a/docs/de/docs/advanced/testing-events.md b/docs/de/docs/advanced/testing-events.md index 569518c51d..5b12f3f186 100644 --- a/docs/de/docs/advanced/testing-events.md +++ b/docs/de/docs/advanced/testing-events.md @@ -2,11 +2,11 @@ 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_py39.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. Für die deprecateten Events `startup` und `shutdown` können Sie den `TestClient` wie folgt verwenden: -{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *} +{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *} diff --git a/docs/de/docs/advanced/testing-websockets.md b/docs/de/docs/advanced/testing-websockets.md index f25aa4fd04..9ecca7a4f7 100644 --- a/docs/de/docs/advanced/testing-websockets.md +++ b/docs/de/docs/advanced/testing-websockets.md @@ -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: -{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *} +{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *} /// note | Hinweis diff --git a/docs/de/docs/advanced/using-request-directly.md b/docs/de/docs/advanced/using-request-directly.md index 8ec6741d07..36d73b8067 100644 --- a/docs/de/docs/advanced/using-request-directly.md +++ b/docs/de/docs/advanced/using-request-directly.md @@ -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. -{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *} +{* ../../docs_src/using_request_directly/tutorial001_py39.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. diff --git a/docs/de/docs/advanced/websockets.md b/docs/de/docs/advanced/websockets.md index 5f662770f0..05ae5a4b31 100644 --- a/docs/de/docs/advanced/websockets.md +++ b/docs/de/docs/advanced/websockets.md @@ -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: -{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *} ## Einen `websocket` erstellen { #create-a-websocket } Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`: -{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *} /// 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. -{* ../../docs_src/websockets/tutorial001.py hl[48:52] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *} Sie können Binär-, Text- und JSON-Daten empfangen und senden. diff --git a/docs/de/docs/advanced/wsgi.md b/docs/de/docs/advanced/wsgi.md index 1de9739dde..3cd776a6ab 100644 --- a/docs/de/docs/advanced/wsgi.md +++ b/docs/de/docs/advanced/wsgi.md @@ -12,7 +12,7 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware. Und dann mounten Sie das auf einem Pfad. -{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *} +{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *} ## Es testen { #check-it } diff --git a/docs/de/docs/how-to/conditional-openapi.md b/docs/de/docs/how-to/conditional-openapi.md index f6a2fad3bc..6e665cc4c0 100644 --- a/docs/de/docs/how-to/conditional-openapi.md +++ b/docs/de/docs/how-to/conditional-openapi.md @@ -29,7 +29,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener Zum Beispiel: -{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *} +{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *} Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`. diff --git a/docs/de/docs/how-to/configure-swagger-ui.md b/docs/de/docs/how-to/configure-swagger-ui.md index 3616f03ac4..1c3f5c0c5a 100644 --- a/docs/de/docs/how-to/configure-swagger-ui.md +++ b/docs/de/docs/how-to/configure-swagger-ui.md @@ -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: -{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *} ... 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): -{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *} Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern: @@ -46,7 +46,7 @@ Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_paramet 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_py39.py hl[3] *} ## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters } diff --git a/docs/de/docs/how-to/custom-docs-ui-assets.md b/docs/de/docs/how-to/custom-docs-ui-assets.md index 6b8b1a1767..6b1d654adf 100644 --- a/docs/de/docs/how-to/custom-docs-ui-assets.md +++ b/docs/de/docs/how-to/custom-docs-ui-assets.md @@ -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`: -{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *} +{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *} ### 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 ... -{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *} +{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *} /// 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*: -{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *} +{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *} ### Es testen { #test-it } @@ -118,7 +118,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen: * Importieren Sie `StaticFiles`. * „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_py39.py hl[7,11] *} ### 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`: -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *} ### 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 ... -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *} /// 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*: -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *} ### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui } diff --git a/docs/de/docs/how-to/extending-openapi.md b/docs/de/docs/how-to/extending-openapi.md index 146ee098bc..c07ed2aa08 100644 --- a/docs/de/docs/how-to/extending-openapi.md +++ b/docs/de/docs/how-to/extending-openapi.md @@ -43,19 +43,19 @@ Fügen wir beispielsweise Requests verwendet. -{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *} +{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *} ### Die Methode überschreiben { #override-the-method } 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_py39.py hl[29] *} ### Es testen { #check-it } diff --git a/docs/de/docs/how-to/graphql.md b/docs/de/docs/how-to/graphql.md index d2958dcd9e..0583faf4a3 100644 --- a/docs/de/docs/how-to/graphql.md +++ b/docs/de/docs/how-to/graphql.md @@ -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: -{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *} +{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *} Weitere Informationen zu Strawberry finden Sie in der Strawberry-Dokumentation. diff --git a/docs/de/docs/project-generation.md b/docs/de/docs/project-generation.md index 290f605b38..62702d8529 100644 --- a/docs/de/docs/project-generation.md +++ b/docs/de/docs/project-generation.md @@ -13,7 +13,7 @@ GitHub-Repository: Verkettet sie mit einem Leerzeichen in der Mitte. +* Verkettet sie mit einem Leerzeichen in der Mitte. -{* ../../docs_src/python_types/tutorial001.py hl[2] *} +{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *} ### Es bearbeiten { #edit-it } @@ -78,7 +78,7 @@ Das war's. Das sind die „Typhinweise“: -{* ../../docs_src/python_types/tutorial002.py hl[1] *} +{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *} 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: -{* ../../docs_src/python_types/tutorial003.py hl[1] *} +{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *} 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: -{* ../../docs_src/python_types/tutorial004.py hl[2] *} +{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *} ## Deklarieren von Typen { #declaring-types } @@ -133,7 +133,7 @@ Zum Beispiel diese: * `bool` * `bytes` -{* ../../docs_src/python_types/tutorial005.py hl[1] *} +{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *} ### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters } @@ -161,56 +161,24 @@ Wenn Sie über die **neueste Version von Python** verfügen, verwenden Sie die B 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 (`:`). Als Typ nehmen Sie `list`. 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_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!} -``` - -//// +{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *} /// info | Info 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`. -/// 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: @@ -225,21 +193,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`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *} Das bedeutet: @@ -254,21 +208,7 @@ Der erste Typ-Parameter ist für die Schlüssel des `dict`. Der zweite Typ-Parameter ist für die Werte des `dict`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *} Das bedeutet: @@ -282,7 +222,7 @@ Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** se 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. -In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem vertikalen Balken (`|`) aufzulisten. +In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem vertikalen Balken (`|`) aufzulisten. //// tab | Python 3.10+ @@ -292,10 +232,10 @@ In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die mö //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} +{!> ../../docs_src/python_types/tutorial008b_py39.py!} ``` //// @@ -309,7 +249,7 @@ Sie können deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` se 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!} +{!../../docs_src/python_types/tutorial009_py39.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. @@ -326,18 +266,18 @@ Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können: //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} +{!> ../../docs_src/python_types/tutorial009_py39.py!} ``` //// -//// tab | Python 3.8+ Alternative +//// tab | Python 3.9+ Alternative ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} +{!> ../../docs_src/python_types/tutorial009b_py39.py!} ``` //// @@ -353,11 +293,11 @@ Beide sind äquivalent und im Hintergrund dasselbe, aber ich empfehle `Union` st 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. +Es geht nur um Worte 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] *} +{* ../../docs_src/python_types/tutorial009c_py39.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: @@ -390,13 +330,13 @@ Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern u * `set` * `dict` -Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul: +Und ebenso wie bei früheren Python-Versionen, aus dem `typing`-Modul: * `Union` -* `Optional` (so wie unter Python 3.8) +* `Optional` * ... und andere. -In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den vertikalen Balken (`|`) verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher. +In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den vertikalen Balken (`|`) verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher. //// @@ -409,7 +349,7 @@ Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern u * `set` * `dict` -Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul: +Und Generics aus dem `typing`-Modul: * `Union` * `Optional` @@ -417,29 +357,17 @@ Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul: //// -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ... und andere. - -//// - ### Klassen als Typen { #classes-as-types } Sie können auch eine Klasse als Typ einer Variablen deklarieren. 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_py39.py hl[1:3] *} Dann können Sie eine Variable vom Typ `Person` deklarieren: -{* ../../docs_src/python_types/tutorial010.py hl[6] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *} Und wiederum bekommen Sie die volle Editor-Unterstützung: @@ -463,29 +391,7 @@ Und Sie erhalten volle Editor-Unterstützung für dieses Objekt. Ein Beispiel aus der offiziellen Pydantic Dokumentation: -//// tab | Python 3.10+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial011_py310.py *} /// info | Info @@ -507,27 +413,9 @@ Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None Python bietet auch die Möglichkeit, **zusätzliche Metadaten** in Typhinweisen unterzubringen, mittels `Annotated`. -//// tab | Python 3.9+ +Seit Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren. -In Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren. - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *} Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`. diff --git a/docs/de/docs/tutorial/background-tasks.md b/docs/de/docs/tutorial/background-tasks.md index 2c381ccfac..1d34430dc6 100644 --- a/docs/de/docs/tutorial/background-tasks.md +++ b/docs/de/docs/tutorial/background-tasks.md @@ -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`: -{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *} **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`: -{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *} ## 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: -{* ../../docs_src/background_tasks/tutorial001.py hl[14] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *} `.add_task()` erhält als Argumente: diff --git a/docs/de/docs/tutorial/body-nested-models.md b/docs/de/docs/tutorial/body-nested-models.md index 324d31928d..65a5d7c1de 100644 --- a/docs/de/docs/tutorial/body-nested-models.md +++ b/docs/de/docs/tutorial/body-nested-models.md @@ -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. -### `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 } -Um Typen wie `list`, `dict`, `tuple` mit inneren Typ-Parametern (inneren Typen) zu deklarieren: - -* 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: +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 `]` ```Python 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. Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen. @@ -178,12 +157,6 @@ 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: -```Python -images: List[Image] -``` - -oder in Python 3.9 und darüber: - ```Python images: list[Image] ``` diff --git a/docs/de/docs/tutorial/body.md b/docs/de/docs/tutorial/body.md index 1e6382b6f2..0ad95b0386 100644 --- a/docs/de/docs/tutorial/body.md +++ b/docs/de/docs/tutorial/body.md @@ -162,7 +162,7 @@ Die Funktionsparameter werden wie folgt erkannt: 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` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.9+) 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. diff --git a/docs/de/docs/tutorial/cors.md b/docs/de/docs/tutorial/cors.md index 191a7b4ef3..81f0f36051 100644 --- a/docs/de/docs/tutorial/cors.md +++ b/docs/de/docs/tutorial/cors.md @@ -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-Header oder alle mit der Wildcard `"*"`. -{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *} +{* ../../docs_src/cors/tutorial001_py39.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. diff --git a/docs/de/docs/tutorial/debugging.md b/docs/de/docs/tutorial/debugging.md index 0a31f86536..0d12877c10 100644 --- a/docs/de/docs/tutorial/debugging.md +++ b/docs/de/docs/tutorial/debugging.md @@ -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: -{* ../../docs_src/debugging/tutorial001.py hl[1,15] *} +{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *} ### Über `__name__ == "__main__"` { #about-name-main } diff --git a/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md index 3d4493f353..7df0842eb1 100644 --- a/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/de/docs/tutorial/dependencies/classes-as-dependencies.md @@ -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: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ nicht annotiert +//// tab | Python 3.9+ nicht annotiert /// 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: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, ... @@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ... //// -//// tab | Python 3.8+ nicht annotiert +//// tab | Python 3.9+ nicht annotiert /// tip | Tipp @@ -163,7 +163,7 @@ commons: CommonQueryParams ... Sie könnten tatsächlich einfach schreiben: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[Any, Depends(CommonQueryParams)] @@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ nicht annotiert +//// tab | Python 3.9+ nicht annotiert /// 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: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ nicht annotiert +//// tab | Python 3.9+ nicht annotiert /// tip | Tipp @@ -225,7 +225,7 @@ In diesem speziellen Fall können Sie Folgendes tun: Anstatt zu schreiben: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ nicht annotiert +//// tab | Python 3.9+ nicht annotiert /// tip | Tipp @@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ... schreiben Sie: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends()] @@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()] //// -//// tab | Python 3.8 nicht annotiert +//// tab | Python 3.9+ nicht annotiert /// tip | Tipp diff --git a/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md index 34db6c6bed..0083e7e7ea 100644 --- a/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/de/docs/tutorial/dependencies/dependencies-with-yield.md @@ -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 Response erzeugt wird: -{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *} 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_py39.py hl[4] *} 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_py39.py hl[5:6] *} /// 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. -{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *} ## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield } @@ -268,7 +268,7 @@ In Python können Sie Kontextmanager erstellen, indem Sie Requests zuständig ist, die an: @@ -320,7 +320,7 @@ Das ist unsere „**Pfadoperation-Funktion**“: * **Operation**: ist `get`. * **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`). -{* ../../docs_src/first_steps/tutorial001.py hl[7] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *} Dies ist eine Python-Funktion. @@ -332,7 +332,7 @@ In diesem Fall handelt es sich um eine `async`-Funktion. Sie könnten sie auch als normale Funktion anstelle von `async def` definieren: -{* ../../docs_src/first_steps/tutorial003.py hl[7] *} +{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *} /// note | Hinweis @@ -342,7 +342,7 @@ Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../as ### Schritt 5: den Inhalt zurückgeben { #step-5-return-the-content } -{* ../../docs_src/first_steps/tutorial001.py hl[8] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *} Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben. diff --git a/docs/de/docs/tutorial/handling-errors.md b/docs/de/docs/tutorial/handling-errors.md index a39c3db37a..d890b44629 100644 --- a/docs/de/docs/tutorial/handling-errors.md +++ b/docs/de/docs/tutorial/handling-errors.md @@ -25,7 +25,7 @@ Um HTTP-deprecatet kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu: -{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *} +{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *} Sie wird in der interaktiven Dokumentation gut sichtbar als deprecatet markiert werden: diff --git a/docs/de/docs/tutorial/path-params-numeric-validations.md b/docs/de/docs/tutorial/path-params-numeric-validations.md index 5b74749447..8b52e8b42f 100644 --- a/docs/de/docs/tutorial/path-params-numeric-validations.md +++ b/docs/de/docs/tutorial/path-params-numeric-validations.md @@ -54,7 +54,7 @@ Für **FastAPI** spielt es keine Rolle. Es erkennt die Parameter anhand ihrer Na Sie können Ihre Funktion also so deklarieren: -{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *} Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da es nicht darauf ankommt, dass Sie keine Funktionsparameter-Defaultwerte für `Query()` oder `Path()` verwenden. @@ -83,7 +83,7 @@ Wenn Sie: Python wird nichts mit diesem `*` machen, aber es wird wissen, dass alle folgenden Parameter als Schlüsselwortargumente (Schlüssel-Wert-Paare) verwendet werden sollen, auch bekannt als kwargs. Selbst wenn diese keinen Defaultwert haben. -{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *} ### Besser mit `Annotated` { #better-with-annotated } diff --git a/docs/de/docs/tutorial/path-params.md b/docs/de/docs/tutorial/path-params.md index 1db288fb87..1de4973155 100644 --- a/docs/de/docs/tutorial/path-params.md +++ b/docs/de/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-Formatstrings verwendet wird: -{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} +{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *} Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben. @@ -16,7 +16,7 @@ Wenn Sie dieses Beispiel ausführen und auf Enumerationen (oder Enums) gibt es in Python seit Version 3.4. - -/// /// tip | Tipp @@ -158,7 +153,7 @@ Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`): -{* ../../docs_src/path_params/tutorial005.py hl[16] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *} ### Die API-Dokumentation testen { #check-the-docs } @@ -174,13 +169,13 @@ Der *Pfad-Parameter* wird ein *Query ist die Menge von Schlüssel-Wert-Paaren, die nach dem `?` in einer URL folgen und durch `&`-Zeichen getrennt sind. @@ -127,7 +127,7 @@ Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach op Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert: -{* ../../docs_src/query_params/tutorial005.py hl[6:7] *} +{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *} Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`. diff --git a/docs/de/docs/tutorial/response-model.md b/docs/de/docs/tutorial/response-model.md index 7b77125cb5..4c0205b31f 100644 --- a/docs/de/docs/tutorial/response-model.md +++ b/docs/de/docs/tutorial/response-model.md @@ -183,7 +183,7 @@ Es kann Fälle geben, bei denen Sie etwas zurückgeben, das kein gültiges Pydan Der häufigste Anwendungsfall ist, wenn Sie [eine Response direkt zurückgeben, wie es später im Handbuch für fortgeschrittene Benutzer erläutert wird](../advanced/response-directly.md){.internal-link target=_blank}. -{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *} +{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *} Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist. @@ -193,7 +193,7 @@ Und Tools werden auch glücklich sein, weil sowohl `RedirectResponse` als auch ` Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden. -{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *} +{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *} Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert. diff --git a/docs/de/docs/tutorial/response-status-code.md b/docs/de/docs/tutorial/response-status-code.md index 928003c3fc..fd17c99336 100644 --- a/docs/de/docs/tutorial/response-status-code.md +++ b/docs/de/docs/tutorial/response-status-code.md @@ -8,7 +8,7 @@ Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-St * `@app.delete()` * usw. -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} /// note | Hinweis @@ -74,7 +74,7 @@ Um mehr über die einzelnen Statuscodes zu erfahren und welcher wofür verwendet Lassen Sie uns das vorherige Beispiel noch einmal anschauen: -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} `201` ist der Statuscode für „Created“ („Erzeugt“). @@ -82,7 +82,7 @@ Aber Sie müssen sich nicht merken, was jeder dieser Codes bedeutet. Sie können die Annehmlichkeit von Variablen aus `fastapi.status` nutzen. -{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *} +{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *} Diese sind nur eine Annehmlichkeit, sie enthalten dieselbe Zahl, aber so können Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden: diff --git a/docs/de/docs/tutorial/static-files.md b/docs/de/docs/tutorial/static-files.md index 0c4e7c8abd..9ba2501756 100644 --- a/docs/de/docs/tutorial/static-files.md +++ b/docs/de/docs/tutorial/static-files.md @@ -7,7 +7,7 @@ Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisc * Importieren Sie `StaticFiles`. * „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad. -{* ../../docs_src/static_files/tutorial001.py hl[2,6] *} +{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *} /// note | Technische Details diff --git a/docs/de/docs/tutorial/testing.md b/docs/de/docs/tutorial/testing.md index b18469998d..d889b1e1fb 100644 --- a/docs/de/docs/tutorial/testing.md +++ b/docs/de/docs/tutorial/testing.md @@ -30,7 +30,7 @@ Verwenden Sie das `TestClient`-Objekt auf die gleiche Weise wie `httpx`. Schreiben Sie einfache `assert`-Anweisungen mit den Standard-Python-Ausdrücken, die Sie überprüfen müssen (wiederum, Standard-`pytest`). -{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *} +{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *} /// tip | Tipp @@ -76,7 +76,7 @@ Nehmen wir an, Sie haben eine Dateistruktur wie in [Größere Anwendungen](bigge In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung: -{* ../../docs_src/app_testing/main.py *} +{* ../../docs_src/app_testing/app_a_py39/main.py *} ### Testdatei { #testing-file } @@ -93,7 +93,7 @@ Dann könnten Sie eine Datei `test_main.py` mit Ihren Tests haben. Sie könnte s Da sich diese Datei im selben Package befindet, können Sie relative Importe verwenden, um das Objekt `app` aus dem `main`-Modul (`main.py`) zu importieren: -{* ../../docs_src/app_testing/test_main.py hl[3] *} +{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *} ... und haben den Code für die Tests wie zuvor. diff --git a/docs/en/docs/advanced/additional-responses.md b/docs/en/docs/advanced/additional-responses.md index cb3a40d13e..bb70753edd 100644 --- a/docs/en/docs/advanced/additional-responses.md +++ b/docs/en/docs/advanced/additional-responses.md @@ -26,7 +26,7 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write: -{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *} +{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *} /// note @@ -203,7 +203,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd And a response with a status code `200` that uses your `response_model`, but includes a custom `example`: -{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *} +{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *} It will all be combined and included in your OpenAPI, and shown in the API docs: diff --git a/docs/en/docs/advanced/async-tests.md b/docs/en/docs/advanced/async-tests.md index e920e22c3c..65ddc60b2d 100644 --- a/docs/en/docs/advanced/async-tests.md +++ b/docs/en/docs/advanced/async-tests.md @@ -32,11 +32,11 @@ For a simple example, let's consider a file structure similar to the one describ The file `main.py` would have: -{* ../../docs_src/async_tests/main.py *} +{* ../../docs_src/async_tests/app_a_py39/main.py *} The file `test_main.py` would have the tests for `main.py`, it could look like this now: -{* ../../docs_src/async_tests/test_main.py *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py *} ## Run it { #run-it } @@ -56,7 +56,7 @@ $ pytest The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously: -{* ../../docs_src/async_tests/test_main.py hl[7] *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *} /// tip @@ -66,7 +66,7 @@ Note that the test function is now `async def` instead of just `def` as before w Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`. -{* ../../docs_src/async_tests/test_main.py hl[9:12] *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *} This is the equivalent to: diff --git a/docs/en/docs/advanced/behind-a-proxy.md b/docs/en/docs/advanced/behind-a-proxy.md index f4dbd45607..4fef02bd1c 100644 --- a/docs/en/docs/advanced/behind-a-proxy.md +++ b/docs/en/docs/advanced/behind-a-proxy.md @@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*" For example, let's say you define a *path operation* `/items/`: -{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *} If the client tries to go to `/items`, by default, it would be redirected to `/items/`. @@ -115,7 +115,7 @@ In this case, the original path `/app` would actually be served at `/api/v1/app` Even though all your code is written assuming there's just `/app`. -{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *} And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`. @@ -193,7 +193,7 @@ You can get the current `root_path` used by your application for each request, i Here we are including it in the message just for demonstration purposes. -{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *} Then, if you start Uvicorn with: @@ -220,7 +220,7 @@ The response would be something like: Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app: -{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *} +{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *} Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn. @@ -400,7 +400,7 @@ If you pass a custom list of `servers` and there's a `root_path` (because your A For example: -{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *} +{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *} Will generate an OpenAPI schema like: @@ -455,7 +455,7 @@ If you don't specify the `servers` parameter and `root_path` is equal to `/`, th If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`: -{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *} +{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *} and then it won't include it in the OpenAPI schema. diff --git a/docs/en/docs/advanced/custom-response.md b/docs/en/docs/advanced/custom-response.md index 0f3d8b7017..e53409c39d 100644 --- a/docs/en/docs/advanced/custom-response.md +++ b/docs/en/docs/advanced/custom-response.md @@ -30,7 +30,7 @@ This is because by default, FastAPI will inspect every item inside and make sure But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class. -{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *} /// info @@ -55,7 +55,7 @@ To return a response with HTML directly from **FastAPI**, use `HTMLResponse`. * Import `HTMLResponse`. * Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*. -{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *} /// info @@ -73,7 +73,7 @@ As seen in [Return a Response directly](response-directly.md){.internal-link tar The same example from above, returning an `HTMLResponse`, could look like: -{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *} +{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *} /// warning @@ -97,7 +97,7 @@ The `response_class` will then be used only to document the OpenAPI *path operat For example, it could be something like: -{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *} +{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *} In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`. @@ -136,7 +136,7 @@ It accepts the following parameters: FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types. -{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} ### `HTMLResponse` { #htmlresponse } @@ -146,7 +146,7 @@ Takes some text or bytes and returns an HTML response, as you read above. Takes some text or bytes and returns a plain text response. -{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *} ### `JSONResponse` { #jsonresponse } @@ -180,7 +180,7 @@ This requires installing `ujson` for example with `pip install ujson`. /// -{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *} /// tip @@ -194,14 +194,14 @@ Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default You can return a `RedirectResponse` directly: -{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *} +{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *} --- Or you can use it in the `response_class` parameter: -{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *} If you do that, then you can return the URL directly from your *path operation* function. @@ -211,13 +211,13 @@ In this case, the `status_code` used will be the default one for the `RedirectRe You can also use the `status_code` parameter combined with the `response_class` parameter: -{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *} ### `StreamingResponse` { #streamingresponse } Takes an async generator or a normal generator/iterator and streams the response body. -{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} +{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *} #### Using `StreamingResponse` with file-like objects { #using-streamingresponse-with-file-like-objects } @@ -227,7 +227,7 @@ That way, you don't have to read it all first in memory, and you can pass that g This includes many libraries to interact with cloud storage, video processing, and others. -{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *} +{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *} 1. This is the generator function. It's a "generator function" because it contains `yield` statements inside. 2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response. @@ -256,11 +256,11 @@ Takes a different set of arguments to instantiate than the other response types: File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers. -{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *} +{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *} You can also use the `response_class` parameter: -{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *} +{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *} In this case, you can return the file path directly from your *path operation* function. @@ -274,7 +274,7 @@ Let's say you want it to return indented and formatted JSON, so you want to use You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`: -{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *} +{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *} Now instead of returning: @@ -300,7 +300,7 @@ The parameter that defines this is `default_response_class`. In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`. -{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *} +{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *} /// tip diff --git a/docs/en/docs/advanced/events.md b/docs/en/docs/advanced/events.md index d9e3cb52e7..9414b7a3f0 100644 --- a/docs/en/docs/advanced/events.md +++ b/docs/en/docs/advanced/events.md @@ -30,7 +30,7 @@ Let's start with an example and then see it in detail. We create an async function `lifespan()` with `yield` like this: -{* ../../docs_src/events/tutorial003.py hl[16,19] *} +{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *} Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*. @@ -48,7 +48,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷 The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`. -{* ../../docs_src/events/tutorial003.py hl[14:19] *} +{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *} The first part of the function, before the `yield`, will be executed **before** the application starts. @@ -60,7 +60,7 @@ If you check, the function is decorated with an `@asynccontextmanager`. That converts the function into something called an "**async context manager**". -{* ../../docs_src/events/tutorial003.py hl[1,13] *} +{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *} A **context manager** in Python is something that you can use in a `with` statement, for example, `open()` can be used as a context manager: @@ -82,7 +82,7 @@ In our code example above, we don't use it directly, but we pass it to FastAPI f The `lifespan` parameter of the `FastAPI` app takes an **async context manager**, so we can pass our new `lifespan` async context manager to it. -{* ../../docs_src/events/tutorial003.py hl[22] *} +{* ../../docs_src/events/tutorial003_py39.py hl[22] *} ## Alternative Events (deprecated) { #alternative-events-deprecated } @@ -104,7 +104,7 @@ These functions can be declared with `async def` or normal `def`. To add a function that should be run before the application starts, declare it with the event `"startup"`: -{* ../../docs_src/events/tutorial001.py hl[8] *} +{* ../../docs_src/events/tutorial001_py39.py hl[8] *} In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values. @@ -116,7 +116,7 @@ And your application won't start receiving requests until all the `startup` even To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`: -{* ../../docs_src/events/tutorial002.py hl[6] *} +{* ../../docs_src/events/tutorial002_py39.py hl[6] *} Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`. diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md index 897c308086..2d0c2aa0c9 100644 --- a/docs/en/docs/advanced/generate-clients.md +++ b/docs/en/docs/advanced/generate-clients.md @@ -167,7 +167,7 @@ But for the generated client, we could **modify** the OpenAPI operation IDs righ We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this: -{* ../../docs_src/generate_clients/tutorial004.py *} +{* ../../docs_src/generate_clients/tutorial004_py39.py *} //// tab | Node.js diff --git a/docs/en/docs/advanced/middleware.md b/docs/en/docs/advanced/middleware.md index 8deb0d917d..765b389329 100644 --- a/docs/en/docs/advanced/middleware.md +++ b/docs/en/docs/advanced/middleware.md @@ -57,13 +57,13 @@ Enforces that all incoming requests must either be `https` or `wss`. Any incoming request to `http` or `ws` will be redirected to the secure scheme instead. -{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *} +{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *} ## `TrustedHostMiddleware` { #trustedhostmiddleware } Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks. -{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *} +{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *} The following arguments are supported: @@ -78,7 +78,7 @@ Handles GZip responses for any request that includes `"gzip"` in the `Accept-Enc The middleware will handle both standard and streaming responses. -{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *} +{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *} The following arguments are supported: diff --git a/docs/en/docs/advanced/openapi-webhooks.md b/docs/en/docs/advanced/openapi-webhooks.md index 416cf4b75b..59f060c032 100644 --- a/docs/en/docs/advanced/openapi-webhooks.md +++ b/docs/en/docs/advanced/openapi-webhooks.md @@ -32,7 +32,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0` When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`. -{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *} +{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *} The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**. diff --git a/docs/en/docs/advanced/path-operation-advanced-configuration.md b/docs/en/docs/advanced/path-operation-advanced-configuration.md index 5879bc5c71..01196af79e 100644 --- a/docs/en/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/en/docs/advanced/path-operation-advanced-configuration.md @@ -12,7 +12,7 @@ You can set the OpenAPI `operationId` to be used in your *path operation* with t You would have to make sure that it is unique for each operation. -{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *} ### Using the *path operation function* name as the operationId { #using-the-path-operation-function-name-as-the-operationid } @@ -20,7 +20,7 @@ If you want to use your APIs' function names as `operationId`s, you can iterate You should do it after adding all your *path operations*. -{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *} /// tip @@ -40,7 +40,7 @@ Even if they are in different modules (Python files). To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`: -{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *} ## Advanced description from docstring { #advanced-description-from-docstring } @@ -92,7 +92,7 @@ You can extend the OpenAPI schema for a *path operation* using the parameter `op This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): -{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *} If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*. @@ -139,7 +139,7 @@ For example, you could decide to read and validate the request with your own cod You could do that with `openapi_extra`: -{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *} In this example, we didn't declare any Pydantic model. In fact, the request body is not even parsed as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way. diff --git a/docs/en/docs/advanced/response-change-status-code.md b/docs/en/docs/advanced/response-change-status-code.md index 912ed0f1a1..d9708aa627 100644 --- a/docs/en/docs/advanced/response-change-status-code.md +++ b/docs/en/docs/advanced/response-change-status-code.md @@ -20,7 +20,7 @@ You can declare a parameter of type `Response` in your *path operation function* And then you can set the `status_code` in that *temporal* response object. -{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} +{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *} And then you can return any object you need, as you normally would (a `dict`, a database model, etc). diff --git a/docs/en/docs/advanced/response-cookies.md b/docs/en/docs/advanced/response-cookies.md index 1f41d84b7c..5b6fab112b 100644 --- a/docs/en/docs/advanced/response-cookies.md +++ b/docs/en/docs/advanced/response-cookies.md @@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function* And then you can set cookies in that *temporal* response object. -{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *} +{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *} And then you can return any object you need, as you normally would (a `dict`, a database model, etc). @@ -24,7 +24,7 @@ To do that, you can create a response as described in [Return a Response Directl Then set Cookies in it, and then return it: -{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *} /// tip diff --git a/docs/en/docs/advanced/response-directly.md b/docs/en/docs/advanced/response-directly.md index 156b4dac7e..4374cb9637 100644 --- a/docs/en/docs/advanced/response-directly.md +++ b/docs/en/docs/advanced/response-directly.md @@ -54,7 +54,7 @@ Let's say that you want to return an Strawberry documentation. diff --git a/docs/en/docs/management-tasks.md b/docs/en/docs/management-tasks.md index 05cd5d27d0..aac4d6fe40 100644 --- a/docs/en/docs/management-tasks.md +++ b/docs/en/docs/management-tasks.md @@ -239,7 +239,7 @@ A PR should have a specific use case that it is solving. * If the PR is for a feature, it should have docs. * Unless it's a feature we want to discourage, like support for a corner case that we don't want users to use. * The docs should include a source example file, not write Python directly in Markdown. -* If the source example(s) file can have different syntax for Python 3.8, 3.9, 3.10, there should be different versions of the file, and they should be shown in tabs in the docs. +* If the source example(s) file can have different syntax for different Python versions, there should be different versions of the file, and they should be shown in tabs in the docs. * There should be tests testing the source example. * Before the PR is applied, the new tests should fail. * After applying the PR, the new tests should pass. diff --git a/docs/en/docs/python-types.md b/docs/en/docs/python-types.md index e4bd2a8749..b685deef29 100644 --- a/docs/en/docs/python-types.md +++ b/docs/en/docs/python-types.md @@ -22,7 +22,7 @@ If you are a Python expert, and you already know everything about type hints, sk Let's start with a simple example: -{* ../../docs_src/python_types/tutorial001.py *} +{* ../../docs_src/python_types/tutorial001_py39.py *} Calling this program outputs: @@ -36,7 +36,7 @@ The function does the following: * Converts the first letter of each one to upper case with `title()`. * Concatenates them with a space in the middle. -{* ../../docs_src/python_types/tutorial001.py hl[2] *} +{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *} ### Edit it { #edit-it } @@ -78,7 +78,7 @@ That's it. Those are the "type hints": -{* ../../docs_src/python_types/tutorial002.py hl[1] *} +{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *} That is not the same as declaring default values like would be with: @@ -106,7 +106,7 @@ With that, you can scroll, seeing the options, until you find the one that "ring Check this function, it already has type hints: -{* ../../docs_src/python_types/tutorial003.py hl[1] *} +{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *} Because the editor knows the types of the variables, you don't only get completion, you also get error checks: @@ -114,7 +114,7 @@ Because the editor knows the types of the variables, you don't only get completi Now you know that you have to fix it, convert `age` to a string with `str(age)`: -{* ../../docs_src/python_types/tutorial004.py hl[2] *} +{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *} ## Declaring types { #declaring-types } @@ -133,7 +133,7 @@ You can use, for example: * `bool` * `bytes` -{* ../../docs_src/python_types/tutorial005.py hl[1] *} +{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *} ### Generic types with type parameters { #generic-types-with-type-parameters } @@ -161,56 +161,24 @@ If you can use the **latest versions of Python**, use the examples for the lates For example, let's define a variable to be a `list` of `str`. -//// tab | Python 3.9+ - Declare the variable, with the same colon (`:`) syntax. As the type, put `list`. As the list is a type that contains some internal types, you put them in square brackets: -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -From `typing`, import `List` (with a capital `L`): - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -Declare the variable, with the same colon (`:`) syntax. - -As the type, put the `List` that you imported from `typing`. - -As the list is a type that contains some internal types, you put them in square brackets: - -```Python hl_lines="4" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *} /// info Those internal types in the square brackets are called "type parameters". -In this case, `str` is the type parameter passed to `List` (or `list` in Python 3.9 and above). +In this case, `str` is the type parameter passed to `list`. /// That means: "the variable `items` is a `list`, and each of the items in this list is a `str`". -/// tip - -If you use Python 3.9 or above, you don't have to import `List` from `typing`, you can use the same regular `list` type instead. - -/// - By doing that, your editor can provide support even while processing items from the list: @@ -225,21 +193,7 @@ And still, the editor knows it is a `str`, and provides support for that. You would do the same to declare `tuple`s and `set`s: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *} This means: @@ -254,21 +208,7 @@ The first type parameter is for the keys of the `dict`. The second type parameter is for the values of the `dict`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *} This means: @@ -292,10 +232,10 @@ In Python 3.10 there's also a **new syntax** where you can put the possible type //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} +{!> ../../docs_src/python_types/tutorial008b_py39.py!} ``` //// @@ -309,7 +249,7 @@ You can declare that a value could have a type, like `str`, but that it could al In Python 3.6 and above (including Python 3.10) you can declare it by importing and using `Optional` from the `typing` module. ```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009.py!} +{!../../docs_src/python_types/tutorial009_py39.py!} ``` Using `Optional[str]` instead of just `str` will let the editor help you detect errors where you could be assuming that a value is always a `str`, when it could actually be `None` too. @@ -326,18 +266,18 @@ This also means that in Python 3.10, you can use `Something | None`: //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} +{!> ../../docs_src/python_types/tutorial009_py39.py!} ``` //// -//// tab | Python 3.8+ alternative +//// tab | Python 3.9+ alternative ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} +{!> ../../docs_src/python_types/tutorial009b_py39.py!} ``` //// @@ -357,7 +297,7 @@ It's just about the words and names. But those words can affect how you and your As an example, let's take this function: -{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} +{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *} The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter: @@ -390,10 +330,10 @@ You can use the same builtin types as generics (with square brackets and types i * `set` * `dict` -And the same as with Python 3.8, from the `typing` module: +And the same as with previous Python versions, from the `typing` module: * `Union` -* `Optional` (the same as with Python 3.8) +* `Optional` * ...and others. In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the vertical bar (`|`) to declare unions of types, that's a lot better and simpler. @@ -409,7 +349,7 @@ You can use the same builtin types as generics (with square brackets and types i * `set` * `dict` -And the same as with Python 3.8, from the `typing` module: +And generics from the `typing` module: * `Union` * `Optional` @@ -417,29 +357,17 @@ And the same as with Python 3.8, from the `typing` module: //// -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ...and others. - -//// - ### Classes as types { #classes-as-types } You can also declare a class as the type of a variable. Let's say you have a class `Person`, with a name: -{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *} Then you can declare a variable to be of type `Person`: -{* ../../docs_src/python_types/tutorial010.py hl[6] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *} And then, again, you get all the editor support: @@ -463,29 +391,7 @@ And you get all the editor support with that resulting object. An example from the official Pydantic docs: -//// tab | Python 3.10+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial011_py310.py *} /// info @@ -507,27 +413,9 @@ Pydantic has a special behavior when you use `Optional` or `Union[Something, Non Python also has a feature that allows putting **additional metadata** in these type hints using `Annotated`. -//// tab | Python 3.9+ +Since Python 3.9, `Annotated` is a part of the standard library, so you can import it from `typing`. -In Python 3.9, `Annotated` is part of the standard library, so you can import it from `typing`. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -In versions below Python 3.9, you import `Annotated` from `typing_extensions`. - -It will already be installed with **FastAPI**. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *} Python itself doesn't do anything with this `Annotated`. And for editors and other tools, the type is still `str`. diff --git a/docs/en/docs/tutorial/background-tasks.md b/docs/en/docs/tutorial/background-tasks.md index ab44f89c19..be7ecd5871 100644 --- a/docs/en/docs/tutorial/background-tasks.md +++ b/docs/en/docs/tutorial/background-tasks.md @@ -15,7 +15,7 @@ This includes, for example: First, import `BackgroundTasks` and define a parameter in your *path operation function* with a type declaration of `BackgroundTasks`: -{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *} **FastAPI** will create the object of type `BackgroundTasks` for you and pass it as that parameter. @@ -31,13 +31,13 @@ In this case, the task function will write to a file (simulating sending an emai And as the write operation doesn't use `async` and `await`, we define the function with normal `def`: -{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *} ## Add the background task { #add-the-background-task } Inside of your *path operation function*, pass your task function to the *background tasks* object with the method `.add_task()`: -{* ../../docs_src/background_tasks/tutorial001.py hl[14] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *} `.add_task()` receives as arguments: diff --git a/docs/en/docs/tutorial/body-nested-models.md b/docs/en/docs/tutorial/body-nested-models.md index 445235a420..5fd83a8f3c 100644 --- a/docs/en/docs/tutorial/body-nested-models.md +++ b/docs/en/docs/tutorial/body-nested-models.md @@ -14,35 +14,15 @@ This will make `tags` be a list, although it doesn't declare the type of the ele But Python has a specific way to declare lists with internal types, or "type parameters": -### Import typing's `List` { #import-typings-list } - -In Python 3.9 and above you can use the standard `list` to declare these type annotations as we'll see below. 💡 - -But in Python versions before 3.9 (3.6 and above), you first need to import `List` from standard Python's `typing` module: - -{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *} - ### Declare a `list` with a type parameter { #declare-a-list-with-a-type-parameter } -To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`: - -* If you are in a Python version lower than 3.9, import their equivalent version from the `typing` module -* Pass the internal type(s) as "type parameters" using square brackets: `[` and `]` - -In Python 3.9 it would be: +To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`, +pass the internal type(s) as "type parameters" using square brackets: `[` and `]` ```Python my_list: list[str] ``` -In versions of Python before 3.9, it would be: - -```Python -from typing import List - -my_list: List[str] -``` - That's all standard Python syntax for type declarations. Use that same standard syntax for model attributes with internal types. @@ -178,12 +158,6 @@ Notice how `Offer` has a list of `Item`s, which in turn have an optional list of If the top level value of the JSON body you expect is a JSON `array` (a Python `list`), you can declare the type in the parameter of the function, the same as in Pydantic models: -```Python -images: List[Image] -``` - -or in Python 3.9 and above: - ```Python images: list[Image] ``` diff --git a/docs/en/docs/tutorial/body.md b/docs/en/docs/tutorial/body.md index a820802f74..25087b8406 100644 --- a/docs/en/docs/tutorial/body.md +++ b/docs/en/docs/tutorial/body.md @@ -163,7 +163,7 @@ The function parameters will be recognized as follows: FastAPI will know that the value of `q` is not required because of the default value `= None`. -The `str | None` (Python 3.10+) or `Union` in `Union[str, None]` (Python 3.8+) is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`. +The `str | None` (Python 3.10+) or `Union` in `Union[str, None]` (Python 3.9+) is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`. But adding the type annotations will allow your editor to give you better support and detect errors. diff --git a/docs/en/docs/tutorial/cors.md b/docs/en/docs/tutorial/cors.md index e3de37b43c..8a3a8eb0a8 100644 --- a/docs/en/docs/tutorial/cors.md +++ b/docs/en/docs/tutorial/cors.md @@ -46,7 +46,7 @@ You can also specify whether your backend allows: * Specific HTTP methods (`POST`, `PUT`) or all of them with the wildcard `"*"`. * Specific HTTP headers or all of them with the wildcard `"*"`. -{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *} +{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *} The default parameters used by the `CORSMiddleware` implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context. diff --git a/docs/en/docs/tutorial/debugging.md b/docs/en/docs/tutorial/debugging.md index 08b440084e..a2edfe7203 100644 --- a/docs/en/docs/tutorial/debugging.md +++ b/docs/en/docs/tutorial/debugging.md @@ -6,7 +6,7 @@ You can connect the debugger in your editor, for example with Visual Studio Code In your FastAPI application, import and run `uvicorn` directly: -{* ../../docs_src/debugging/tutorial001.py hl[1,15] *} +{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *} ### About `__name__ == "__main__"` { #about-name-main } diff --git a/docs/en/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/en/docs/tutorial/dependencies/classes-as-dependencies.md index 686a5632e2..0a6a786b50 100644 --- a/docs/en/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/en/docs/tutorial/dependencies/classes-as-dependencies.md @@ -101,7 +101,7 @@ Now you can declare your dependency using this class. Notice how we write `CommonQueryParams` twice in the above code: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip @@ -137,7 +137,7 @@ It is from this one that FastAPI will extract the declared parameters and that i In this case, the first `CommonQueryParams`, in: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, ... @@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ... //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip @@ -163,7 +163,7 @@ commons: CommonQueryParams ... You could actually write just: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[Any, Depends(CommonQueryParams)] @@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip @@ -197,7 +197,7 @@ But declaring the type is encouraged as that way your editor will know what will But you see that we are having some code repetition here, writing `CommonQueryParams` twice: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip @@ -225,7 +225,7 @@ For those specific cases, you can do the following: Instead of writing: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip @@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ...you write: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends()] @@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()] //// -//// tab | Python 3.8 non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip diff --git a/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md index 494c40efab..d9f3345619 100644 --- a/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md @@ -29,15 +29,15 @@ For example, you could use this to create a database session and close it after Only the code prior to and including the `yield` statement is executed before creating a response: -{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *} The yielded value is what is injected into *path operations* and other dependencies: -{* ../../docs_src/dependencies/tutorial007.py hl[4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *} The code following the `yield` statement is executed after the response: -{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *} /// tip @@ -57,7 +57,7 @@ So, you can look for that specific exception inside the dependency with `except In the same way, you can use `finally` to make sure the exit steps are executed, no matter if there was an exception or not. -{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *} ## Sub-dependencies with `yield` { #sub-dependencies-with-yield } @@ -269,7 +269,7 @@ In Python, you can create Context Managers by deprecated, but without removing it, pass the parameter `deprecated`: -{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *} +{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *} It will be clearly marked as deprecated in the interactive docs: diff --git a/docs/en/docs/tutorial/path-params-numeric-validations.md b/docs/en/docs/tutorial/path-params-numeric-validations.md index f7f2d6ceb0..8b1b8a8392 100644 --- a/docs/en/docs/tutorial/path-params-numeric-validations.md +++ b/docs/en/docs/tutorial/path-params-numeric-validations.md @@ -54,7 +54,7 @@ It doesn't matter for **FastAPI**. It will detect the parameters by their names, So, you can declare your function as: -{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *} But keep in mind that if you use `Annotated`, you won't have this problem, it won't matter as you're not using the function parameter default values for `Query()` or `Path()`. @@ -83,7 +83,7 @@ Pass `*`, as the first parameter of the function. Python won't do anything with that `*`, but it will know that all the following parameters should be called as keyword arguments (key-value pairs), also known as kwargs. Even if they don't have a default value. -{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *} ### Better with `Annotated` { #better-with-annotated } diff --git a/docs/en/docs/tutorial/path-params.md b/docs/en/docs/tutorial/path-params.md index 457cc2713f..ea4307900c 100644 --- a/docs/en/docs/tutorial/path-params.md +++ b/docs/en/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ You can declare path "parameters" or "variables" with the same syntax used by Python format strings: -{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} +{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *} The value of the path parameter `item_id` will be passed to your function as the argument `item_id`. @@ -16,7 +16,7 @@ So, if you run this example and go to Enumerations (or enums) are available in Python since version 3.4. - -/// +{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *} /// tip @@ -158,7 +152,7 @@ If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Then create a *path parameter* with a type annotation using the enum class you created (`ModelName`): -{* ../../docs_src/path_params/tutorial005.py hl[16] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *} ### Check the docs { #check-the-docs } @@ -174,13 +168,13 @@ The value of the *path parameter* will be an *enumeration member*. You can compare it with the *enumeration member* in your created enum `ModelName`: -{* ../../docs_src/path_params/tutorial005.py hl[17] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *} #### Get the *enumeration value* { #get-the-enumeration-value } You can get the actual value (a `str` in this case) using `model_name.value`, or in general, `your_enum_member.value`: -{* ../../docs_src/path_params/tutorial005.py hl[20] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *} /// tip @@ -194,7 +188,7 @@ You can return *enum members* from your *path operation*, even nested in a JSON They will be converted to their corresponding values (strings in this case) before returning them to the client: -{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *} In your client you will get a JSON response like: @@ -233,7 +227,7 @@ In this case, the name of the parameter is `file_path`, and the last part, `:pat So, you can use it with: -{* ../../docs_src/path_params/tutorial004.py hl[6] *} +{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *} /// tip diff --git a/docs/en/docs/tutorial/query-params-str-validations.md b/docs/en/docs/tutorial/query-params-str-validations.md index adf08a9249..aba87a4484 100644 --- a/docs/en/docs/tutorial/query-params-str-validations.md +++ b/docs/en/docs/tutorial/query-params-str-validations.md @@ -55,7 +55,7 @@ q: str | None = None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python q: Union[str, None] = None @@ -73,7 +73,7 @@ q: Annotated[str | None] = None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python q: Annotated[Union[str, None]] = None diff --git a/docs/en/docs/tutorial/query-params.md b/docs/en/docs/tutorial/query-params.md index 2323b83c7c..3c9c225fb0 100644 --- a/docs/en/docs/tutorial/query-params.md +++ b/docs/en/docs/tutorial/query-params.md @@ -2,7 +2,7 @@ When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters. -{* ../../docs_src/query_params/tutorial001.py hl[9] *} +{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *} The query is the set of key-value pairs that go after the `?` in a URL, separated by `&` characters. @@ -128,7 +128,7 @@ If you don't want to add a specific value but just make it optional, set the def But when you want to make a query parameter required, you can just not declare any default value: -{* ../../docs_src/query_params/tutorial005.py hl[6:7] *} +{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *} Here the query parameter `needy` is a required query parameter of type `str`. diff --git a/docs/en/docs/tutorial/response-model.md b/docs/en/docs/tutorial/response-model.md index 5090dbcdfd..a38c610d4f 100644 --- a/docs/en/docs/tutorial/response-model.md +++ b/docs/en/docs/tutorial/response-model.md @@ -183,7 +183,7 @@ There might be cases where you return something that is not a valid Pydantic fie The most common case would be [returning a Response directly as explained later in the advanced docs](../advanced/response-directly.md){.internal-link target=_blank}. -{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *} +{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *} This simple case is handled automatically by FastAPI because the return type annotation is the class (or a subclass of) `Response`. @@ -193,7 +193,7 @@ And tools will also be happy because both `RedirectResponse` and `JSONResponse` You can also use a subclass of `Response` in the type annotation: -{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *} +{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *} This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case. diff --git a/docs/en/docs/tutorial/response-status-code.md b/docs/en/docs/tutorial/response-status-code.md index a2d9757b28..6389592486 100644 --- a/docs/en/docs/tutorial/response-status-code.md +++ b/docs/en/docs/tutorial/response-status-code.md @@ -8,7 +8,7 @@ The same way you can specify a response model, you can also declare the HTTP sta * `@app.delete()` * etc. -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} /// note @@ -74,7 +74,7 @@ To know more about each status code and which code is for what, check the parse como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera. diff --git a/docs/es/docs/advanced/response-change-status-code.md b/docs/es/docs/advanced/response-change-status-code.md index 067267750b..940f1dd3ff 100644 --- a/docs/es/docs/advanced/response-change-status-code.md +++ b/docs/es/docs/advanced/response-change-status-code.md @@ -20,7 +20,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function* Y luego puedes establecer el `status_code` en ese objeto de response *temporal*. -{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} +{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *} Y luego puedes devolver cualquier objeto que necesites, como lo harías normalmente (un `dict`, un modelo de base de datos, etc.). diff --git a/docs/es/docs/advanced/response-cookies.md b/docs/es/docs/advanced/response-cookies.md index ce2ff0281d..550a5d97a7 100644 --- a/docs/es/docs/advanced/response-cookies.md +++ b/docs/es/docs/advanced/response-cookies.md @@ -6,7 +6,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function* Y luego puedes establecer cookies en ese objeto de response *temporal*. -{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *} +{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *} Y entonces puedes devolver cualquier objeto que necesites, como normalmente lo harías (un `dict`, un modelo de base de datos, etc). @@ -24,7 +24,7 @@ Para hacer eso, puedes crear un response como se describe en [Devolver un Respon Luego establece Cookies en ella, y luego devuélvela: -{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *} /// tip | Consejo diff --git a/docs/es/docs/advanced/response-directly.md b/docs/es/docs/advanced/response-directly.md index 96b30b915c..2da4e84e70 100644 --- a/docs/es/docs/advanced/response-directly.md +++ b/docs/es/docs/advanced/response-directly.md @@ -54,7 +54,7 @@ Digamos que quieres devolver un response en documentación de Strawberry. diff --git a/docs/es/docs/python-types.md b/docs/es/docs/python-types.md index e51c2352c5..60b50a08ff 100644 --- a/docs/es/docs/python-types.md +++ b/docs/es/docs/python-types.md @@ -22,7 +22,7 @@ Si eres un experto en Python, y ya sabes todo sobre las anotaciones de tipos, sa Comencemos con un ejemplo simple: -{* ../../docs_src/python_types/tutorial001.py *} +{* ../../docs_src/python_types/tutorial001_py39.py *} Llamar a este programa genera: @@ -36,7 +36,7 @@ La función hace lo siguiente: * Convierte la primera letra de cada uno a mayúsculas con `title()`. * Concatena ambos con un espacio en el medio. -{* ../../docs_src/python_types/tutorial001.py hl[2] *} +{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *} ### Edítalo { #edit-it } @@ -78,7 +78,7 @@ Eso es todo. Esas son las "anotaciones de tipos": -{* ../../docs_src/python_types/tutorial002.py hl[1] *} +{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *} Eso no es lo mismo que declarar valores predeterminados como sería con: @@ -106,7 +106,7 @@ Con eso, puedes desplazarte, viendo las opciones, hasta que encuentres la que "t Revisa esta función, ya tiene anotaciones de tipos: -{* ../../docs_src/python_types/tutorial003.py hl[1] *} +{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *} Porque el editor conoce los tipos de las variables, no solo obtienes autocompletado, también obtienes chequeo de errores: @@ -114,7 +114,7 @@ Porque el editor conoce los tipos de las variables, no solo obtienes autocomplet Ahora sabes que debes corregirlo, convertir `age` a un string con `str(age)`: -{* ../../docs_src/python_types/tutorial004.py hl[2] *} +{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *} ## Declaración de tipos { #declaring-types } @@ -133,7 +133,7 @@ Puedes usar, por ejemplo: * `bool` * `bytes` -{* ../../docs_src/python_types/tutorial005.py hl[1] *} +{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *} ### Tipos genéricos con parámetros de tipo { #generic-types-with-type-parameters } @@ -161,56 +161,24 @@ Si puedes usar las **últimas versiones de Python**, utiliza los ejemplos para l Por ejemplo, vamos a definir una variable para ser una `list` de `str`. -//// tab | Python 3.9+ - Declara la variable, con la misma sintaxis de dos puntos (`:`). Como tipo, pon `list`. Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes: -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -De `typing`, importa `List` (con una `L` mayúscula): - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -Declara la variable, con la misma sintaxis de dos puntos (`:`). - -Como tipo, pon el `List` que importaste de `typing`. - -Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes: - -```Python hl_lines="4" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *} /// info | Información Esos tipos internos en los corchetes se denominan "parámetros de tipo". -En este caso, `str` es el parámetro de tipo pasado a `List` (o `list` en Python 3.9 y superior). +En este caso, `str` es el parámetro de tipo pasado a `list`. /// Eso significa: "la variable `items` es una `list`, y cada uno de los ítems en esta lista es un `str`". -/// tip | Consejo - -Si usas Python 3.9 o superior, no tienes que importar `List` de `typing`, puedes usar el mismo tipo `list` regular en su lugar. - -/// - Al hacer eso, tu editor puede proporcionar soporte incluso mientras procesa elementos de la lista: @@ -225,21 +193,7 @@ Y aún así, el editor sabe que es un `str` y proporciona soporte para eso. Harías lo mismo para declarar `tuple`s y `set`s: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *} Esto significa: @@ -254,21 +208,7 @@ El primer parámetro de tipo es para las claves del `dict`. El segundo parámetro de tipo es para los valores del `dict`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *} Esto significa: @@ -292,10 +232,10 @@ En Python 3.10 también hay una **nueva sintaxis** donde puedes poner los posibl //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} +{!> ../../docs_src/python_types/tutorial008b_py39.py!} ``` //// @@ -309,7 +249,7 @@ Puedes declarar que un valor podría tener un tipo, como `str`, pero que tambié En Python 3.6 y posteriores (incluyendo Python 3.10) puedes declararlo importando y usando `Optional` del módulo `typing`. ```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009.py!} +{!../../docs_src/python_types/tutorial009_py39.py!} ``` Usar `Optional[str]` en lugar de solo `str` te permitirá al editor ayudarte a detectar errores donde podrías estar asumiendo que un valor siempre es un `str`, cuando en realidad también podría ser `None`. @@ -326,18 +266,18 @@ Esto también significa que en Python 3.10, puedes usar `Something | None`: //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} +{!> ../../docs_src/python_types/tutorial009_py39.py!} ``` //// -//// tab | Python 3.8+ alternativa +//// tab | Python 3.9+ alternativa ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} +{!> ../../docs_src/python_types/tutorial009b_py39.py!} ``` //// @@ -357,7 +297,7 @@ Se trata solo de las palabras y nombres. Pero esas palabras pueden afectar cómo Como ejemplo, tomemos esta función: -{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} +{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *} El parámetro `name` está definido como `Optional[str]`, pero **no es opcional**, no puedes llamar a la función sin el parámetro: @@ -390,10 +330,10 @@ Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos d * `set` * `dict` -Y lo mismo que con Python 3.8, desde el módulo `typing`: +Y, como con versiones anteriores de Python, desde el módulo `typing`: * `Union` -* `Optional` (lo mismo que con Python 3.8) +* `Optional` * ...y otros. En Python 3.10, como alternativa a usar los genéricos `Union` y `Optional`, puedes usar la barra vertical (`|`) para declarar uniones de tipos, eso es mucho mejor y más simple. @@ -409,7 +349,7 @@ Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos d * `set` * `dict` -Y lo mismo que con Python 3.8, desde el módulo `typing`: +Y generics desde el módulo `typing`: * `Union` * `Optional` @@ -417,29 +357,17 @@ Y lo mismo que con Python 3.8, desde el módulo `typing`: //// -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ...y otros. - -//// - ### Clases como tipos { #classes-as-types } También puedes declarar una clase como el tipo de una variable. Digamos que tienes una clase `Person`, con un nombre: -{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *} Luego puedes declarar una variable para que sea de tipo `Person`: -{* ../../docs_src/python_types/tutorial010.py hl[6] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *} Y luego, nuevamente, obtienes todo el soporte del editor: @@ -463,29 +391,7 @@ Y obtienes todo el soporte del editor con ese objeto resultante. Un ejemplo de la documentación oficial de Pydantic: -//// tab | Python 3.10+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial011_py310.py *} /// info | Información @@ -507,27 +413,9 @@ Pydantic tiene un comportamiento especial cuando utilizas `Optional` o `Union[So Python también tiene una funcionalidad que permite poner **metadatos adicional** en estas anotaciones de tipos usando `Annotated`. -//// tab | Python 3.9+ +Desde Python 3.9, `Annotated` es parte de la standard library, así que puedes importarlo desde `typing`. -En Python 3.9, `Annotated` es parte de la standard library, así que puedes importarlo desde `typing`. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -En versiones por debajo de Python 3.9, importas `Annotated` de `typing_extensions`. - -Ya estará instalado con **FastAPI**. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *} Python en sí no hace nada con este `Annotated`. Y para los editores y otras herramientas, el tipo sigue siendo `str`. diff --git a/docs/es/docs/tutorial/background-tasks.md b/docs/es/docs/tutorial/background-tasks.md index 8cd0767f8e..cc8a2c9cbe 100644 --- a/docs/es/docs/tutorial/background-tasks.md +++ b/docs/es/docs/tutorial/background-tasks.md @@ -15,7 +15,7 @@ Esto incluye, por ejemplo: Primero, importa `BackgroundTasks` y define un parámetro en tu *path operation function* con una declaración de tipo de `BackgroundTasks`: -{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *} **FastAPI** creará el objeto de tipo `BackgroundTasks` por ti y lo pasará como ese parámetro. @@ -31,13 +31,13 @@ En este caso, la función de tarea escribirá en un archivo (simulando el envío Y como la operación de escritura no usa `async` y `await`, definimos la función con un `def` normal: -{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *} ## Agregar la tarea en segundo plano { #add-the-background-task } Dentro de tu *path operation function*, pasa tu función de tarea al objeto de *background tasks* con el método `.add_task()`: -{* ../../docs_src/background_tasks/tutorial001.py hl[14] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *} `.add_task()` recibe como argumentos: diff --git a/docs/es/docs/tutorial/body-nested-models.md b/docs/es/docs/tutorial/body-nested-models.md index 04f4b39c4a..0dfd6576f1 100644 --- a/docs/es/docs/tutorial/body-nested-models.md +++ b/docs/es/docs/tutorial/body-nested-models.md @@ -14,35 +14,15 @@ Esto hará que `tags` sea una lista, aunque no declare el tipo de los elementos Pero Python tiene una forma específica de declarar listas con tipos internos, o "parámetros de tipo": -### Importar `List` de typing { #import-typings-list } - -En Python 3.9 y superior, puedes usar el `list` estándar para declarar estas anotaciones de tipo como veremos a continuación. 💡 - -Pero en versiones de Python anteriores a 3.9 (desde 3.6 en adelante), primero necesitas importar `List` del módulo `typing` estándar de Python: - -{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *} - ### Declarar una `list` con un parámetro de tipo { #declare-a-list-with-a-type-parameter } -Para declarar tipos que tienen parámetros de tipo (tipos internos), como `list`, `dict`, `tuple`: - -* Si estás en una versión de Python inferior a 3.9, importa su versión equivalente del módulo `typing` -* Pasa el/los tipo(s) interno(s) como "parámetros de tipo" usando corchetes: `[` y `]` - -En Python 3.9 sería: +Para declarar tipos que tienen parámetros de tipo (tipos internos), como `list`, `dict`, `tuple`, +pasa el/los tipo(s) interno(s) como "parámetros de tipo" usando corchetes: `[` y `]` ```Python my_list: list[str] ``` -En versiones de Python anteriores a 3.9, sería: - -```Python -from typing import List - -my_list: List[str] -``` - Eso es toda la sintaxis estándar de Python para declaraciones de tipo. Usa esa misma sintaxis estándar para atributos de modelos con tipos internos. @@ -178,12 +158,6 @@ Observa cómo `Offer` tiene una lista de `Item`s, que a su vez tienen una lista Si el valor superior del cuerpo JSON que esperas es un `array` JSON (una `list` en Python), puedes declarar el tipo en el parámetro de la función, al igual que en los modelos Pydantic: -```Python -images: List[Image] -``` - -o en Python 3.9 y superior: - ```Python images: list[Image] ``` diff --git a/docs/es/docs/tutorial/body.md b/docs/es/docs/tutorial/body.md index 58877c5c46..06a70dbc79 100644 --- a/docs/es/docs/tutorial/body.md +++ b/docs/es/docs/tutorial/body.md @@ -161,7 +161,7 @@ Los parámetros de la función se reconocerán de la siguiente manera: FastAPI sabrá que el valor de `q` no es requerido debido al valor por defecto `= None`. -El `str | None` (Python 3.10+) o `Union` en `Union[str, None]` (Python 3.8+) no es utilizado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de `= None`. +El `str | None` (Python 3.10+) o `Union` en `Union[str, None]` (Python 3.9+) no es utilizado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de `= None`. Pero agregar las anotaciones de tipos permitirá que tu editor te brinde un mejor soporte y detecte errores. diff --git a/docs/es/docs/tutorial/cors.md b/docs/es/docs/tutorial/cors.md index d6bc7ea61f..c1a23295e1 100644 --- a/docs/es/docs/tutorial/cors.md +++ b/docs/es/docs/tutorial/cors.md @@ -46,7 +46,7 @@ También puedes especificar si tu backend permite: * Métodos HTTP específicos (`POST`, `PUT`) o todos ellos con el comodín `"*"`. * Headers HTTP específicos o todos ellos con el comodín `"*"`. -{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *} +{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *} Los parámetros predeterminados utilizados por la implementación de `CORSMiddleware` son restrictivos por defecto, por lo que necesitarás habilitar explícitamente orígenes, métodos o headers particulares para que los navegadores estén permitidos de usarlos en un contexto de Cross-Domain. diff --git a/docs/es/docs/tutorial/debugging.md b/docs/es/docs/tutorial/debugging.md index 1e57df2092..c31daf40f4 100644 --- a/docs/es/docs/tutorial/debugging.md +++ b/docs/es/docs/tutorial/debugging.md @@ -6,7 +6,7 @@ Puedes conectar el depurador en tu editor, por ejemplo con Visual Studio Code o En tu aplicación de FastAPI, importa y ejecuta `uvicorn` directamente: -{* ../../docs_src/debugging/tutorial001.py hl[1,15] *} +{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *} ### Acerca de `__name__ == "__main__"` { #about-name-main } diff --git a/docs/es/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/es/docs/tutorial/dependencies/classes-as-dependencies.md index 37cc2e2133..a3a75efcd9 100644 --- a/docs/es/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/es/docs/tutorial/dependencies/classes-as-dependencies.md @@ -101,7 +101,7 @@ Ahora puedes declarar tu dependencia usando esta clase. Nota cómo escribimos `CommonQueryParams` dos veces en el código anterior: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ sin `Annotated` +//// tab | Python 3.9+ sin `Annotated` /// tip | Consejo @@ -137,7 +137,7 @@ Es a partir de este que **FastAPI** extraerá los parámetros declarados y es lo En este caso, el primer `CommonQueryParams`, en: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, ... @@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ... //// -//// tab | Python 3.8+ sin `Annotated` +//// tab | Python 3.9+ sin `Annotated` /// tip | Consejo @@ -163,7 +163,7 @@ commons: CommonQueryParams ... De hecho, podrías escribir simplemente: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[Any, Depends(CommonQueryParams)] @@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ sin `Annotated` +//// tab | Python 3.9+ sin `Annotated` /// tip | Consejo @@ -197,7 +197,7 @@ Pero declarar el tipo es recomendable, ya que de esa manera tu editor sabrá lo Pero ves que estamos teniendo algo de repetición de código aquí, escribiendo `CommonQueryParams` dos veces: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ sin `Annotated` +//// tab | Python 3.9+ sin `Annotated` /// tip | Consejo @@ -225,7 +225,7 @@ Para esos casos específicos, puedes hacer lo siguiente: En lugar de escribir: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ sin `Annotated` +//// tab | Python 3.9+ sin `Annotated` /// tip | Consejo @@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ...escribes: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends()] @@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()] //// -//// tab | Python 3.8 sin `Annotated` +//// tab | Python 3.9+ sin `Annotated` /// tip | Consejo diff --git a/docs/es/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/es/docs/tutorial/dependencies/dependencies-with-yield.md index e29c749a5f..aa645daa47 100644 --- a/docs/es/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/es/docs/tutorial/dependencies/dependencies-with-yield.md @@ -29,15 +29,15 @@ Por ejemplo, podrías usar esto para crear una sesión de base de datos y cerrar Solo el código anterior e incluyendo la declaración `yield` se ejecuta antes de crear un response: -{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *} El valor generado es lo que se inyecta en *path operations* y otras dependencias: -{* ../../docs_src/dependencies/tutorial007.py hl[4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *} El código posterior a la declaración `yield` se ejecuta después del response: -{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *} /// tip | Consejo @@ -57,7 +57,7 @@ Por lo tanto, puedes buscar esa excepción específica dentro de la dependencia Del mismo modo, puedes usar `finally` para asegurarte de que los pasos de salida se ejecuten, sin importar si hubo una excepción o no. -{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *} ## Sub-dependencias con `yield` { #sub-dependencies-with-yield } @@ -270,7 +270,7 @@ En Python, puedes crear Context Managers deprecated, pero sin eliminarla, pasa el parámetro `deprecated`: -{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *} +{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *} Se marcará claramente como deprecado en la documentación interactiva: diff --git a/docs/es/docs/tutorial/path-params-numeric-validations.md b/docs/es/docs/tutorial/path-params-numeric-validations.md index a6f0a4cd3d..569dd03dd0 100644 --- a/docs/es/docs/tutorial/path-params-numeric-validations.md +++ b/docs/es/docs/tutorial/path-params-numeric-validations.md @@ -54,7 +54,7 @@ No importa para **FastAPI**. Detectará los parámetros por sus nombres, tipos y Así que puedes declarar tu función como: -{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *} Pero ten en cuenta que si usas `Annotated`, no tendrás este problema, no importará ya que no estás usando los valores por defecto de los parámetros de la función para `Query()` o `Path()`. @@ -83,7 +83,7 @@ Pasa `*`, como el primer parámetro de la función. Python no hará nada con ese `*`, pero sabrá que todos los parámetros siguientes deben ser llamados como argumentos de palabras clave (parejas key-value), también conocidos como kwargs. Incluso si no tienen un valor por defecto. -{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *} ### Mejor con `Annotated` { #better-with-annotated } diff --git a/docs/es/docs/tutorial/path-params.md b/docs/es/docs/tutorial/path-params.md index c49b31c44e..7ba49f3b0b 100644 --- a/docs/es/docs/tutorial/path-params.md +++ b/docs/es/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ Puedes declarar "parámetros" o "variables" de path con la misma sintaxis que se usa en los format strings de Python: -{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} +{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *} El valor del parámetro de path `item_id` se pasará a tu función como el argumento `item_id`. @@ -16,7 +16,7 @@ Así que, si ejecutas este ejemplo y vas a Las enumeraciones (o enums) están disponibles en Python desde la versión 3.4. - -/// +{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *} /// tip | Consejo @@ -158,7 +152,7 @@ Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de analisado como JSON, ele é lido diretamente como `bytes` e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma. diff --git a/docs/pt/docs/advanced/response-change-status-code.md b/docs/pt/docs/advanced/response-change-status-code.md index 0f08873f67..ee81f0bfc8 100644 --- a/docs/pt/docs/advanced/response-change-status-code.md +++ b/docs/pt/docs/advanced/response-change-status-code.md @@ -20,7 +20,7 @@ Você pode declarar um parâmetro do tipo `Response` em sua *função de operaç E então você pode definir o `status_code` neste objeto de retorno temporal. -{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} +{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *} E então você pode retornar qualquer objeto que você precise, como você faria normalmente (um `dict`, um modelo de banco de dados, etc.). diff --git a/docs/pt/docs/advanced/response-cookies.md b/docs/pt/docs/advanced/response-cookies.md index 41fc000133..67820b433b 100644 --- a/docs/pt/docs/advanced/response-cookies.md +++ b/docs/pt/docs/advanced/response-cookies.md @@ -6,7 +6,7 @@ Você pode declarar um parâmetro do tipo `Response` na sua *função de operaç E então você pode definir cookies nesse objeto de resposta *temporário*. -{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *} +{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *} Em seguida, você pode retornar qualquer objeto que precise, como normalmente faria (um `dict`, um modelo de banco de dados, etc). @@ -24,7 +24,7 @@ Para fazer isso, você pode criar uma resposta como descrito em [Retorne uma Res Então, defina os cookies nela e a retorne: -{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *} /// tip | Dica diff --git a/docs/pt/docs/advanced/response-directly.md b/docs/pt/docs/advanced/response-directly.md index 0c0144e9a1..bbbef2f913 100644 --- a/docs/pt/docs/advanced/response-directly.md +++ b/docs/pt/docs/advanced/response-directly.md @@ -54,7 +54,7 @@ Vamos dizer que você quer retornar uma resposta documentação do Strawberry. diff --git a/docs/pt/docs/python-types.md b/docs/pt/docs/python-types.md index 3e2d1ccb30..fc983d1df1 100644 --- a/docs/pt/docs/python-types.md +++ b/docs/pt/docs/python-types.md @@ -22,7 +22,7 @@ Se você é um especialista em Python e já sabe tudo sobre type hints, pule par Vamos começar com um exemplo simples: -{* ../../docs_src/python_types/tutorial001.py *} +{* ../../docs_src/python_types/tutorial001_py39.py *} A chamada deste programa gera: @@ -36,7 +36,7 @@ A função faz o seguinte: * Converte a primeira letra de cada uma em maiúsculas com `title()`. * Concatena com um espaço no meio. -{* ../../docs_src/python_types/tutorial001.py hl[2] *} +{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *} ### Edite-o { #edit-it } @@ -78,7 +78,7 @@ para: Esses são os "type hints": -{* ../../docs_src/python_types/tutorial002.py hl[1] *} +{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *} Isso não é o mesmo que declarar valores padrão como seria com: @@ -106,7 +106,7 @@ Com isso, você pode rolar, vendo as opções, até encontrar o que "soa familia Verifique esta função, ela já possui type hints: -{* ../../docs_src/python_types/tutorial003.py hl[1] *} +{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *} Como o editor conhece os tipos de variáveis, você não obtém apenas o preenchimento automático, mas também as verificações de erro: @@ -114,7 +114,7 @@ Como o editor conhece os tipos de variáveis, você não obtém apenas o preench Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`: -{* ../../docs_src/python_types/tutorial004.py hl[2] *} +{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *} ## Declarando Tipos { #declaring-types } @@ -133,7 +133,7 @@ Você pode usar, por exemplo: * `bool` * `bytes` -{* ../../docs_src/python_types/tutorial005.py hl[1] *} +{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *} ### Tipos genéricos com parâmetros de tipo { #generic-types-with-type-parameters } @@ -161,56 +161,24 @@ Se você pode utilizar a **versão mais recente do Python**, utilize os exemplos Por exemplo, vamos definir uma variável para ser uma `list` de `str`. -//// tab | Python 3.9+ +Declare a variável, com a mesma sintaxe com dois pontos (`:`). -Declare uma variável com a mesma sintaxe com dois pontos (`:`) +Como o tipo, coloque `list`. -Como tipo, coloque `list`. +Como a lista é um tipo que contém tipos internos, você os coloca entre colchetes: -Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes: - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -De `typing`, importe `List` (com o `L` maiúsculo): - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -Declare uma variável com a mesma sintaxe com dois pontos (`:`) - -Como tipo, coloque o `List` que você importou de `typing`. - -Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes: - -```Python hl_lines="4" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *} /// info | Informação Estes tipos internos dentro dos colchetes são chamados "parâmetros de tipo" (type parameters). -Neste caso, `str` é o parâmetro de tipo passado para `List` (ou `list` no Python 3.9 ou superior). +Neste caso, `str` é o parâmetro de tipo passado para `list`. /// Isso significa: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`". -/// tip | Dica - -Se você usa o Python 3.9 ou superior, você não precisa importar `List` de `typing`. Você pode utilizar o mesmo tipo `list` no lugar. - -/// - Ao fazer isso, seu editor pode fornecer suporte mesmo durante o processamento de itens da lista: @@ -225,21 +193,7 @@ E, ainda assim, o editor sabe que é um `str` e fornece suporte para isso. Você faria o mesmo para declarar `tuple`s e `set`s: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *} Isso significa que: @@ -254,21 +208,7 @@ O primeiro parâmetro de tipo é para as chaves do `dict`. O segundo parâmetro de tipo é para os valores do `dict`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *} Isso significa que: @@ -292,10 +232,10 @@ No Python 3.10 também existe uma **nova sintaxe** onde você pode colocar os po //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} +{!> ../../docs_src/python_types/tutorial008b_py39.py!} ``` //// @@ -309,7 +249,7 @@ Você pode declarar que um valor pode ter um tipo, como `str`, mas que ele tamb No Python 3.6 e superior (incluindo o Python 3.10) você pode declará-lo importando e utilizando `Optional` do módulo `typing`. ```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009.py!} +{!../../docs_src/python_types/tutorial009_py39.py!} ``` O uso de `Optional[str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`. @@ -326,18 +266,18 @@ Isso também significa que no Python 3.10, você pode utilizar `Something | None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} +{!> ../../docs_src/python_types/tutorial009_py39.py!} ``` //// -//// tab | Python 3.8+ alternativa +//// tab | Python 3.9+ alternativa ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} +{!> ../../docs_src/python_types/tutorial009b_py39.py!} ``` //// @@ -357,7 +297,7 @@ Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os s Por exemplo, vamos pegar esta função: -{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} +{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *} O parâmetro `name` é definido como `Optional[str]`, mas ele **não é opcional**, você não pode chamar a função sem o parâmetro: @@ -390,10 +330,10 @@ Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e ti * `set` * `dict` -E o mesmo como no Python 3.8, do módulo `typing`: +E o mesmo que com versões anteriores do Python, do módulo `typing`: * `Union` -* `Optional` (o mesmo que com o 3.8) +* `Optional` * ...entre outros. No Python 3.10, como uma alternativa para a utilização dos genéricos `Union` e `Optional`, você pode usar a barra vertical (`|`) para declarar uniões de tipos. Isso é muito melhor e mais simples. @@ -409,7 +349,7 @@ Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e ti * `set` * `dict` -E o mesmo como no Python 3.8, do módulo `typing`: +E genéricos do módulo `typing`: * `Union` * `Optional` @@ -417,31 +357,19 @@ E o mesmo como no Python 3.8, do módulo `typing`: //// -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ...entre outros. - -//// - ### Classes como tipos { #classes-as-types } Você também pode declarar uma classe como o tipo de uma variável. Digamos que você tenha uma classe `Person`, com um nome: -{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *} Então você pode declarar que uma variável é do tipo `Person`: -{* ../../docs_src/python_types/tutorial010.py hl[6] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *} -E então, novamente, você recebe todo o suporte do editor: +E então, novamente, você recebe todo o apoio do editor: @@ -461,31 +389,9 @@ Em seguida, você cria uma instância dessa classe com alguns valores e ela os v E você recebe todo o suporte do editor com esse objeto resultante. -Retirado dos documentos oficiais dos Pydantic: +Um exemplo da documentação oficial do Pydantic: -//// tab | Python 3.10+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial011_py310.py *} /// info | Informação @@ -507,27 +413,9 @@ O Pydantic tem um comportamento especial quando você usa `Optional` ou `Union[S O Python possui uma funcionalidade que nos permite incluir **metadados adicionais** nos type hints utilizando `Annotated`. -//// tab | Python 3.9+ +Desde o Python 3.9, `Annotated` faz parte da biblioteca padrão, então você pode importá-lo de `typing`. -No Python 3.9, `Annotated` é parte da biblioteca padrão, então você pode importá-lo de `typing`. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -Em versões abaixo do Python 3.9, você importa `Annotated` de `typing_extensions`. - -Ele já estará instalado com o **FastAPI**. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *} O Python em si não faz nada com este `Annotated`. E para editores e outras ferramentas, o tipo ainda é `str`. diff --git a/docs/pt/docs/tutorial/background-tasks.md b/docs/pt/docs/tutorial/background-tasks.md index af0c8b2acd..34805364b4 100644 --- a/docs/pt/docs/tutorial/background-tasks.md +++ b/docs/pt/docs/tutorial/background-tasks.md @@ -15,7 +15,7 @@ Isso inclui, por exemplo: Primeiro, importe `BackgroundTasks` e defina um parâmetro na sua *função de operação de rota* com uma declaração de tipo `BackgroundTasks`: -{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *} O **FastAPI** criará o objeto do tipo `BackgroundTasks` para você e o passará como esse parâmetro. @@ -31,13 +31,13 @@ Neste caso, a função da tarefa escreverá em um arquivo (simulando o envio de E como a operação de escrita não usa `async` e `await`, definimos a função com um `def` normal: -{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *} ## Adicione a tarefa em segundo plano { #add-the-background-task } Dentro da sua *função de operação de rota*, passe sua função de tarefa para o objeto de *tarefas em segundo plano* com o método `.add_task()`: -{* ../../docs_src/background_tasks/tutorial001.py hl[14] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *} O `.add_task()` recebe como argumentos: diff --git a/docs/pt/docs/tutorial/body-nested-models.md b/docs/pt/docs/tutorial/body-nested-models.md index 4f3ca661fb..f2bec19a2f 100644 --- a/docs/pt/docs/tutorial/body-nested-models.md +++ b/docs/pt/docs/tutorial/body-nested-models.md @@ -14,35 +14,15 @@ Isso fará com que tags seja uma lista de itens mesmo sem declarar o tipo dos el Mas o Python tem uma maneira específica de declarar listas com tipos internos ou "parâmetros de tipo": -### Importe `List` do typing { #import-typings-list } - -No Python 3.9 e superior você pode usar a `list` padrão para declarar essas anotações de tipo, como veremos abaixo. 💡 - -Mas nas versões do Python anteriores à 3.9 (3.6 e superiores), primeiro é necessário importar `List` do módulo padrão `typing` do Python: - -{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *} - ### Declare uma `list` com um parâmetro de tipo { #declare-a-list-with-a-type-parameter } -Para declarar tipos que têm parâmetros de tipo (tipos internos), como `list`, `dict`, `tuple`: - -* Se você estiver em uma versão do Python inferior a 3.9, importe a versão equivalente do módulo `typing` -* Passe o(s) tipo(s) interno(s) como "parâmetros de tipo" usando colchetes: `[` e `]` - -No Python 3.9, seria: +Para declarar tipos que têm parâmetros de tipo (tipos internos), como `list`, `dict`, `tuple`, +passe o(s) tipo(s) interno(s) como "parâmetros de tipo" usando colchetes: `[` e `]` ```Python my_list: list[str] ``` -Em versões do Python anteriores à 3.9, seria: - -```Python -from typing import List - -my_list: List[str] -``` - Essa é a sintaxe padrão do Python para declarações de tipo. Use a mesma sintaxe padrão para atributos de modelo com tipos internos. @@ -178,12 +158,6 @@ Observe como `Offer` tem uma lista de `Item`s, que por sua vez têm uma lista op Se o valor de primeiro nível do corpo JSON que você espera for um `array` do JSON (uma` lista` do Python), você pode declarar o tipo no parâmetro da função, da mesma forma que nos modelos do Pydantic: -```Python -images: List[Image] -``` - -ou no Python 3.9 e superior: - ```Python images: list[Image] ``` diff --git a/docs/pt/docs/tutorial/body.md b/docs/pt/docs/tutorial/body.md index ef00b9a7a7..1330f4458f 100644 --- a/docs/pt/docs/tutorial/body.md +++ b/docs/pt/docs/tutorial/body.md @@ -161,7 +161,7 @@ Os parâmetros da função serão reconhecidos conforme abaixo: O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`. -O `str | None` (Python 3.10+) ou o `Union` em `Union[str, None]` (Python 3.8+) não é utilizado pelo FastAPI para determinar que o valor não é obrigatório, ele saberá que não é obrigatório porque tem um valor padrão `= None`. +O `str | None` (Python 3.10+) ou o `Union` em `Union[str, None]` (Python 3.9+) não é utilizado pelo FastAPI para determinar que o valor não é obrigatório, ele saberá que não é obrigatório porque tem um valor padrão `= None`. Mas adicionar as anotações de tipo permitirá ao seu editor oferecer um suporte melhor e detectar erros. diff --git a/docs/pt/docs/tutorial/cors.md b/docs/pt/docs/tutorial/cors.md index c08191db14..0f99db888e 100644 --- a/docs/pt/docs/tutorial/cors.md +++ b/docs/pt/docs/tutorial/cors.md @@ -46,7 +46,7 @@ Você também pode especificar se o seu backend permite: * Métodos HTTP específicos (`POST`, `PUT`) ou todos eles com o curinga `"*"`. * Cabeçalhos HTTP específicos ou todos eles com o curinga `"*"`. -{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *} +{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *} Os parâmetros padrão usados ​​pela implementação `CORSMiddleware` são restritivos por padrão, então você precisará habilitar explicitamente as origens, métodos ou cabeçalhos específicos para que os navegadores tenham permissão para usá-los em um contexto cross domain. diff --git a/docs/pt/docs/tutorial/debugging.md b/docs/pt/docs/tutorial/debugging.md index 21d1d527bd..e39c7d1280 100644 --- a/docs/pt/docs/tutorial/debugging.md +++ b/docs/pt/docs/tutorial/debugging.md @@ -6,7 +6,7 @@ Você pode conectar o depurador no seu editor, por exemplo, com o Visual Studio Em sua aplicação FastAPI, importe e execute `uvicorn` diretamente: -{* ../../docs_src/debugging/tutorial001.py hl[1,15] *} +{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *} ### Sobre `__name__ == "__main__"` { #about-name-main } diff --git a/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md index aa26d158f4..c30d0b5f08 100644 --- a/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md @@ -101,7 +101,7 @@ O **FastAPI** chama a classe `CommonQueryParams`. Isso cria uma "instância" des Perceba como escrevemos `CommonQueryParams` duas vezes no código abaixo: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Dica @@ -137,7 +137,7 @@ O último `CommonQueryParams`, em: Nesse caso, o primeiro `CommonQueryParams`, em: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, ... @@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ... //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Dica @@ -163,7 +163,7 @@ commons: CommonQueryParams ... Na verdade você poderia escrever apenas: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[Any, Depends(CommonQueryParams)] @@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Dica @@ -197,7 +197,7 @@ Mas declarar o tipo é encorajado por que é a forma que o seu editor de texto s Mas você pode ver que temos uma repetição do código neste exemplo, escrevendo `CommonQueryParams` duas vezes: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Dica @@ -225,7 +225,7 @@ Para esses casos específicos, você pode fazer o seguinte: Em vez de escrever: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Dica @@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ...escreva: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends()] @@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()] //// -//// tab | Python 3.8 non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Dica diff --git a/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md index 0aedcfb31e..3678730139 100644 --- a/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md @@ -29,15 +29,15 @@ Por exemplo, você poderia utilizar isso para criar uma sessão do banco de dado Apenas o código anterior à declaração com `yield` e o código contendo essa declaração são executados antes de criar uma resposta: -{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *} O valor gerado (yielded) é o que é injetado nas *operações de rota* e outras dependências: -{* ../../docs_src/dependencies/tutorial007.py hl[4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *} O código após o `yield` é executado após a resposta: -{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *} /// tip | Dica @@ -57,7 +57,7 @@ Então, você pode procurar por essa exceção específica dentro da dependênci Da mesma forma, você pode utilizar `finally` para garantir que os passos de saída são executados, com ou sem exceções. -{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *} ## Subdependências com `yield` { #sub-dependencies-with-yield } @@ -269,7 +269,7 @@ Em Python, você pode criar Gerenciadores de Contexto ao descontinuada, mas sem removê-la, passe o parâmetro `deprecated`: -{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *} +{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *} Ela será claramente marcada como descontinuada nas documentações interativas: diff --git a/docs/pt/docs/tutorial/path-params-numeric-validations.md b/docs/pt/docs/tutorial/path-params-numeric-validations.md index cec744fd5e..9f12ba38fe 100644 --- a/docs/pt/docs/tutorial/path-params-numeric-validations.md +++ b/docs/pt/docs/tutorial/path-params-numeric-validations.md @@ -54,7 +54,7 @@ Isso não faz diferença para o **FastAPI**. Ele vai detectar os parâmetros pel Então, você pode declarar sua função assim: -{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *} Mas tenha em mente que, se você usar `Annotated`, você não terá esse problema, não fará diferença, pois você não está usando valores padrão de parâmetros de função para `Query()` ou `Path()`. @@ -83,7 +83,7 @@ Passe `*`, como o primeiro parâmetro da função. O Python não fará nada com esse `*`, mas saberá que todos os parâmetros seguintes devem ser chamados como argumentos nomeados (pares chave-valor), também conhecidos como kwargs. Mesmo que eles não tenham um valor padrão. -{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *} ### Melhor com `Annotated` { #better-with-annotated } diff --git a/docs/pt/docs/tutorial/path-params.md b/docs/pt/docs/tutorial/path-params.md index d795d5b2a0..1f47ca6e59 100644 --- a/docs/pt/docs/tutorial/path-params.md +++ b/docs/pt/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ Você pode declarar "parâmetros" ou "variáveis" de path com a mesma sintaxe usada por strings de formatação do Python: -{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} +{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *} O valor do parâmetro de path `item_id` será passado para a sua função como o argumento `item_id`. @@ -16,7 +16,7 @@ Então, se você executar este exemplo e acessar Enumerations (ou enums) estão disponíveis no Python desde a versão 3.4. -/// +{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *} /// tip | Dica Se você está se perguntando, "AlexNet", "ResNet" e "LeNet" são apenas nomes de modelos de Aprendizado de Máquina. @@ -146,7 +142,7 @@ Se você está se perguntando, "AlexNet", "ResNet" e "LeNet" são apenas nomes d Em seguida, crie um *parâmetro de path* com anotação de tipo usando a classe enum que você criou (`ModelName`): -{* ../../docs_src/path_params/tutorial005.py hl[16] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *} ### Verifique a documentação { #check-the-docs } @@ -162,13 +158,13 @@ O valor do *parâmetro de path* será um *membro de enumeração*. Você pode compará-lo com o *membro de enumeração* no seu enum `ModelName` criado: -{* ../../docs_src/path_params/tutorial005.py hl[17] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *} #### Obtenha o valor da enumeração { #get-the-enumeration-value } Você pode obter o valor real (um `str` neste caso) usando `model_name.value`, ou, em geral, `your_enum_member.value`: -{* ../../docs_src/path_params/tutorial005.py hl[20] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *} /// tip | Dica Você também pode acessar o valor `"lenet"` com `ModelName.lenet.value`. @@ -180,7 +176,7 @@ Você pode retornar *membros de enum* da sua *operação de rota*, até mesmo an Eles serão convertidos para seus valores correspondentes (strings neste caso) antes de serem retornados ao cliente: -{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *} No seu cliente, você receberá uma resposta JSON como: @@ -219,7 +215,7 @@ Nesse caso, o nome do parâmetro é `file_path`, e a última parte, `:path`, diz Então, você pode usá-lo com: -{* ../../docs_src/path_params/tutorial004.py hl[6] *} +{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *} /// tip | Dica Você pode precisar que o parâmetro contenha `/home/johndoe/myfile.txt`, com uma barra inicial (`/`). diff --git a/docs/pt/docs/tutorial/query-params-str-validations.md b/docs/pt/docs/tutorial/query-params-str-validations.md index 948f8ca8fa..5ec1b1b55e 100644 --- a/docs/pt/docs/tutorial/query-params-str-validations.md +++ b/docs/pt/docs/tutorial/query-params-str-validations.md @@ -55,7 +55,7 @@ q: str | None = None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python q: Union[str, None] = None @@ -73,7 +73,7 @@ q: Annotated[str | None] = None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python q: Annotated[Union[str, None]] = None diff --git a/docs/pt/docs/tutorial/query-params.md b/docs/pt/docs/tutorial/query-params.md index 5a3fed0359..8826602a25 100644 --- a/docs/pt/docs/tutorial/query-params.md +++ b/docs/pt/docs/tutorial/query-params.md @@ -2,7 +2,7 @@ Quando você declara outros parâmetros na função que não fazem parte dos parâmetros da rota, esses parâmetros são automaticamente interpretados como parâmetros de "consulta". -{* ../../docs_src/query_params/tutorial001.py hl[9] *} +{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *} A consulta é o conjunto de pares chave-valor que vai depois de `?` na URL, separado pelo caractere `&`. @@ -127,7 +127,7 @@ Caso você não queira adicionar um valor específico mas queira apenas torná-l Porém, quando você quiser fazer com que o parâmetro de consulta seja obrigatório, você pode simplesmente não declarar nenhum valor como padrão. -{* ../../docs_src/query_params/tutorial005.py hl[6:7] *} +{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *} Aqui o parâmetro de consulta `needy` é um valor obrigatório, do tipo `str`. diff --git a/docs/pt/docs/tutorial/response-model.md b/docs/pt/docs/tutorial/response-model.md index 5958240e4c..dc66bb46c4 100644 --- a/docs/pt/docs/tutorial/response-model.md +++ b/docs/pt/docs/tutorial/response-model.md @@ -183,7 +183,7 @@ Pode haver casos em que você retorna algo que não é um campo Pydantic válido O caso mais comum seria [retornar uma Response diretamente, conforme explicado posteriormente na documentação avançada](../advanced/response-directly.md){.internal-link target=_blank}. -{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *} +{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *} Este caso simples é tratado automaticamente pelo FastAPI porque a anotação do tipo de retorno é a classe (ou uma subclasse de) `Response`. @@ -193,7 +193,7 @@ E as ferramentas também ficarão felizes porque `RedirectResponse` e ​​`JSO Você também pode usar uma subclasse de `Response` na anotação de tipo: -{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *} +{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *} Isso também funcionará porque `RedirectResponse` é uma subclasse de `Response`, e o FastAPI tratará automaticamente este caso simples. diff --git a/docs/pt/docs/tutorial/response-status-code.md b/docs/pt/docs/tutorial/response-status-code.md index 854bf57c9d..756c86dada 100644 --- a/docs/pt/docs/tutorial/response-status-code.md +++ b/docs/pt/docs/tutorial/response-status-code.md @@ -8,7 +8,7 @@ Da mesma forma que você pode especificar um modelo de resposta, você também p * `@app.delete()` * etc. -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} /// note | Nota @@ -74,7 +74,7 @@ Para saber mais sobre cada código de status e qual código serve para quê, ver Vamos ver o exemplo anterior novamente: -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} `201` é o código de status para "Criado". @@ -82,7 +82,7 @@ Mas você não precisa memorizar o que cada um desses códigos significa. Você pode usar as variáveis de conveniência de `fastapi.status`. -{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *} +{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *} Eles são apenas uma conveniência, eles possuem o mesmo número, mas dessa forma você pode usar o preenchimento automático do editor para encontrá-los: diff --git a/docs/pt/docs/tutorial/static-files.md b/docs/pt/docs/tutorial/static-files.md index 13313a909e..04a02c7f96 100644 --- a/docs/pt/docs/tutorial/static-files.md +++ b/docs/pt/docs/tutorial/static-files.md @@ -7,7 +7,7 @@ Você pode servir arquivos estáticos automaticamente a partir de um diretório * Importe `StaticFiles`. * "Monte" uma instância de `StaticFiles()` em um path específico. -{* ../../docs_src/static_files/tutorial001.py hl[2,6] *} +{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *} /// note | Detalhes Técnicos diff --git a/docs/pt/docs/tutorial/testing.md b/docs/pt/docs/tutorial/testing.md index 03f1981a3c..e56edcb8c2 100644 --- a/docs/pt/docs/tutorial/testing.md +++ b/docs/pt/docs/tutorial/testing.md @@ -30,7 +30,7 @@ Use o objeto `TestClient` da mesma forma que você faz com `httpx`. Escreva instruções `assert` simples com as expressões Python padrão que você precisa verificar (novamente, `pytest` padrão). -{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *} +{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *} /// tip | Dica @@ -76,7 +76,7 @@ Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicaç No arquivo `main.py` você tem sua aplicação **FastAPI**: -{* ../../docs_src/app_testing/main.py *} +{* ../../docs_src/app_testing/app_a_py39/main.py *} ### Arquivo de teste { #testing-file } @@ -92,7 +92,7 @@ Então você poderia ter um arquivo `test_main.py` com seus testes. Ele poderia Como esse arquivo está no mesmo pacote, você pode usar importações relativas para importar o objeto `app` do módulo `main` (`main.py`): -{* ../../docs_src/app_testing/test_main.py hl[3] *} +{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *} ...e ter o código para os testes como antes. diff --git a/docs/pt/llm-prompt.md b/docs/pt/llm-prompt.md index 01ce4143cb..2374070ced 100644 --- a/docs/pt/llm-prompt.md +++ b/docs/pt/llm-prompt.md @@ -47,7 +47,7 @@ For the next terms, use the following translations: * list (as in Python list): list * Machine Learning: Aprendizado de Máquina * media type: media type (do not translate to "tipo de mídia") -* non-Annotated: non-Annotated (do not translate non-Annotated when it comes after a Python version.e.g., “Python 3.8+ non-Annotated”) +* non-Annotated: non-Annotated (do not translate non-Annotated when it comes after a Python version.e.g., “Python 3.10+ non-Annotated”) * operation IDs: IDs de operação * path (as in URL path): path * path operation: operação de rota diff --git a/docs/ru/docs/advanced/additional-responses.md b/docs/ru/docs/advanced/additional-responses.md index 1fc3715e41..fca4f072da 100644 --- a/docs/ru/docs/advanced/additional-responses.md +++ b/docs/ru/docs/advanced/additional-responses.md @@ -26,7 +26,7 @@ Например, чтобы объявить ещё один ответ со статус-кодом `404` и Pydantic-моделью `Message`, можно написать: -{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *} +{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *} /// note | Примечание @@ -203,7 +203,7 @@ А также ответ со статус-кодом `200`, который использует ваш `response_model`, но включает пользовательский `example`: -{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *} +{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *} Всё это будет объединено и включено в ваш OpenAPI и отображено в документации API: diff --git a/docs/ru/docs/advanced/async-tests.md b/docs/ru/docs/advanced/async-tests.md index 5062bc52e7..e689704066 100644 --- a/docs/ru/docs/advanced/async-tests.md +++ b/docs/ru/docs/advanced/async-tests.md @@ -32,11 +32,11 @@ Файл `main.py`: -{* ../../docs_src/async_tests/main.py *} +{* ../../docs_src/async_tests/app_a_py39/main.py *} Файл `test_main.py` содержит тесты для `main.py`, теперь он может выглядеть так: -{* ../../docs_src/async_tests/test_main.py *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py *} ## Запуск тестов { #run-it } @@ -56,7 +56,7 @@ $ pytest Маркер `@pytest.mark.anyio` говорит pytest, что тестовая функция должна быть вызвана асинхронно: -{* ../../docs_src/async_tests/test_main.py hl[7] *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *} /// tip | Подсказка @@ -66,7 +66,7 @@ $ pytest Затем мы можем создать `AsyncClient` со ссылкой на приложение и посылать асинхронные запросы, используя `await`. -{* ../../docs_src/async_tests/test_main.py hl[9:12] *} +{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *} Это эквивалентно следующему: diff --git a/docs/ru/docs/advanced/behind-a-proxy.md b/docs/ru/docs/advanced/behind-a-proxy.md index 7119efe2dc..f78da01a09 100644 --- a/docs/ru/docs/advanced/behind-a-proxy.md +++ b/docs/ru/docs/advanced/behind-a-proxy.md @@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*" Например, вы объявили операцию пути `/items/`: -{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *} Если клиент обратится к `/items`, по умолчанию произойдёт редирект на `/items/`. @@ -115,7 +115,7 @@ sequenceDiagram Хотя весь ваш код написан с расчётом, что путь один — `/app`. -{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *} Прокси будет «обрезать» префикс пути на лету перед передачей запроса на сервер приложения (скорее всего Uvicorn, запущенный через FastAPI CLI), поддерживая у вашего приложения иллюзию, что его обслуживают по `/app`, чтобы вам не пришлось менять весь код и добавлять префикс `/api/v1`. @@ -193,7 +193,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 Здесь мы добавляем его в сообщение лишь для демонстрации. -{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *} +{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *} Затем, если вы запустите Uvicorn так: @@ -220,7 +220,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 Если нет возможности передать опцию командной строки `--root-path` (или аналог), вы можете указать параметр `root_path` при создании приложения FastAPI: -{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *} +{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *} Передача `root_path` в `FastAPI` эквивалентна опции командной строки `--root-path` для Uvicorn или Hypercorn. @@ -400,7 +400,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 Например: -{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *} +{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *} Будет сгенерирована схема OpenAPI примерно такая: @@ -455,7 +455,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 Если вы не хотите, чтобы FastAPI добавлял автоматический сервер, используя `root_path`, укажите параметр `root_path_in_servers=False`: -{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *} +{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *} и тогда этот сервер не будет добавлен в схему OpenAPI. diff --git a/docs/ru/docs/advanced/custom-response.md b/docs/ru/docs/advanced/custom-response.md index 2c238bd95b..49550b49ff 100644 --- a/docs/ru/docs/advanced/custom-response.md +++ b/docs/ru/docs/advanced/custom-response.md @@ -30,7 +30,7 @@ Но если вы уверены, что содержимое, которое вы возвращаете, **сериализуемо в JSON**, вы можете передать его напрямую в класс ответа и избежать дополнительных накладных расходов, которые FastAPI понёс бы, пропуская возвращаемое содержимое через `jsonable_encoder` перед передачей в класс ответа. -{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *} /// info | Информация @@ -55,7 +55,7 @@ - Импортируйте `HTMLResponse`. - Передайте `HTMLResponse` в параметр `response_class` вашего декоратора операции пути. -{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *} /// info | Информация @@ -73,7 +73,7 @@ Тот же пример сверху, возвращающий `HTMLResponse`, может выглядеть так: -{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *} +{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *} /// warning | Предупреждение @@ -97,7 +97,7 @@ Например, это может быть что-то вроде: -{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *} +{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *} В этом примере функция `generate_html_response()` уже генерирует и возвращает `Response` вместо возврата HTML в `str`. @@ -136,7 +136,7 @@ FastAPI (фактически Starlette) автоматически добавит заголовок Content-Length. Также будет добавлен заголовок Content-Type, основанный на `media_type` и с добавлением charset для текстовых типов. -{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} ### `HTMLResponse` { #htmlresponse } @@ -146,7 +146,7 @@ FastAPI (фактически Starlette) автоматически добави Принимает текст или байты и возвращает ответ в виде простого текста. -{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *} ### `JSONResponse` { #jsonresponse } @@ -180,7 +180,7 @@ FastAPI (фактически Starlette) автоматически добави /// -{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *} +{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *} /// tip | Совет @@ -194,13 +194,13 @@ FastAPI (фактически Starlette) автоматически добави Вы можете вернуть `RedirectResponse` напрямую: -{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *} +{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *} --- Или можно использовать его в параметре `response_class`: -{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *} Если вы сделаете так, то сможете возвращать URL напрямую из своей функции-обработчика пути. @@ -210,13 +210,13 @@ FastAPI (фактически Starlette) автоматически добави Также вы можете использовать параметр `status_code` в сочетании с параметром `response_class`: -{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} +{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *} ### `StreamingResponse` { #streamingresponse } Принимает асинхронный генератор или обычный генератор/итератор и отправляет тело ответа потоково. -{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} +{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *} #### Использование `StreamingResponse` с файлоподобными объектами { #using-streamingresponse-with-file-like-objects } @@ -226,7 +226,7 @@ FastAPI (фактически Starlette) автоматически добави Это включает многие библиотеки для работы с облачным хранилищем, обработки видео и т.д. -{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *} +{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *} 1. Это функция-генератор. Она является «функцией-генератором», потому что содержит оператор(ы) `yield` внутри. 2. Используя блок `with`, мы гарантируем, что файлоподобный объект будет закрыт после завершения работы функции-генератора. То есть после того, как она закончит отправку ответа. @@ -255,11 +255,11 @@ FastAPI (фактически Starlette) автоматически добави Файловые ответы будут содержать соответствующие заголовки `Content-Length`, `Last-Modified` и `ETag`. -{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *} +{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *} Вы также можете использовать параметр `response_class`: -{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *} +{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *} В этом случае вы можете возвращать путь к файлу напрямую из своей функции-обработчика пути. @@ -273,7 +273,7 @@ FastAPI (фактически Starlette) автоматически добави Вы могли бы создать `CustomORJSONResponse`. Главное, что вам нужно сделать — реализовать метод `Response.render(content)`, который возвращает содержимое как `bytes`: -{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *} +{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *} Теперь вместо того, чтобы возвращать: @@ -299,7 +299,7 @@ FastAPI (фактически Starlette) автоматически добави В примере ниже **FastAPI** будет использовать `ORJSONResponse` по умолчанию во всех операциях пути вместо `JSONResponse`. -{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *} +{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *} /// tip | Совет diff --git a/docs/ru/docs/advanced/events.md b/docs/ru/docs/advanced/events.md index 20d1df98a9..db73d9094e 100644 --- a/docs/ru/docs/advanced/events.md +++ b/docs/ru/docs/advanced/events.md @@ -30,7 +30,7 @@ Мы создаём асинхронную функцию `lifespan()` с `yield` примерно так: -{* ../../docs_src/events/tutorial003.py hl[16,19] *} +{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *} Здесь мы симулируем дорогую операцию startup по загрузке модели, помещая (фиктивную) функцию модели в словарь с моделями Машинного обучения до `yield`. Этот код будет выполнен до того, как приложение начнет принимать запросы, во время startup. @@ -48,7 +48,7 @@ Первое, на что стоит обратить внимание, — мы определяем асинхронную функцию с `yield`. Это очень похоже на Зависимости с `yield`. -{* ../../docs_src/events/tutorial003.py hl[14:19] *} +{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *} Первая часть функции, до `yield`, будет выполнена до запуска приложения. @@ -60,7 +60,7 @@ Это превращает функцию в «асинхронный менеджер контекста». -{* ../../docs_src/events/tutorial003.py hl[1,13] *} +{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *} Менеджер контекста в Python — это то, что можно использовать в операторе `with`. Например, `open()` можно использовать как менеджер контекста: @@ -82,7 +82,7 @@ async with lifespan(app): Параметр `lifespan` приложения `FastAPI` принимает асинхронный менеджер контекста, поэтому мы можем передать ему наш новый асинхронный менеджер контекста `lifespan`. -{* ../../docs_src/events/tutorial003.py hl[22] *} +{* ../../docs_src/events/tutorial003_py39.py hl[22] *} ## Альтернативные события (устаревшие) { #alternative-events-deprecated } @@ -104,7 +104,7 @@ async with lifespan(app): Чтобы добавить функцию, которую нужно запустить до старта приложения, объявите её как обработчик события `"startup"`: -{* ../../docs_src/events/tutorial001.py hl[8] *} +{* ../../docs_src/events/tutorial001_py39.py hl[8] *} В этом случае функция-обработчик события `startup` инициализирует «базу данных» items (это просто `dict`) некоторыми значениями. @@ -116,7 +116,7 @@ async with lifespan(app): Чтобы добавить функцию, которую нужно запустить при завершении работы приложения, объявите её как обработчик события `"shutdown"`: -{* ../../docs_src/events/tutorial002.py hl[6] *} +{* ../../docs_src/events/tutorial002_py39.py hl[6] *} Здесь функция-обработчик события `shutdown` запишет строку текста `"Application shutdown"` в файл `log.txt`. diff --git a/docs/ru/docs/advanced/generate-clients.md b/docs/ru/docs/advanced/generate-clients.md index ee52412c6d..00bdd31fe8 100644 --- a/docs/ru/docs/advanced/generate-clients.md +++ b/docs/ru/docs/advanced/generate-clients.md @@ -167,7 +167,7 @@ FastAPI использует **уникальный ID** для каждой *о Мы можем скачать OpenAPI JSON в файл `openapi.json`, а затем **убрать этот префикс‑тег** таким скриптом: -{* ../../docs_src/generate_clients/tutorial004.py *} +{* ../../docs_src/generate_clients/tutorial004_py39.py *} //// tab | Node.js diff --git a/docs/ru/docs/advanced/middleware.md b/docs/ru/docs/advanced/middleware.md index 82c86b2317..5ebe010782 100644 --- a/docs/ru/docs/advanced/middleware.md +++ b/docs/ru/docs/advanced/middleware.md @@ -57,13 +57,13 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") Любой входящий запрос по `http` или `ws` будет перенаправлен на безопасную схему. -{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *} +{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *} ## `TrustedHostMiddleware` { #trustedhostmiddleware } Гарантирует, что во всех входящих запросах корректно установлен `Host`‑заголовок, чтобы защититься от атак на HTTP‑заголовок Host. -{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *} +{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *} Поддерживаются следующие аргументы: @@ -78,7 +78,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow") Это middleware обрабатывает как обычные, так и потоковые ответы. -{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *} +{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *} Поддерживаются следующие аргументы: diff --git a/docs/ru/docs/advanced/openapi-webhooks.md b/docs/ru/docs/advanced/openapi-webhooks.md index d38cf315f7..3a2b9fff74 100644 --- a/docs/ru/docs/advanced/openapi-webhooks.md +++ b/docs/ru/docs/advanced/openapi-webhooks.md @@ -32,7 +32,7 @@ При создании приложения на **FastAPI** есть атрибут `webhooks`, с помощью которого можно объявлять вебхуки так же, как вы объявляете операции пути (обработчики пути), например с `@app.webhooks.post()`. -{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *} +{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *} Определенные вами вебхуки попадут в схему **OpenAPI** и в автоматический **интерфейс документации**. diff --git a/docs/ru/docs/advanced/path-operation-advanced-configuration.md b/docs/ru/docs/advanced/path-operation-advanced-configuration.md index 78a16a5583..eaf9ad0528 100644 --- a/docs/ru/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/ru/docs/advanced/path-operation-advanced-configuration.md @@ -12,7 +12,7 @@ Нужно убедиться, что он уникален для каждой операции. -{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *} ### Использование имени функции-обработчика пути как operationId { #using-the-path-operation-function-name-as-the-operationid } @@ -20,7 +20,7 @@ Делать это следует после добавления всех *операций пути*. -{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *} /// tip | Совет @@ -40,7 +40,7 @@ Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматической документации), используйте параметр `include_in_schema` и установите его в `False`: -{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *} ## Расширенное описание из docstring { #advanced-description-from-docstring } @@ -92,7 +92,7 @@ `openapi_extra` может пригодиться, например, чтобы объявить [Расширения OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): -{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *} Если вы откроете автоматическую документацию API, ваше расширение появится внизу страницы конкретной *операции пути*. @@ -139,7 +139,7 @@ Это можно сделать с помощью `openapi_extra`: -{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *} В этом примере мы не объявляли никакую Pydantic-модель. Фактически тело запроса даже не распарсено как JSON, оно читается напрямую как `bytes`, а функция `magic_data_reader()` будет отвечать за его парсинг каким-то способом. diff --git a/docs/ru/docs/advanced/response-change-status-code.md b/docs/ru/docs/advanced/response-change-status-code.md index e9e1c9470f..85d9050ffc 100644 --- a/docs/ru/docs/advanced/response-change-status-code.md +++ b/docs/ru/docs/advanced/response-change-status-code.md @@ -20,7 +20,7 @@ И затем вы можете установить `status_code` в этом *временном* объекте ответа. -{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} +{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *} После этого вы можете вернуть любой объект, который вам нужен, как обычно (`dict`, модель базы данных и т.д.). diff --git a/docs/ru/docs/advanced/response-cookies.md b/docs/ru/docs/advanced/response-cookies.md index 9319aba6e2..2872d6c0ad 100644 --- a/docs/ru/docs/advanced/response-cookies.md +++ b/docs/ru/docs/advanced/response-cookies.md @@ -6,7 +6,7 @@ Затем установить cookies в этом временном объекте ответа. -{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *} +{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *} После этого можно вернуть любой объект, как и раньше (например, `dict`, объект модели базы данных и так далее). @@ -24,7 +24,7 @@ Затем установите cookies и верните этот объект: -{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *} /// tip | Совет diff --git a/docs/ru/docs/advanced/response-directly.md b/docs/ru/docs/advanced/response-directly.md index 3c10633e91..b452810714 100644 --- a/docs/ru/docs/advanced/response-directly.md +++ b/docs/ru/docs/advanced/response-directly.md @@ -54,7 +54,7 @@ Вы можете поместить ваш XML-контент в строку, поместить её в `Response` и вернуть: -{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} +{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *} ## Примечания { #notes } diff --git a/docs/ru/docs/advanced/response-headers.md b/docs/ru/docs/advanced/response-headers.md index 1c9360b31d..8f24f05b07 100644 --- a/docs/ru/docs/advanced/response-headers.md +++ b/docs/ru/docs/advanced/response-headers.md @@ -6,7 +6,7 @@ А затем вы можете устанавливать HTTP-заголовки в этом *временном* объекте ответа. -{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *} +{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *} После этого вы можете вернуть любой нужный объект, как обычно (например, `dict`, модель из базы данных и т.д.). @@ -22,7 +22,7 @@ Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, и передайте заголовки как дополнительный параметр: -{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *} +{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *} /// note | Технические детали diff --git a/docs/ru/docs/advanced/settings.md b/docs/ru/docs/advanced/settings.md index 0ef46fb13c..b96ee44a3a 100644 --- a/docs/ru/docs/advanced/settings.md +++ b/docs/ru/docs/advanced/settings.md @@ -62,7 +62,7 @@ $ pip install "fastapi[all]" //// tab | Pydantic v2 -{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *} +{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *} //// @@ -74,7 +74,7 @@ $ pip install "fastapi[all]" /// -{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *} +{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *} //// @@ -92,7 +92,7 @@ $ pip install "fastapi[all]" Затем вы можете использовать новый объект `settings` в вашем приложении: -{* ../../docs_src/settings/tutorial001.py hl[18:20] *} +{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *} ### Запуск сервера { #run-the-server } @@ -126,11 +126,11 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p Например, у вас может быть файл `config.py` со следующим содержимым: -{* ../../docs_src/settings/app01/config.py *} +{* ../../docs_src/settings/app01_py39/config.py *} А затем использовать его в файле `main.py`: -{* ../../docs_src/settings/app01/main.py hl[3,11:13] *} +{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *} /// tip | Совет diff --git a/docs/ru/docs/advanced/sub-applications.md b/docs/ru/docs/advanced/sub-applications.md index 3464f17040..fa5a683f45 100644 --- a/docs/ru/docs/advanced/sub-applications.md +++ b/docs/ru/docs/advanced/sub-applications.md @@ -10,7 +10,7 @@ Сначала создайте основное, верхнего уровня, приложение **FastAPI** и его *операции пути*: -{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *} +{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *} ### Подприложение { #sub-application } @@ -18,7 +18,7 @@ Это подприложение — обычное стандартное приложение FastAPI, но именно оно будет «смонтировано»: -{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *} +{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *} ### Смонтируйте подприложение { #mount-the-sub-application } @@ -26,7 +26,7 @@ В этом случае оно будет смонтировано по пути `/subapi`: -{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *} +{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *} ### Проверьте автоматическую документацию API { #check-the-automatic-api-docs } diff --git a/docs/ru/docs/advanced/templates.md b/docs/ru/docs/advanced/templates.md index 204e887605..460e2e4660 100644 --- a/docs/ru/docs/advanced/templates.md +++ b/docs/ru/docs/advanced/templates.md @@ -27,7 +27,7 @@ $ pip install jinja2 - Объявите параметр `Request` в *операции пути*, которая будет возвращать шаблон. - Используйте созданный `templates`, чтобы отрендерить и вернуть `TemplateResponse`; передайте имя шаблона, объект `request` и словарь «context» с парами ключ-значение для использования внутри шаблона Jinja2. -{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *} +{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *} /// note | Примечание diff --git a/docs/ru/docs/advanced/testing-events.md b/docs/ru/docs/advanced/testing-events.md index e0ec774399..82caea845b 100644 --- a/docs/ru/docs/advanced/testing-events.md +++ b/docs/ru/docs/advanced/testing-events.md @@ -2,11 +2,11 @@ Если вам нужно, чтобы `lifespan` выполнялся в ваших тестах, вы можете использовать `TestClient` вместе с оператором `with`: -{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *} +{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *} Вы можете узнать больше подробностей в статье [Запуск lifespan в тестах на официальном сайте документации Starlette.](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) Для устаревших событий `startup` и `shutdown` вы можете использовать `TestClient` следующим образом: -{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *} +{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *} diff --git a/docs/ru/docs/advanced/testing-websockets.md b/docs/ru/docs/advanced/testing-websockets.md index e840a03f28..b6626679e4 100644 --- a/docs/ru/docs/advanced/testing-websockets.md +++ b/docs/ru/docs/advanced/testing-websockets.md @@ -4,7 +4,7 @@ Для этого используйте `TestClient` с менеджером контекста `with`, подключаясь к WebSocket: -{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *} +{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *} /// note | Примечание diff --git a/docs/ru/docs/advanced/using-request-directly.md b/docs/ru/docs/advanced/using-request-directly.md index b922216105..cdf500c0e2 100644 --- a/docs/ru/docs/advanced/using-request-directly.md +++ b/docs/ru/docs/advanced/using-request-directly.md @@ -29,7 +29,7 @@ Для этого нужно обратиться к запросу напрямую. -{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *} +{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *} Если объявить параметр *функции-обработчика пути* с типом `Request`, **FastAPI** поймёт, что нужно передать объект `Request` в этот параметр. diff --git a/docs/ru/docs/advanced/websockets.md b/docs/ru/docs/advanced/websockets.md index f26185bea5..fa5e4738eb 100644 --- a/docs/ru/docs/advanced/websockets.md +++ b/docs/ru/docs/advanced/websockets.md @@ -38,13 +38,13 @@ $ pip install websockets Для примера нам нужен наиболее простой способ, который позволит сосредоточиться на серверной части веб‑сокетов и получить рабочий код: -{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *} ## Создание `websocket` { #create-a-websocket } Создайте `websocket` в своем **FastAPI** приложении: -{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *} /// note | Технические детали @@ -58,7 +58,7 @@ $ pip install websockets Через эндпоинт веб-сокета вы можете получать и отправлять сообщения. -{* ../../docs_src/websockets/tutorial001.py hl[48:52] *} +{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *} Вы можете получать и отправлять двоичные, текстовые и JSON данные. diff --git a/docs/ru/docs/advanced/wsgi.md b/docs/ru/docs/advanced/wsgi.md index 1c5bf0a626..64d7c7a289 100644 --- a/docs/ru/docs/advanced/wsgi.md +++ b/docs/ru/docs/advanced/wsgi.md @@ -12,7 +12,7 @@ После этого смонтируйте его на путь. -{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *} +{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *} ## Проверьте { #check-it } diff --git a/docs/ru/docs/how-to/conditional-openapi.md b/docs/ru/docs/how-to/conditional-openapi.md index dc987ae26b..d0845b91e2 100644 --- a/docs/ru/docs/how-to/conditional-openapi.md +++ b/docs/ru/docs/how-to/conditional-openapi.md @@ -29,7 +29,7 @@ Например: -{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *} +{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *} Здесь мы объявляем настройку `openapi_url` с тем же значением по умолчанию — `"/openapi.json"`. diff --git a/docs/ru/docs/how-to/configure-swagger-ui.md b/docs/ru/docs/how-to/configure-swagger-ui.md index 9d104423d7..b3b1c1ba62 100644 --- a/docs/ru/docs/how-to/configure-swagger-ui.md +++ b/docs/ru/docs/how-to/configure-swagger-ui.md @@ -18,7 +18,7 @@ FastAPI преобразует эти настройки в **JSON**, чтобы Но вы можете отключить её, установив `syntaxHighlight` в `False`: -{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *} …и после этого Swagger UI больше не будет показывать подсветку синтаксиса: @@ -28,7 +28,7 @@ FastAPI преобразует эти настройки в **JSON**, чтобы Аналогично вы можете задать тему подсветки синтаксиса с ключом "syntaxHighlight.theme" (обратите внимание, что посередине стоит точка): -{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *} Эта настройка изменит цветовую тему подсветки синтаксиса: @@ -46,7 +46,7 @@ FastAPI включает некоторые параметры конфигур Например, чтобы отключить `deepLinking`, можно передать такие настройки в `swagger_ui_parameters`: -{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *} +{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *} ## Другие параметры Swagger UI { #other-swagger-ui-parameters } diff --git a/docs/ru/docs/how-to/custom-docs-ui-assets.md b/docs/ru/docs/how-to/custom-docs-ui-assets.md index c07a9695b9..f524911e65 100644 --- a/docs/ru/docs/how-to/custom-docs-ui-assets.md +++ b/docs/ru/docs/how-to/custom-docs-ui-assets.md @@ -18,7 +18,7 @@ Чтобы отключить её, установите их URL в значение `None` при создании вашего приложения `FastAPI`: -{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *} +{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *} ### Подключить пользовательскую документацию { #include-the-custom-docs } @@ -34,7 +34,7 @@ Аналогично и для ReDoc... -{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *} +{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *} /// tip | Совет @@ -50,7 +50,7 @@ Swagger UI сделает это за вас «за кулисами», но д Чтобы убедиться, что всё работает, создайте *операцию пути*: -{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *} +{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *} ### Тестирование { #test-it } @@ -118,7 +118,7 @@ Swagger UI сделает это за вас «за кулисами», но д * Импортируйте `StaticFiles`. * Смонтируйте экземпляр `StaticFiles()` в определённый путь. -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *} ### Протестируйте статические файлы { #test-the-static-files } @@ -144,7 +144,7 @@ Swagger UI сделает это за вас «за кулисами», но д Чтобы отключить её, установите их URL в значение `None` при создании вашего приложения `FastAPI`: -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *} ### Подключить пользовательскую документацию со статическими файлами { #include-the-custom-docs-for-static-files } @@ -160,7 +160,7 @@ Swagger UI сделает это за вас «за кулисами», но д Аналогично и для ReDoc... -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *} /// tip | Совет @@ -176,7 +176,7 @@ Swagger UI сделает это за вас «за кулисами», но д Чтобы убедиться, что всё работает, создайте *операцию пути*: -{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *} +{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *} ### Тестирование UI со статическими файлами { #test-static-files-ui } diff --git a/docs/ru/docs/how-to/extending-openapi.md b/docs/ru/docs/how-to/extending-openapi.md index 2897fb89ba..1d69cbdb3a 100644 --- a/docs/ru/docs/how-to/extending-openapi.md +++ b/docs/ru/docs/how-to/extending-openapi.md @@ -43,19 +43,19 @@ Сначала напишите приложение **FastAPI** как обычно: -{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *} +{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *} ### Сгенерируйте схему OpenAPI { #generate-the-openapi-schema } Затем используйте ту же вспомогательную функцию для генерации схемы OpenAPI внутри функции `custom_openapi()`: -{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *} +{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *} ### Измените схему OpenAPI { #modify-the-openapi-schema } Теперь можно добавить расширение ReDoc, добавив кастомный `x-logo` в «объект» `info` в схеме OpenAPI: -{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *} +{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *} ### Кэшируйте схему OpenAPI { #cache-the-openapi-schema } @@ -65,13 +65,13 @@ Она будет создана один раз, а затем тот же кэшированный вариант будет использоваться для последующих запросов. -{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *} +{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *} ### Переопределите метод { #override-the-method } Теперь вы можете заменить метод `.openapi()` на вашу новую функцию. -{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *} +{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *} ### Проверьте { #check-it } diff --git a/docs/ru/docs/how-to/graphql.md b/docs/ru/docs/how-to/graphql.md index 9ed6d95ca1..97278069ad 100644 --- a/docs/ru/docs/how-to/graphql.md +++ b/docs/ru/docs/how-to/graphql.md @@ -35,7 +35,7 @@ Вот небольшой пример того, как можно интегрировать Strawberry с FastAPI: -{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *} +{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *} Подробнее о Strawberry можно узнать в документации Strawberry. diff --git a/docs/ru/docs/python-types.md b/docs/ru/docs/python-types.md index 84a901f547..ae4a1e2b79 100644 --- a/docs/ru/docs/python-types.md +++ b/docs/ru/docs/python-types.md @@ -22,7 +22,7 @@ Python поддерживает необязательные «подсказк Давайте начнем с простого примера: -{* ../../docs_src/python_types/tutorial001.py *} +{* ../../docs_src/python_types/tutorial001_py39.py *} Вызов этой программы выводит: @@ -36,7 +36,7 @@ John Doe * Преобразует первую букву каждого значения в верхний регистр с помощью `title()`. * Соединяет их пробелом посередине. -{* ../../docs_src/python_types/tutorial001.py hl[2] *} +{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *} ### Отредактируем пример { #edit-it } @@ -78,7 +78,7 @@ John Doe Это и есть «подсказки типов»: -{* ../../docs_src/python_types/tutorial002.py hl[1] *} +{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *} Это не то же самое, что объявление значений по умолчанию, как, например: @@ -106,7 +106,7 @@ John Doe Посмотрите на эту функцию — у неё уже есть подсказки типов: -{* ../../docs_src/python_types/tutorial003.py hl[1] *} +{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *} Так как редактор кода знает типы переменных, вы получаете не только автозавершение, но и проверки ошибок: @@ -114,7 +114,7 @@ John Doe Теперь вы знаете, что нужно исправить — преобразовать `age` в строку с помощью `str(age)`: -{* ../../docs_src/python_types/tutorial004.py hl[2] *} +{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *} ## Объявление типов { #declaring-types } @@ -133,7 +133,7 @@ John Doe * `bool` * `bytes` -{* ../../docs_src/python_types/tutorial005.py hl[1] *} +{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *} ### Generic-типы с параметрами типов { #generic-types-with-type-parameters } @@ -161,56 +161,24 @@ John Doe Например, давайте определим переменную как `list` из `str`. -//// tab | Python 3.9+ - Объявите переменную с тем же синтаксисом двоеточия (`:`). В качестве типа укажите `list`. Так как список — это тип, содержащий внутренние типы, укажите их в квадратных скобках: -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -Из `typing` импортируйте `List` (с заглавной `L`): - -```Python hl_lines="1" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -Объявите переменную с тем же синтаксисом двоеточия (`:`). - -В качестве типа используйте `List`, который вы импортировали из `typing`. - -Так как список — это тип, содержащий внутренние типы, укажите их в квадратных скобках: - -```Python hl_lines="4" -{!> ../../docs_src/python_types/tutorial006.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *} /// info | Информация Эти внутренние типы в квадратных скобках называются «параметрами типов». -В данном случае `str` — это параметр типа, передаваемый в `List` (или `list` в Python 3.9 и выше). +В данном случае `str` — это параметр типа, передаваемый в `list`. /// Это означает: «переменная `items` — это `list`, и каждый элемент этого списка — `str`». -/// tip | Совет - -Если вы используете Python 3.9 или выше, вам не нужно импортировать `List` из `typing`, можно использовать обычный встроенный тип `list`. - -/// - Таким образом, ваш редактор кода сможет помогать даже при обработке элементов списка: @@ -225,21 +193,7 @@ John Doe Аналогично вы бы объявили `tuple` и `set`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *} Это означает: @@ -254,21 +208,7 @@ John Doe Второй параметр типа — для значений `dict`: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *} Это означает: @@ -292,10 +232,10 @@ John Doe //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial008b.py!} +{!> ../../docs_src/python_types/tutorial008b_py39.py!} ``` //// @@ -309,7 +249,7 @@ John Doe В Python 3.6 и выше (включая Python 3.10) это можно объявить, импортировав и используя `Optional` из модуля `typing`. ```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009.py!} +{!../../docs_src/python_types/tutorial009_py39.py!} ``` Использование `Optional[str]` вместо просто `str` позволит редактору кода помочь вам обнаружить ошибки, когда вы предполагаете, что значение всегда `str`, хотя на самом деле оно может быть и `None`. @@ -326,18 +266,18 @@ John Doe //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009.py!} +{!> ../../docs_src/python_types/tutorial009_py39.py!} ``` //// -//// tab | Python 3.8+ альтернативный вариант +//// tab | Python 3.9+ альтернативный вариант ```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial009b.py!} +{!> ../../docs_src/python_types/tutorial009b_py39.py!} ``` //// @@ -357,7 +297,7 @@ John Doe В качестве примера возьмём эту функцию: -{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} +{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *} Параметр `name` определён как `Optional[str]`, но он **не необязательный** — вы не можете вызвать функцию без этого параметра: @@ -390,10 +330,10 @@ say_hi(name=None) # Это работает, None допустим 🎉 * `set` * `dict` -И, как и в Python 3.8, из модуля `typing`: +И, как и в предыдущих версиях Python, из модуля `typing`: * `Union` -* `Optional` (так же, как в Python 3.8) +* `Optional` * ...и другие. В Python 3.10, как альтернативу generics `Union` и `Optional`, можно использовать вертикальную черту (`|`) для объявления объединений типов — это гораздо лучше и проще. @@ -409,7 +349,7 @@ say_hi(name=None) # Это работает, None допустим 🎉 * `set` * `dict` -И, как и в Python 3.8, из модуля `typing`: +И generics из модуля `typing`: * `Union` * `Optional` @@ -417,29 +357,17 @@ say_hi(name=None) # Это работает, None допустим 🎉 //// -//// tab | Python 3.8+ - -* `List` -* `Tuple` -* `Set` -* `Dict` -* `Union` -* `Optional` -* ...и другие. - -//// - ### Классы как типы { #classes-as-types } Вы также можете объявлять класс как тип переменной. Допустим, у вас есть класс `Person` с именем: -{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *} Тогда вы можете объявить переменную типа `Person`: -{* ../../docs_src/python_types/tutorial010.py hl[6] *} +{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *} И снова вы получите полную поддержку редактора кода: @@ -463,29 +391,7 @@ say_hi(name=None) # Это работает, None допустим 🎉 Пример из официальной документации Pydantic: -//// tab | Python 3.10+ - -```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!} -``` - -//// +{* ../../docs_src/python_types/tutorial011_py310.py *} /// info | Информация @@ -507,27 +413,9 @@ say_hi(name=None) # Это работает, None допустим 🎉 В Python также есть возможность добавлять **дополнительные метаданные** к подсказкам типов с помощью `Annotated`. -//// tab | Python 3.9+ +Начиная с Python 3.9, `Annotated` входит в стандартную библиотеку, поэтому вы можете импортировать его из `typing`. -В Python 3.9 `Annotated` входит в стандартную библиотеку, поэтому вы можете импортировать его из `typing`. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013_py39.py!} -``` - -//// - -//// tab | Python 3.8+ - -В версиях ниже Python 3.9 импортируйте `Annotated` из `typing_extensions`. - -Он уже будет установлен вместе с **FastAPI**. - -```Python hl_lines="1 4" -{!> ../../docs_src/python_types/tutorial013.py!} -``` - -//// +{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *} Сам Python ничего не делает с `Annotated`. А для редакторов кода и других инструментов тип по-прежнему `str`. @@ -558,7 +446,7 @@ say_hi(name=None) # Это работает, None допустим 🎉 ...и **FastAPI** использует эти же объявления для: -* **Определения требований**: из path-параметров, query-параметров, HTTP-заголовков, тел запросов, зависимостей и т.д. +* **Определения требований**: из path-параметров пути запроса, query-параметров, HTTP-заголовков, тел запросов, зависимостей и т.д. * **Преобразования данных**: из HTTP-запроса к требуемому типу. * **Валидации данных**: приходящих с каждого HTTP-запроса: * Генерации **автоматических ошибок**, возвращаемых клиенту, когда данные некорректны. diff --git a/docs/ru/docs/tutorial/background-tasks.md b/docs/ru/docs/tutorial/background-tasks.md index 1ed8522d69..8d7b7442f9 100644 --- a/docs/ru/docs/tutorial/background-tasks.md +++ b/docs/ru/docs/tutorial/background-tasks.md @@ -15,7 +15,7 @@ Сначала импортируйте `BackgroundTasks` и объявите параметр в вашей функции‑обработчике пути с типом `BackgroundTasks`: -{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *} **FastAPI** создаст объект типа `BackgroundTasks` для вас и передаст его через этот параметр. @@ -31,13 +31,13 @@ Так как операция записи не использует `async` и `await`, мы определим функцию как обычную `def`: -{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *} ## Добавление фоновой задачи { #add-the-background-task } Внутри вашей функции‑обработчика пути передайте функцию задачи объекту фоновых задач методом `.add_task()`: -{* ../../docs_src/background_tasks/tutorial001.py hl[14] *} +{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *} `.add_task()` принимает следующие аргументы: diff --git a/docs/ru/docs/tutorial/body-nested-models.md b/docs/ru/docs/tutorial/body-nested-models.md index 5bb5abbe63..4c914b97f0 100644 --- a/docs/ru/docs/tutorial/body-nested-models.md +++ b/docs/ru/docs/tutorial/body-nested-models.md @@ -14,35 +14,14 @@ В Python есть специальный способ объявлять списки с внутренними типами, или «параметрами типа»: -### Импортируйте `List` из модуля typing { #import-typings-list } - -В Python 3.9 и выше вы можете использовать стандартный тип `list` для объявления аннотаций типов, как мы увидим ниже. 💡 - -Но в версиях Python до 3.9 (начиная с 3.6) сначала вам необходимо импортировать `List` из стандартного модуля `typing`: - -{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *} - ### Объявите `list` с параметром типа { #declare-a-list-with-a-type-parameter } -Для объявления типов, у которых есть параметры типа (внутренние типы), таких как `list`, `dict`, `tuple`: - -* Если у вас Python версии ниже 3.9, импортируйте их аналоги из модуля `typing` -* Передайте внутренний(ие) тип(ы) как «параметры типа», используя квадратные скобки: `[` и `]` - -В Python 3.9 это будет: +Для объявления типов, у которых есть параметры типа (внутренние типы), таких как `list`, `dict`, `tuple`, передайте внутренний(ие) тип(ы) как «параметры типа», используя квадратные скобки: `[` и `]` ```Python my_list: list[str] ``` -В версиях Python до 3.9 это будет: - -```Python -from typing import List - -my_list: List[str] -``` - Это всё стандартный синтаксис Python для объявления типов. Используйте этот же стандартный синтаксис для атрибутов модели с внутренними типами. @@ -107,7 +86,7 @@ my_list: List[str] Ещё раз: сделав такое объявление, с помощью **FastAPI** вы получите: -* Поддержку редактора кода (автозавершение и т. д.), даже для вложенных моделей +* Поддержку редактора кода (автозавершение и т.д.), даже для вложенных моделей * Преобразование данных * Валидацию данных * Автоматическую документацию @@ -178,12 +157,6 @@ my_list: List[str] Если верхний уровень значения тела JSON-объекта представляет собой JSON `array` (в Python — `list`), вы можете объявить тип в параметре функции, так же как в моделях Pydantic: -```Python -images: List[Image] -``` - -или в Python 3.9 и выше: - ```Python images: list[Image] ``` diff --git a/docs/ru/docs/tutorial/body.md b/docs/ru/docs/tutorial/body.md index 16ff6466c1..b61f3e7a09 100644 --- a/docs/ru/docs/tutorial/body.md +++ b/docs/ru/docs/tutorial/body.md @@ -161,7 +161,7 @@ JSON Schema ваших моделей будет частью сгенериро FastAPI понимает, что значение `q` не является обязательным из-за значения по умолчанию `= None`. -Аннотации типов `str | None` (Python 3.10+) или `Union[str, None]` (Python 3.8+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`. +Аннотации типов `str | None` (Python 3.10+) или `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`. Но добавление аннотаций типов позволит вашему редактору кода лучше вас поддерживать и обнаруживать ошибки. diff --git a/docs/ru/docs/tutorial/cors.md b/docs/ru/docs/tutorial/cors.md index b0704351a9..d09a31e2c3 100644 --- a/docs/ru/docs/tutorial/cors.md +++ b/docs/ru/docs/tutorial/cors.md @@ -46,7 +46,7 @@ * Отдельных HTTP-методов (`POST`, `PUT`) или всех вместе, используя `"*"`. * Отдельных HTTP-заголовков или всех вместе, используя `"*"`. -{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *} +{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *} `CORSMiddleware` использует "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте. diff --git a/docs/ru/docs/tutorial/debugging.md b/docs/ru/docs/tutorial/debugging.md index a5340af089..51955835e6 100644 --- a/docs/ru/docs/tutorial/debugging.md +++ b/docs/ru/docs/tutorial/debugging.md @@ -6,7 +6,7 @@ В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую: -{* ../../docs_src/debugging/tutorial001.py hl[1,15] *} +{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *} ### Описание `__name__ == "__main__"` { #about-name-main } diff --git a/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md index ec7770d960..a38e885d43 100644 --- a/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md +++ b/docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md @@ -101,7 +101,7 @@ fluffy = Cat(name="Mr Fluffy") Обратите внимание, что в приведенном выше коде мы два раза пишем `CommonQueryParams`: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Подсказка @@ -137,7 +137,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) В этом случае первый `CommonQueryParams`, в: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, ... @@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ... //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Подсказка @@ -163,7 +163,7 @@ commons: CommonQueryParams ... На самом деле можно написать просто: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[Any, Depends(CommonQueryParams)] @@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Подсказка @@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams) Но вы видите, что здесь мы имеем некоторое повторение кода, дважды написав `CommonQueryParams`: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Подсказка @@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) Вместо того чтобы писать: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] @@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)] //// -//// tab | Python 3.8+ non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Подсказка @@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams) ...следует написать: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python commons: Annotated[CommonQueryParams, Depends()] @@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()] //// -//// tab | Python 3.8 non-Annotated +//// tab | Python 3.9+ non-Annotated /// tip | Подсказка diff --git a/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md index 7ff85246dc..dc202db616 100644 --- a/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md @@ -29,15 +29,15 @@ FastAPI поддерживает зависимости, которые выпо Перед созданием ответа будет выполнен только код до и включая оператор `yield`: -{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *} Значение, полученное из `yield`, внедряется в *операции пути* и другие зависимости: -{* ../../docs_src/dependencies/tutorial007.py hl[4] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *} Код, следующий за оператором `yield`, выполняется после ответа: -{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *} /// tip | Подсказка @@ -57,7 +57,7 @@ FastAPI поддерживает зависимости, которые выпо Точно так же можно использовать `finally`, чтобы убедиться, что обязательные шаги при выходе выполнены независимо от того, было ли исключение или нет. -{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *} +{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *} ## Подзависимости с `yield` { #sub-dependencies-with-yield } @@ -269,7 +269,7 @@ with open("./somefile.txt") as f: Их также можно использовать внутри зависимостей **FastAPI** с `yield`, применяя операторы `with` или `async with` внутри функции зависимости: -{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *} +{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *} /// tip | Подсказка diff --git a/docs/ru/docs/tutorial/dependencies/global-dependencies.md b/docs/ru/docs/tutorial/dependencies/global-dependencies.md index 075d6b0baa..2347c6dd83 100644 --- a/docs/ru/docs/tutorial/dependencies/global-dependencies.md +++ b/docs/ru/docs/tutorial/dependencies/global-dependencies.md @@ -6,7 +6,7 @@ В этом случае они будут применяться ко всем *операциям пути* в приложении: -{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *} +{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *} Все способы [добавления `dependencies` (зависимостей) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} по-прежнему применимы, но в данном случае зависимости применяются ко всем *операциям пути* приложения. diff --git a/docs/ru/docs/tutorial/dependencies/sub-dependencies.md b/docs/ru/docs/tutorial/dependencies/sub-dependencies.md index efe8d98c31..da31a6682f 100644 --- a/docs/ru/docs/tutorial/dependencies/sub-dependencies.md +++ b/docs/ru/docs/tutorial/dependencies/sub-dependencies.md @@ -62,7 +62,7 @@ query_extractor --> query_or_cookie_extractor --> read_query В расширенном сценарии, когда вы знаете, что вам нужно, чтобы зависимость вызывалась на каждом шаге (возможно, несколько раз) в одном и том же запросе, вместо использования "кэшированного" значения, вы можете установить параметр `use_cache=False` при использовании `Depends`: -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python hl_lines="1" 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+ без Annotated +//// tab | Python 3.9+ без Annotated /// tip | Подсказка diff --git a/docs/ru/docs/tutorial/first-steps.md b/docs/ru/docs/tutorial/first-steps.md index 6f59d72054..798c03d517 100644 --- a/docs/ru/docs/tutorial/first-steps.md +++ b/docs/ru/docs/tutorial/first-steps.md @@ -2,7 +2,7 @@ Самый простой файл FastAPI может выглядеть так: -{* ../../docs_src/first_steps/tutorial001.py *} +{* ../../docs_src/first_steps/tutorial001_py39.py *} Скопируйте это в файл `main.py`. @@ -183,7 +183,7 @@ Deploying to FastAPI Cloud... ### Шаг 1: импортируйте `FastAPI` { #step-1-import-fastapi } -{* ../../docs_src/first_steps/tutorial001.py hl[1] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *} `FastAPI` — это класс на Python, который предоставляет всю функциональность для вашего API. @@ -197,7 +197,7 @@ Deploying to FastAPI Cloud... ### Шаг 2: создайте экземпляр `FastAPI` { #step-2-create-a-fastapi-instance } -{* ../../docs_src/first_steps/tutorial001.py hl[3] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *} Здесь переменная `app` будет экземпляром класса `FastAPI`. @@ -266,7 +266,7 @@ https://example.com/items/foo #### Определите *декоратор операции пути (path operation decorator)* { #define-a-path-operation-decorator } -{* ../../docs_src/first_steps/tutorial001.py hl[6] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *} `@app.get("/")` сообщает **FastAPI**, что функция прямо под ним отвечает за обработку запросов, поступающих: @@ -320,7 +320,7 @@ https://example.com/items/foo * **операция**: `get`. * **функция**: функция ниже «декоратора» (ниже `@app.get("/")`). -{* ../../docs_src/first_steps/tutorial001.py hl[7] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *} Это функция на Python. @@ -332,7 +332,7 @@ https://example.com/items/foo Вы также можете определить её как обычную функцию вместо `async def`: -{* ../../docs_src/first_steps/tutorial003.py hl[7] *} +{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *} /// note | Примечание @@ -342,7 +342,7 @@ https://example.com/items/foo ### Шаг 5: верните содержимое { #step-5-return-the-content } -{* ../../docs_src/first_steps/tutorial001.py hl[8] *} +{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *} Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д. diff --git a/docs/ru/docs/tutorial/handling-errors.md b/docs/ru/docs/tutorial/handling-errors.md index 63ca8665ef..2e00d70759 100644 --- a/docs/ru/docs/tutorial/handling-errors.md +++ b/docs/ru/docs/tutorial/handling-errors.md @@ -25,7 +25,7 @@ ### Импортируйте `HTTPException` { #import-httpexception } -{* ../../docs_src/handling_errors/tutorial001.py hl[1] *} +{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *} ### Вызовите `HTTPException` в своем коде { #raise-an-httpexception-in-your-code } @@ -39,7 +39,7 @@ В данном примере, когда клиент запрашивает элемент по несуществующему ID, возникает исключение со статус-кодом `404`: -{* ../../docs_src/handling_errors/tutorial001.py hl[11] *} +{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *} ### Возвращаемый ответ { #the-resulting-response } @@ -77,7 +77,7 @@ Но в случае, если это необходимо для продвинутого сценария, можно добавить пользовательские заголовки: -{* ../../docs_src/handling_errors/tutorial002.py hl[14] *} +{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *} ## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers } @@ -89,7 +89,7 @@ Можно добавить собственный обработчик исключений с помощью `@app.exception_handler()`: -{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *} +{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *} Здесь, если запросить `/unicorns/yolo`, то *операция пути* вызовет `UnicornException`. @@ -127,7 +127,7 @@ Обработчик исключения получит объект `Request` и исключение. -{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *} +{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *} Теперь, если перейти к `/items/foo`, то вместо стандартной JSON-ошибки с: @@ -159,7 +159,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa Например, для этих ошибок можно вернуть обычный текстовый ответ вместо JSON: -{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *} +{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *} /// note | Технические детали @@ -183,7 +183,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa Вы можете использовать его при разработке приложения для регистрации тела и его отладки, возврата пользователю и т.д. -{* ../../docs_src/handling_errors/tutorial005.py hl[14] *} +{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *} Теперь попробуйте отправить недействительный элемент, например: @@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException Если вы хотите использовать исключение вместе с теми же обработчиками исключений по умолчанию из **FastAPI**, вы можете импортировать и повторно использовать обработчики исключений по умолчанию из `fastapi.exception_handlers`: -{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *} +{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *} В этом примере вы просто `выводите в терминал` ошибку с очень выразительным сообщением, но идея вам понятна. Вы можете использовать исключение, а затем просто повторно использовать стандартные обработчики исключений. diff --git a/docs/ru/docs/tutorial/metadata.md b/docs/ru/docs/tutorial/metadata.md index 2e359752e1..e4fe5fb544 100644 --- a/docs/ru/docs/tutorial/metadata.md +++ b/docs/ru/docs/tutorial/metadata.md @@ -18,7 +18,7 @@ Вы можете задать их следующим образом: -{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *} +{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *} /// tip | Подсказка @@ -36,7 +36,7 @@ К примеру: -{* ../../docs_src/metadata/tutorial001_1.py hl[31] *} +{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *} ## Метаданные для тегов { #metadata-for-tags } @@ -58,7 +58,7 @@ Создайте метаданные для ваших тегов и передайте их в параметре `openapi_tags`: -{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *} +{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *} Помните, что вы можете использовать Markdown внутри описания, к примеру "login" будет отображен жирным шрифтом (**login**) и "fancy" будет отображаться курсивом (_fancy_). @@ -72,7 +72,7 @@ Используйте параметр `tags` с вашими *операциями пути* (и `APIRouter`ами), чтобы присвоить им различные теги: -{* ../../docs_src/metadata/tutorial004.py hl[21,26] *} +{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *} /// info | Дополнительная информация @@ -100,7 +100,7 @@ К примеру, чтобы задать её отображение по адресу `/api/v1/openapi.json`: -{* ../../docs_src/metadata/tutorial002.py hl[3] *} +{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *} Если вы хотите отключить схему OpenAPI полностью, вы можете задать `openapi_url=None`, это также отключит пользовательские интерфейсы документации, которые её используют. @@ -117,4 +117,4 @@ К примеру, чтобы задать отображение Swagger UI по адресу `/documentation` и отключить ReDoc: -{* ../../docs_src/metadata/tutorial003.py hl[3] *} +{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *} diff --git a/docs/ru/docs/tutorial/middleware.md b/docs/ru/docs/tutorial/middleware.md index 5803b398b9..a83d3c0111 100644 --- a/docs/ru/docs/tutorial/middleware.md +++ b/docs/ru/docs/tutorial/middleware.md @@ -33,7 +33,7 @@ * Затем она возвращает ответ `response`, сгенерированный *операцией пути*. * Также имеется возможность видоизменить `response`, перед тем как его вернуть. -{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *} +{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *} /// tip | Примечание @@ -59,7 +59,7 @@ Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа: -{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *} +{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *} /// tip | Примечание diff --git a/docs/ru/docs/tutorial/path-operation-configuration.md b/docs/ru/docs/tutorial/path-operation-configuration.md index 63b48a3941..96a54ffea0 100644 --- a/docs/ru/docs/tutorial/path-operation-configuration.md +++ b/docs/ru/docs/tutorial/path-operation-configuration.md @@ -46,7 +46,7 @@ **FastAPI** поддерживает это так же, как и в случае с обычными строками: -{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *} +{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *} ## Краткое и развёрнутое содержание { #summary-and-description } @@ -92,7 +92,7 @@ OpenAPI указывает, что каждой *операции пути* не Если вам необходимо пометить *операцию пути* как устаревшую, при этом не удаляя её, передайте параметр `deprecated`: -{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *} +{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *} Он будет четко помечен как устаревший в интерактивной документации: diff --git a/docs/ru/docs/tutorial/path-params-numeric-validations.md b/docs/ru/docs/tutorial/path-params-numeric-validations.md index ccea1945e4..f0fe788051 100644 --- a/docs/ru/docs/tutorial/path-params-numeric-validations.md +++ b/docs/ru/docs/tutorial/path-params-numeric-validations.md @@ -54,7 +54,7 @@ Path-параметр всегда является обязательным, п Поэтому вы можете определить функцию так: -{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *} Но имейте в виду, что если вы используете `Annotated`, вы не столкнётесь с этой проблемой, так как вы не используете значения по умолчанию параметров функции для `Query()` или `Path()`. @@ -83,7 +83,7 @@ Path-параметр всегда является обязательным, п Python не будет ничего делать с `*`, но он будет знать, что все следующие параметры являются именованными аргументами (парами ключ-значение), также известными как kwargs, даже если у них нет значений по умолчанию. -{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *} +{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *} ### Лучше с `Annotated` { #better-with-annotated } diff --git a/docs/ru/docs/tutorial/path-params.md b/docs/ru/docs/tutorial/path-params.md index f7d138afbe..83a7ed3ffe 100644 --- a/docs/ru/docs/tutorial/path-params.md +++ b/docs/ru/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python: -{* ../../docs_src/path_params/tutorial001.py hl[6:7] *} +{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *} Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`. @@ -16,7 +16,7 @@ Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python: -{* ../../docs_src/path_params/tutorial002.py hl[7] *} +{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *} Здесь, `item_id` объявлен типом `int`. @@ -118,13 +118,13 @@ Поскольку *операции пути* выполняются в порядке их объявления, необходимо, чтобы путь для `/users/me` был объявлен раньше, чем путь для `/users/{user_id}`: -{* ../../docs_src/path_params/tutorial003.py hl[6,11] *} +{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *} Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`. Аналогично, вы не можете переопределить операцию с путем: -{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *} +{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *} Первый будет выполняться всегда, так как путь совпадает первым. @@ -140,13 +140,7 @@ Затем создайте атрибуты класса с фиксированными допустимыми значениями: -{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *} - -/// info | Дополнительная информация - -Перечисления (enum) доступны в Python начиная с версии 3.4. - -/// +{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *} /// tip | Подсказка @@ -158,7 +152,7 @@ Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее: -{* ../../docs_src/path_params/tutorial005.py hl[16] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *} ### Проверьте документацию { #check-the-docs } @@ -174,13 +168,13 @@ Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`: -{* ../../docs_src/path_params/tutorial005.py hl[17] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *} #### Получение *значения перечисления* { #get-the-enumeration-value } Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`: -{* ../../docs_src/path_params/tutorial005.py hl[20] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *} /// tip | Подсказка @@ -194,7 +188,7 @@ Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту: -{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *} +{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *} Вы отправите клиенту такой JSON-ответ: ```JSON @@ -232,7 +226,7 @@ OpenAPI не поддерживает способов объявления *п Можете использовать так: -{* ../../docs_src/path_params/tutorial004.py hl[6] *} +{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *} /// tip | Подсказка diff --git a/docs/ru/docs/tutorial/query-params-str-validations.md b/docs/ru/docs/tutorial/query-params-str-validations.md index 302901d4ec..3a4ecc37dc 100644 --- a/docs/ru/docs/tutorial/query-params-str-validations.md +++ b/docs/ru/docs/tutorial/query-params-str-validations.md @@ -55,7 +55,7 @@ q: str | None = None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python q: Union[str, None] = None @@ -73,7 +73,7 @@ q: Annotated[str | None] = None //// -//// tab | Python 3.8+ +//// tab | Python 3.9+ ```Python q: Annotated[Union[str, None]] = None diff --git a/docs/ru/docs/tutorial/query-params.md b/docs/ru/docs/tutorial/query-params.md index 5a84f9768c..be1c0e46e1 100644 --- a/docs/ru/docs/tutorial/query-params.md +++ b/docs/ru/docs/tutorial/query-params.md @@ -2,7 +2,7 @@ Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры. -{* ../../docs_src/query_params/tutorial001.py hl[9] *} +{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *} Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`. @@ -127,7 +127,7 @@ http://127.0.0.1:8000/items/foo?short=yes Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию: -{* ../../docs_src/query_params/tutorial005.py hl[6:7] *} +{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *} Здесь параметр запроса `needy` является обязательным параметром с типом данных `str`. diff --git a/docs/ru/docs/tutorial/response-model.md b/docs/ru/docs/tutorial/response-model.md index c045f9ed78..07308c1db2 100644 --- a/docs/ru/docs/tutorial/response-model.md +++ b/docs/ru/docs/tutorial/response-model.md @@ -183,7 +183,7 @@ FastAPI делает несколько вещей внутри вместе с Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}. -{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *} +{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *} Этот простой случай обрабатывается FastAPI автоматически, потому что аннотация возвращаемого типа — это класс (или подкласс) `Response`. @@ -193,7 +193,7 @@ FastAPI делает несколько вещей внутри вместе с Вы также можете использовать подкласс `Response` в аннотации типа: -{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *} +{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *} Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот случай. diff --git a/docs/ru/docs/tutorial/response-status-code.md b/docs/ru/docs/tutorial/response-status-code.md index f5b1ff6ad7..30f642b643 100644 --- a/docs/ru/docs/tutorial/response-status-code.md +++ b/docs/ru/docs/tutorial/response-status-code.md @@ -8,7 +8,7 @@ * `@app.delete()` * и других. -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} /// note | Примечание @@ -74,7 +74,7 @@ FastAPI знает об этом и создаст документацию Open Рассмотрим предыдущий пример еще раз: -{* ../../docs_src/response_status_code/tutorial001.py hl[6] *} +{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *} `201` – это код статуса "Создано". @@ -82,7 +82,7 @@ FastAPI знает об этом и создаст документацию Open Для удобства вы можете использовать переменные из `fastapi.status`. -{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *} +{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *} Они содержат те же числовые значения, но позволяют использовать автозавершение редактора кода для выбора кода статуса: diff --git a/docs/ru/docs/tutorial/static-files.md b/docs/ru/docs/tutorial/static-files.md index 8455aea0a2..f40cfe9b04 100644 --- a/docs/ru/docs/tutorial/static-files.md +++ b/docs/ru/docs/tutorial/static-files.md @@ -7,7 +7,7 @@ * Импортируйте `StaticFiles`. * "Примонтируйте" экземпляр `StaticFiles()` к определённому пути. -{* ../../docs_src/static_files/tutorial001.py hl[2,6] *} +{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *} /// note | Технические детали diff --git a/docs/ru/docs/tutorial/testing.md b/docs/ru/docs/tutorial/testing.md index 7354ed895f..ab58429c51 100644 --- a/docs/ru/docs/tutorial/testing.md +++ b/docs/ru/docs/tutorial/testing.md @@ -30,7 +30,7 @@ $ pip install httpx Напишите простое утверждение с `assert` дабы проверить истинность Python-выражения (это тоже стандарт `pytest`). -{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *} +{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *} /// tip | Подсказка @@ -76,7 +76,7 @@ $ pip install httpx В файле `main.py` находится Ваше приложение **FastAPI**: -{* ../../docs_src/app_testing/main.py *} +{* ../../docs_src/app_testing/app_a_py39/main.py *} ### Файл тестов { #testing-file } @@ -92,7 +92,7 @@ $ pip install httpx Так как оба файла находятся в одной директории, для импорта объекта приложения из файла `main` в файл `test_main` Вы можете использовать относительный импорт: -{* ../../docs_src/app_testing/test_main.py hl[3] *} +{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *} ...и писать дальше тесты, как и раньше. diff --git a/docs_src/additional_responses/tutorial001.py b/docs_src/additional_responses/tutorial001_py39.py similarity index 100% rename from docs_src/additional_responses/tutorial001.py rename to docs_src/additional_responses/tutorial001_py39.py diff --git a/docs_src/additional_responses/tutorial002.py b/docs_src/additional_responses/tutorial002_py39.py similarity index 100% rename from docs_src/additional_responses/tutorial002.py rename to docs_src/additional_responses/tutorial002_py39.py diff --git a/docs_src/additional_responses/tutorial003.py b/docs_src/additional_responses/tutorial003_py39.py similarity index 100% rename from docs_src/additional_responses/tutorial003.py rename to docs_src/additional_responses/tutorial003_py39.py diff --git a/docs_src/additional_responses/tutorial004.py b/docs_src/additional_responses/tutorial004_py39.py similarity index 100% rename from docs_src/additional_responses/tutorial004.py rename to docs_src/additional_responses/tutorial004_py39.py diff --git a/docs_src/additional_status_codes/tutorial001_an.py b/docs_src/additional_status_codes/tutorial001_an.py deleted file mode 100644 index b5ad6a16b6..0000000000 --- a/docs_src/additional_status_codes/tutorial001_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI, status -from fastapi.responses import JSONResponse -from typing_extensions import Annotated - -app = FastAPI() - -items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}} - - -@app.put("/items/{item_id}") -async def upsert_item( - item_id: str, - name: Annotated[Union[str, None], Body()] = None, - size: Annotated[Union[int, None], Body()] = None, -): - if item_id in items: - item = items[item_id] - item["name"] = name - item["size"] = size - return item - else: - item = {"name": name, "size": size} - items[item_id] = item - return JSONResponse(status_code=status.HTTP_201_CREATED, content=item) diff --git a/docs_src/additional_status_codes/tutorial001.py b/docs_src/additional_status_codes/tutorial001_py39.py similarity index 100% rename from docs_src/additional_status_codes/tutorial001.py rename to docs_src/additional_status_codes/tutorial001_py39.py diff --git a/docs_src/advanced_middleware/tutorial001.py b/docs_src/advanced_middleware/tutorial001_py39.py similarity index 100% rename from docs_src/advanced_middleware/tutorial001.py rename to docs_src/advanced_middleware/tutorial001_py39.py diff --git a/docs_src/advanced_middleware/tutorial002.py b/docs_src/advanced_middleware/tutorial002_py39.py similarity index 100% rename from docs_src/advanced_middleware/tutorial002.py rename to docs_src/advanced_middleware/tutorial002_py39.py diff --git a/docs_src/advanced_middleware/tutorial003.py b/docs_src/advanced_middleware/tutorial003_py39.py similarity index 100% rename from docs_src/advanced_middleware/tutorial003.py rename to docs_src/advanced_middleware/tutorial003_py39.py diff --git a/docs_src/app_testing/app_b/__init__.py b/docs_src/app_testing/app_a_py39/__init__.py similarity index 100% rename from docs_src/app_testing/app_b/__init__.py rename to docs_src/app_testing/app_a_py39/__init__.py diff --git a/docs_src/app_testing/main.py b/docs_src/app_testing/app_a_py39/main.py similarity index 100% rename from docs_src/app_testing/main.py rename to docs_src/app_testing/app_a_py39/main.py diff --git a/docs_src/app_testing/test_main.py b/docs_src/app_testing/app_a_py39/test_main.py similarity index 100% rename from docs_src/app_testing/test_main.py rename to docs_src/app_testing/app_a_py39/test_main.py diff --git a/docs_src/app_testing/app_b_an/main.py b/docs_src/app_testing/app_b_an/main.py deleted file mode 100644 index c66278fdd0..0000000000 --- a/docs_src/app_testing/app_b_an/main.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Header, HTTPException -from pydantic import BaseModel -from typing_extensions import Annotated - -fake_secret_token = "coneofsilence" - -fake_db = { - "foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"}, - "bar": {"id": "bar", "title": "Bar", "description": "The bartenders"}, -} - -app = FastAPI() - - -class Item(BaseModel): - id: str - title: str - description: Union[str, None] = None - - -@app.get("/items/{item_id}", response_model=Item) -async def read_main(item_id: str, x_token: Annotated[str, Header()]): - if x_token != fake_secret_token: - raise HTTPException(status_code=400, detail="Invalid X-Token header") - if item_id not in fake_db: - raise HTTPException(status_code=404, detail="Item not found") - return fake_db[item_id] - - -@app.post("/items/", response_model=Item) -async def create_item(item: Item, x_token: Annotated[str, Header()]): - if x_token != fake_secret_token: - raise HTTPException(status_code=400, detail="Invalid X-Token header") - if item.id in fake_db: - raise HTTPException(status_code=409, detail="Item already exists") - fake_db[item.id] = item - return item diff --git a/docs_src/app_testing/app_b_an/test_main.py b/docs_src/app_testing/app_b_an/test_main.py deleted file mode 100644 index 4e1c51ecc8..0000000000 --- a/docs_src/app_testing/app_b_an/test_main.py +++ /dev/null @@ -1,65 +0,0 @@ -from fastapi.testclient import TestClient - -from .main import app - -client = TestClient(app) - - -def test_read_item(): - response = client.get("/items/foo", headers={"X-Token": "coneofsilence"}) - assert response.status_code == 200 - assert response.json() == { - "id": "foo", - "title": "Foo", - "description": "There goes my hero", - } - - -def test_read_item_bad_token(): - response = client.get("/items/foo", headers={"X-Token": "hailhydra"}) - assert response.status_code == 400 - assert response.json() == {"detail": "Invalid X-Token header"} - - -def test_read_nonexistent_item(): - response = client.get("/items/baz", headers={"X-Token": "coneofsilence"}) - assert response.status_code == 404 - assert response.json() == {"detail": "Item not found"} - - -def test_create_item(): - response = client.post( - "/items/", - headers={"X-Token": "coneofsilence"}, - json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"}, - ) - assert response.status_code == 200 - assert response.json() == { - "id": "foobar", - "title": "Foo Bar", - "description": "The Foo Barters", - } - - -def test_create_item_bad_token(): - response = client.post( - "/items/", - headers={"X-Token": "hailhydra"}, - json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"}, - ) - assert response.status_code == 400 - assert response.json() == {"detail": "Invalid X-Token header"} - - -def test_create_existing_item(): - response = client.post( - "/items/", - headers={"X-Token": "coneofsilence"}, - json={ - "id": "foo", - "title": "The Foo ID Stealers", - "description": "There goes my stealer", - }, - ) - assert response.status_code == 409 - assert response.json() == {"detail": "Item already exists"} diff --git a/docs_src/app_testing/app_b_an/__init__.py b/docs_src/app_testing/app_b_py39/__init__.py similarity index 100% rename from docs_src/app_testing/app_b_an/__init__.py rename to docs_src/app_testing/app_b_py39/__init__.py diff --git a/docs_src/app_testing/app_b/main.py b/docs_src/app_testing/app_b_py39/main.py similarity index 100% rename from docs_src/app_testing/app_b/main.py rename to docs_src/app_testing/app_b_py39/main.py diff --git a/docs_src/app_testing/app_b/test_main.py b/docs_src/app_testing/app_b_py39/test_main.py similarity index 100% rename from docs_src/app_testing/app_b/test_main.py rename to docs_src/app_testing/app_b_py39/test_main.py diff --git a/docs_src/app_testing/tutorial001.py b/docs_src/app_testing/tutorial001_py39.py similarity index 100% rename from docs_src/app_testing/tutorial001.py rename to docs_src/app_testing/tutorial001_py39.py diff --git a/docs_src/app_testing/tutorial002.py b/docs_src/app_testing/tutorial002_py39.py similarity index 100% rename from docs_src/app_testing/tutorial002.py rename to docs_src/app_testing/tutorial002_py39.py diff --git a/docs_src/app_testing/tutorial003.py b/docs_src/app_testing/tutorial003_py39.py similarity index 100% rename from docs_src/app_testing/tutorial003.py rename to docs_src/app_testing/tutorial003_py39.py diff --git a/docs_src/app_testing/tutorial004.py b/docs_src/app_testing/tutorial004_py39.py similarity index 100% rename from docs_src/app_testing/tutorial004.py rename to docs_src/app_testing/tutorial004_py39.py diff --git a/docs_src/bigger_applications/app/__init__.py b/docs_src/async_tests/app_a_py39/__init__.py similarity index 100% rename from docs_src/bigger_applications/app/__init__.py rename to docs_src/async_tests/app_a_py39/__init__.py diff --git a/docs_src/async_tests/main.py b/docs_src/async_tests/app_a_py39/main.py similarity index 100% rename from docs_src/async_tests/main.py rename to docs_src/async_tests/app_a_py39/main.py diff --git a/docs_src/async_tests/test_main.py b/docs_src/async_tests/app_a_py39/test_main.py similarity index 100% rename from docs_src/async_tests/test_main.py rename to docs_src/async_tests/app_a_py39/test_main.py diff --git a/docs_src/authentication_error_status_code/tutorial001_an.py b/docs_src/authentication_error_status_code/tutorial001_an.py deleted file mode 100644 index 40678e858d..0000000000 --- a/docs_src/authentication_error_status_code/tutorial001_an.py +++ /dev/null @@ -1,20 +0,0 @@ -from fastapi import Depends, FastAPI, HTTPException, status -from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer -from typing_extensions import Annotated - -app = FastAPI() - - -class HTTPBearer403(HTTPBearer): - def make_not_authenticated_error(self) -> HTTPException: - return HTTPException( - status_code=status.HTTP_403_FORBIDDEN, detail="Not authenticated" - ) - - -CredentialsDep = Annotated[HTTPAuthorizationCredentials, Depends(HTTPBearer403())] - - -@app.get("/me") -def read_me(credentials: CredentialsDep): - return {"message": "You are authenticated", "token": credentials.credentials} diff --git a/docs_src/background_tasks/tutorial001.py b/docs_src/background_tasks/tutorial001_py39.py similarity index 100% rename from docs_src/background_tasks/tutorial001.py rename to docs_src/background_tasks/tutorial001_py39.py diff --git a/docs_src/background_tasks/tutorial002_an.py b/docs_src/background_tasks/tutorial002_an.py deleted file mode 100644 index f63502b09a..0000000000 --- a/docs_src/background_tasks/tutorial002_an.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Union - -from fastapi import BackgroundTasks, Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -def write_log(message: str): - with open("log.txt", mode="a") as log: - log.write(message) - - -def get_query(background_tasks: BackgroundTasks, q: Union[str, None] = None): - if q: - message = f"found query: {q}\n" - background_tasks.add_task(write_log, message) - return q - - -@app.post("/send-notification/{email}") -async def send_notification( - email: str, background_tasks: BackgroundTasks, q: Annotated[str, Depends(get_query)] -): - message = f"message to {email}\n" - background_tasks.add_task(write_log, message) - return {"message": "Message sent"} diff --git a/docs_src/background_tasks/tutorial002.py b/docs_src/background_tasks/tutorial002_py39.py similarity index 100% rename from docs_src/background_tasks/tutorial002.py rename to docs_src/background_tasks/tutorial002_py39.py diff --git a/docs_src/behind_a_proxy/tutorial001_01.py b/docs_src/behind_a_proxy/tutorial001_01_py39.py similarity index 100% rename from docs_src/behind_a_proxy/tutorial001_01.py rename to docs_src/behind_a_proxy/tutorial001_01_py39.py diff --git a/docs_src/behind_a_proxy/tutorial001.py b/docs_src/behind_a_proxy/tutorial001_py39.py similarity index 100% rename from docs_src/behind_a_proxy/tutorial001.py rename to docs_src/behind_a_proxy/tutorial001_py39.py diff --git a/docs_src/behind_a_proxy/tutorial002.py b/docs_src/behind_a_proxy/tutorial002_py39.py similarity index 100% rename from docs_src/behind_a_proxy/tutorial002.py rename to docs_src/behind_a_proxy/tutorial002_py39.py diff --git a/docs_src/behind_a_proxy/tutorial003.py b/docs_src/behind_a_proxy/tutorial003_py39.py similarity index 100% rename from docs_src/behind_a_proxy/tutorial003.py rename to docs_src/behind_a_proxy/tutorial003_py39.py diff --git a/docs_src/behind_a_proxy/tutorial004.py b/docs_src/behind_a_proxy/tutorial004_py39.py similarity index 100% rename from docs_src/behind_a_proxy/tutorial004.py rename to docs_src/behind_a_proxy/tutorial004_py39.py diff --git a/docs_src/bigger_applications/app_an/dependencies.py b/docs_src/bigger_applications/app_an/dependencies.py deleted file mode 100644 index 1374c54b31..0000000000 --- a/docs_src/bigger_applications/app_an/dependencies.py +++ /dev/null @@ -1,12 +0,0 @@ -from fastapi import Header, HTTPException -from typing_extensions import Annotated - - -async def get_token_header(x_token: Annotated[str, Header()]): - if x_token != "fake-super-secret-token": - raise HTTPException(status_code=400, detail="X-Token header invalid") - - -async def get_query_token(token: str): - if token != "jessica": - raise HTTPException(status_code=400, detail="No Jessica token provided") diff --git a/docs_src/bigger_applications/app_an/internal/admin.py b/docs_src/bigger_applications/app_an/internal/admin.py deleted file mode 100644 index 99d3da86b9..0000000000 --- a/docs_src/bigger_applications/app_an/internal/admin.py +++ /dev/null @@ -1,8 +0,0 @@ -from fastapi import APIRouter - -router = APIRouter() - - -@router.post("/") -async def update_admin(): - return {"message": "Admin getting schwifty"} diff --git a/docs_src/bigger_applications/app_an/main.py b/docs_src/bigger_applications/app_an/main.py deleted file mode 100644 index ae544a3aac..0000000000 --- a/docs_src/bigger_applications/app_an/main.py +++ /dev/null @@ -1,23 +0,0 @@ -from fastapi import Depends, FastAPI - -from .dependencies import get_query_token, get_token_header -from .internal import admin -from .routers import items, users - -app = FastAPI(dependencies=[Depends(get_query_token)]) - - -app.include_router(users.router) -app.include_router(items.router) -app.include_router( - admin.router, - prefix="/admin", - tags=["admin"], - dependencies=[Depends(get_token_header)], - responses={418: {"description": "I'm a teapot"}}, -) - - -@app.get("/") -async def root(): - return {"message": "Hello Bigger Applications!"} diff --git a/docs_src/bigger_applications/app_an/routers/items.py b/docs_src/bigger_applications/app_an/routers/items.py deleted file mode 100644 index bde9ff4d55..0000000000 --- a/docs_src/bigger_applications/app_an/routers/items.py +++ /dev/null @@ -1,38 +0,0 @@ -from fastapi import APIRouter, Depends, HTTPException - -from ..dependencies import get_token_header - -router = APIRouter( - prefix="/items", - tags=["items"], - dependencies=[Depends(get_token_header)], - responses={404: {"description": "Not found"}}, -) - - -fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}} - - -@router.get("/") -async def read_items(): - return fake_items_db - - -@router.get("/{item_id}") -async def read_item(item_id: str): - if item_id not in fake_items_db: - raise HTTPException(status_code=404, detail="Item not found") - return {"name": fake_items_db[item_id]["name"], "item_id": item_id} - - -@router.put( - "/{item_id}", - tags=["custom"], - responses={403: {"description": "Operation forbidden"}}, -) -async def update_item(item_id: str): - if item_id != "plumbus": - raise HTTPException( - status_code=403, detail="You can only update the item: plumbus" - ) - return {"item_id": item_id, "name": "The great Plumbus"} diff --git a/docs_src/bigger_applications/app_an/routers/users.py b/docs_src/bigger_applications/app_an/routers/users.py deleted file mode 100644 index 39b3d7e7cf..0000000000 --- a/docs_src/bigger_applications/app_an/routers/users.py +++ /dev/null @@ -1,18 +0,0 @@ -from fastapi import APIRouter - -router = APIRouter() - - -@router.get("/users/", tags=["users"]) -async def read_users(): - return [{"username": "Rick"}, {"username": "Morty"}] - - -@router.get("/users/me", tags=["users"]) -async def read_user_me(): - return {"username": "fakecurrentuser"} - - -@router.get("/users/{username}", tags=["users"]) -async def read_user(username: str): - return {"username": username} diff --git a/docs_src/bigger_applications/app/internal/__init__.py b/docs_src/bigger_applications/app_py39/__init__.py similarity index 100% rename from docs_src/bigger_applications/app/internal/__init__.py rename to docs_src/bigger_applications/app_py39/__init__.py diff --git a/docs_src/bigger_applications/app/dependencies.py b/docs_src/bigger_applications/app_py39/dependencies.py similarity index 100% rename from docs_src/bigger_applications/app/dependencies.py rename to docs_src/bigger_applications/app_py39/dependencies.py diff --git a/docs_src/bigger_applications/app/routers/__init__.py b/docs_src/bigger_applications/app_py39/internal/__init__.py similarity index 100% rename from docs_src/bigger_applications/app/routers/__init__.py rename to docs_src/bigger_applications/app_py39/internal/__init__.py diff --git a/docs_src/bigger_applications/app/internal/admin.py b/docs_src/bigger_applications/app_py39/internal/admin.py similarity index 100% rename from docs_src/bigger_applications/app/internal/admin.py rename to docs_src/bigger_applications/app_py39/internal/admin.py diff --git a/docs_src/bigger_applications/app/main.py b/docs_src/bigger_applications/app_py39/main.py similarity index 100% rename from docs_src/bigger_applications/app/main.py rename to docs_src/bigger_applications/app_py39/main.py diff --git a/docs_src/bigger_applications/app_an/__init__.py b/docs_src/bigger_applications/app_py39/routers/__init__.py similarity index 100% rename from docs_src/bigger_applications/app_an/__init__.py rename to docs_src/bigger_applications/app_py39/routers/__init__.py diff --git a/docs_src/bigger_applications/app/routers/items.py b/docs_src/bigger_applications/app_py39/routers/items.py similarity index 100% rename from docs_src/bigger_applications/app/routers/items.py rename to docs_src/bigger_applications/app_py39/routers/items.py diff --git a/docs_src/bigger_applications/app/routers/users.py b/docs_src/bigger_applications/app_py39/routers/users.py similarity index 100% rename from docs_src/bigger_applications/app/routers/users.py rename to docs_src/bigger_applications/app_py39/routers/users.py diff --git a/docs_src/body/tutorial001.py b/docs_src/body/tutorial001_py39.py similarity index 100% rename from docs_src/body/tutorial001.py rename to docs_src/body/tutorial001_py39.py diff --git a/docs_src/body/tutorial002.py b/docs_src/body/tutorial002_py39.py similarity index 100% rename from docs_src/body/tutorial002.py rename to docs_src/body/tutorial002_py39.py diff --git a/docs_src/body/tutorial003.py b/docs_src/body/tutorial003_py39.py similarity index 100% rename from docs_src/body/tutorial003.py rename to docs_src/body/tutorial003_py39.py diff --git a/docs_src/body/tutorial004.py b/docs_src/body/tutorial004_py39.py similarity index 100% rename from docs_src/body/tutorial004.py rename to docs_src/body/tutorial004_py39.py diff --git a/docs_src/body_fields/tutorial001_an.py b/docs_src/body_fields/tutorial001_an.py deleted file mode 100644 index 15ea1b53dc..0000000000 --- a/docs_src/body_fields/tutorial001_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel, Field -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = Field( - default=None, title="The description of the item", max_length=300 - ) - price: float = Field(gt=0, description="The price must be greater than zero") - tax: Union[float, None] = None - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_fields/tutorial001.py b/docs_src/body_fields/tutorial001_py39.py similarity index 100% rename from docs_src/body_fields/tutorial001.py rename to docs_src/body_fields/tutorial001_py39.py diff --git a/docs_src/body_multiple_params/tutorial001_an.py b/docs_src/body_multiple_params/tutorial001_an.py deleted file mode 100644 index 308eee8544..0000000000 --- a/docs_src/body_multiple_params/tutorial001_an.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Path -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -@app.put("/items/{item_id}") -async def update_item( - item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)], - q: Union[str, None] = None, - item: Union[Item, None] = None, -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - if item: - results.update({"item": item}) - return results diff --git a/docs_src/body_multiple_params/tutorial001.py b/docs_src/body_multiple_params/tutorial001_py39.py similarity index 100% rename from docs_src/body_multiple_params/tutorial001.py rename to docs_src/body_multiple_params/tutorial001_py39.py diff --git a/docs_src/body_multiple_params/tutorial002.py b/docs_src/body_multiple_params/tutorial002_py39.py similarity index 100% rename from docs_src/body_multiple_params/tutorial002.py rename to docs_src/body_multiple_params/tutorial002_py39.py diff --git a/docs_src/body_multiple_params/tutorial003_an.py b/docs_src/body_multiple_params/tutorial003_an.py deleted file mode 100644 index 39ef7340a5..0000000000 --- a/docs_src/body_multiple_params/tutorial003_an.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -class User(BaseModel): - username: str - full_name: Union[str, None] = None - - -@app.put("/items/{item_id}") -async def update_item( - item_id: int, item: Item, user: User, importance: Annotated[int, Body()] -): - results = {"item_id": item_id, "item": item, "user": user, "importance": importance} - return results diff --git a/docs_src/body_multiple_params/tutorial003.py b/docs_src/body_multiple_params/tutorial003_py39.py similarity index 100% rename from docs_src/body_multiple_params/tutorial003.py rename to docs_src/body_multiple_params/tutorial003_py39.py diff --git a/docs_src/body_multiple_params/tutorial004_an.py b/docs_src/body_multiple_params/tutorial004_an.py deleted file mode 100644 index f6830f3920..0000000000 --- a/docs_src/body_multiple_params/tutorial004_an.py +++ /dev/null @@ -1,34 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -class User(BaseModel): - username: str - full_name: Union[str, None] = None - - -@app.put("/items/{item_id}") -async def update_item( - *, - item_id: int, - item: Item, - user: User, - importance: Annotated[int, Body(gt=0)], - q: Union[str, None] = None, -): - results = {"item_id": item_id, "item": item, "user": user, "importance": importance} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/body_multiple_params/tutorial004.py b/docs_src/body_multiple_params/tutorial004_py39.py similarity index 100% rename from docs_src/body_multiple_params/tutorial004.py rename to docs_src/body_multiple_params/tutorial004_py39.py diff --git a/docs_src/body_multiple_params/tutorial005_an.py b/docs_src/body_multiple_params/tutorial005_an.py deleted file mode 100644 index dadde80b55..0000000000 --- a/docs_src/body_multiple_params/tutorial005_an.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_multiple_params/tutorial005.py b/docs_src/body_multiple_params/tutorial005_py39.py similarity index 100% rename from docs_src/body_multiple_params/tutorial005.py rename to docs_src/body_multiple_params/tutorial005_py39.py diff --git a/docs_src/body_nested_models/tutorial001.py b/docs_src/body_nested_models/tutorial001_py39.py similarity index 100% rename from docs_src/body_nested_models/tutorial001.py rename to docs_src/body_nested_models/tutorial001_py39.py diff --git a/docs_src/body_nested_models/tutorial002.py b/docs_src/body_nested_models/tutorial002.py deleted file mode 100644 index 155cff7885..0000000000 --- a/docs_src/body_nested_models/tutorial002.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: List[str] = [] - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Item): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_nested_models/tutorial003.py b/docs_src/body_nested_models/tutorial003.py deleted file mode 100644 index 84ed18bf48..0000000000 --- a/docs_src/body_nested_models/tutorial003.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Item): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_nested_models/tutorial004.py b/docs_src/body_nested_models/tutorial004.py deleted file mode 100644 index a07bfacac1..0000000000 --- a/docs_src/body_nested_models/tutorial004.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Image(BaseModel): - url: str - name: str - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - image: Union[Image, None] = None - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Item): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_nested_models/tutorial005.py b/docs_src/body_nested_models/tutorial005.py deleted file mode 100644 index 5a01264eda..0000000000 --- a/docs_src/body_nested_models/tutorial005.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel, HttpUrl - -app = FastAPI() - - -class Image(BaseModel): - url: HttpUrl - name: str - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - image: Union[Image, None] = None - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Item): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_nested_models/tutorial006.py b/docs_src/body_nested_models/tutorial006.py deleted file mode 100644 index 75f1f30e33..0000000000 --- a/docs_src/body_nested_models/tutorial006.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import List, Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel, HttpUrl - -app = FastAPI() - - -class Image(BaseModel): - url: HttpUrl - name: str - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - images: Union[List[Image], None] = None - - -@app.put("/items/{item_id}") -async def update_item(item_id: int, item: Item): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/body_nested_models/tutorial007.py b/docs_src/body_nested_models/tutorial007.py deleted file mode 100644 index 641f09dced..0000000000 --- a/docs_src/body_nested_models/tutorial007.py +++ /dev/null @@ -1,32 +0,0 @@ -from typing import List, Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel, HttpUrl - -app = FastAPI() - - -class Image(BaseModel): - url: HttpUrl - name: str - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - images: Union[List[Image], None] = None - - -class Offer(BaseModel): - name: str - description: Union[str, None] = None - price: float - items: List[Item] - - -@app.post("/offers/") -async def create_offer(offer: Offer): - return offer diff --git a/docs_src/body_nested_models/tutorial008.py b/docs_src/body_nested_models/tutorial008.py deleted file mode 100644 index 3431cc6365..0000000000 --- a/docs_src/body_nested_models/tutorial008.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import List - -from fastapi import FastAPI -from pydantic import BaseModel, HttpUrl - -app = FastAPI() - - -class Image(BaseModel): - url: HttpUrl - name: str - - -@app.post("/images/multiple/") -async def create_multiple_images(images: List[Image]): - return images diff --git a/docs_src/body_nested_models/tutorial009.py b/docs_src/body_nested_models/tutorial009.py deleted file mode 100644 index 41dce946ec..0000000000 --- a/docs_src/body_nested_models/tutorial009.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import Dict - -from fastapi import FastAPI - -app = FastAPI() - - -@app.post("/index-weights/") -async def create_index_weights(weights: Dict[int, float]): - return weights diff --git a/docs_src/body_updates/tutorial001.py b/docs_src/body_updates/tutorial001.py deleted file mode 100644 index 4e65d77e26..0000000000 --- a/docs_src/body_updates/tutorial001.py +++ /dev/null @@ -1,34 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from fastapi.encoders import jsonable_encoder -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: Union[str, None] = None - description: Union[str, None] = None - price: Union[float, None] = None - tax: float = 10.5 - tags: List[str] = [] - - -items = { - "foo": {"name": "Foo", "price": 50.2}, - "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, - "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, -} - - -@app.get("/items/{item_id}", response_model=Item) -async def read_item(item_id: str): - return items[item_id] - - -@app.put("/items/{item_id}", response_model=Item) -async def update_item(item_id: str, item: Item): - update_item_encoded = jsonable_encoder(item) - items[item_id] = update_item_encoded - return update_item_encoded diff --git a/docs_src/body_updates/tutorial002.py b/docs_src/body_updates/tutorial002.py deleted file mode 100644 index c3a0fe79ea..0000000000 --- a/docs_src/body_updates/tutorial002.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from fastapi.encoders import jsonable_encoder -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: Union[str, None] = None - description: Union[str, None] = None - price: Union[float, None] = None - tax: float = 10.5 - tags: List[str] = [] - - -items = { - "foo": {"name": "Foo", "price": 50.2}, - "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, - "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, -} - - -@app.get("/items/{item_id}", response_model=Item) -async def read_item(item_id: str): - return items[item_id] - - -@app.patch("/items/{item_id}", response_model=Item) -async def update_item(item_id: str, item: Item): - stored_item_data = items[item_id] - stored_item_model = Item(**stored_item_data) - update_data = item.dict(exclude_unset=True) - updated_item = stored_item_model.copy(update=update_data) - items[item_id] = jsonable_encoder(updated_item) - return updated_item diff --git a/docs_src/conditional_openapi/tutorial001.py b/docs_src/conditional_openapi/tutorial001_py39.py similarity index 100% rename from docs_src/conditional_openapi/tutorial001.py rename to docs_src/conditional_openapi/tutorial001_py39.py diff --git a/docs_src/configure_swagger_ui/tutorial001.py b/docs_src/configure_swagger_ui/tutorial001_py39.py similarity index 100% rename from docs_src/configure_swagger_ui/tutorial001.py rename to docs_src/configure_swagger_ui/tutorial001_py39.py diff --git a/docs_src/configure_swagger_ui/tutorial002.py b/docs_src/configure_swagger_ui/tutorial002_py39.py similarity index 100% rename from docs_src/configure_swagger_ui/tutorial002.py rename to docs_src/configure_swagger_ui/tutorial002_py39.py diff --git a/docs_src/configure_swagger_ui/tutorial003.py b/docs_src/configure_swagger_ui/tutorial003_py39.py similarity index 100% rename from docs_src/configure_swagger_ui/tutorial003.py rename to docs_src/configure_swagger_ui/tutorial003_py39.py diff --git a/docs_src/cookie_param_models/tutorial001_an.py b/docs_src/cookie_param_models/tutorial001_an.py deleted file mode 100644 index e5839ffd54..0000000000 --- a/docs_src/cookie_param_models/tutorial001_an.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Union - -from fastapi import Cookie, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Cookies(BaseModel): - session_id: str - fatebook_tracker: Union[str, None] = None - googall_tracker: Union[str, None] = None - - -@app.get("/items/") -async def read_items(cookies: Annotated[Cookies, Cookie()]): - return cookies diff --git a/docs_src/cookie_param_models/tutorial001.py b/docs_src/cookie_param_models/tutorial001_py39.py similarity index 100% rename from docs_src/cookie_param_models/tutorial001.py rename to docs_src/cookie_param_models/tutorial001_py39.py diff --git a/docs_src/cookie_param_models/tutorial002_an.py b/docs_src/cookie_param_models/tutorial002_an.py deleted file mode 100644 index ce5644b7bd..0000000000 --- a/docs_src/cookie_param_models/tutorial002_an.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Union - -from fastapi import Cookie, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Cookies(BaseModel): - model_config = {"extra": "forbid"} - - session_id: str - fatebook_tracker: Union[str, None] = None - googall_tracker: Union[str, None] = None - - -@app.get("/items/") -async def read_items(cookies: Annotated[Cookies, Cookie()]): - return cookies diff --git a/docs_src/cookie_param_models/tutorial002_pv1_an.py b/docs_src/cookie_param_models/tutorial002_pv1_an.py deleted file mode 100644 index ddfda9b6f5..0000000000 --- a/docs_src/cookie_param_models/tutorial002_pv1_an.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import Union - -from fastapi import Cookie, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Cookies(BaseModel): - class Config: - extra = "forbid" - - session_id: str - fatebook_tracker: Union[str, None] = None - googall_tracker: Union[str, None] = None - - -@app.get("/items/") -async def read_items(cookies: Annotated[Cookies, Cookie()]): - return cookies diff --git a/docs_src/cookie_param_models/tutorial002_pv1.py b/docs_src/cookie_param_models/tutorial002_pv1_py39.py similarity index 100% rename from docs_src/cookie_param_models/tutorial002_pv1.py rename to docs_src/cookie_param_models/tutorial002_pv1_py39.py diff --git a/docs_src/cookie_param_models/tutorial002.py b/docs_src/cookie_param_models/tutorial002_py39.py similarity index 100% rename from docs_src/cookie_param_models/tutorial002.py rename to docs_src/cookie_param_models/tutorial002_py39.py diff --git a/docs_src/cookie_params/tutorial001_an.py b/docs_src/cookie_params/tutorial001_an.py deleted file mode 100644 index 6d5931229c..0000000000 --- a/docs_src/cookie_params/tutorial001_an.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Union - -from fastapi import Cookie, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(ads_id: Annotated[Union[str, None], Cookie()] = None): - return {"ads_id": ads_id} diff --git a/docs_src/cookie_params/tutorial001.py b/docs_src/cookie_params/tutorial001_py39.py similarity index 100% rename from docs_src/cookie_params/tutorial001.py rename to docs_src/cookie_params/tutorial001_py39.py diff --git a/docs_src/cors/tutorial001.py b/docs_src/cors/tutorial001_py39.py similarity index 100% rename from docs_src/cors/tutorial001.py rename to docs_src/cors/tutorial001_py39.py diff --git a/docs_src/custom_docs_ui/tutorial001.py b/docs_src/custom_docs_ui/tutorial001_py39.py similarity index 100% rename from docs_src/custom_docs_ui/tutorial001.py rename to docs_src/custom_docs_ui/tutorial001_py39.py diff --git a/docs_src/custom_docs_ui/tutorial002.py b/docs_src/custom_docs_ui/tutorial002_py39.py similarity index 100% rename from docs_src/custom_docs_ui/tutorial002.py rename to docs_src/custom_docs_ui/tutorial002_py39.py diff --git a/docs_src/custom_request_and_route/tutorial001.py b/docs_src/custom_request_and_route/tutorial001.py deleted file mode 100644 index 268ce9019e..0000000000 --- a/docs_src/custom_request_and_route/tutorial001.py +++ /dev/null @@ -1,35 +0,0 @@ -import gzip -from typing import Callable, List - -from fastapi import Body, FastAPI, Request, Response -from fastapi.routing import APIRoute - - -class GzipRequest(Request): - async def body(self) -> bytes: - if not hasattr(self, "_body"): - body = await super().body() - if "gzip" in self.headers.getlist("Content-Encoding"): - body = gzip.decompress(body) - self._body = body - return self._body - - -class GzipRoute(APIRoute): - def get_route_handler(self) -> Callable: - original_route_handler = super().get_route_handler() - - async def custom_route_handler(request: Request) -> Response: - request = GzipRequest(request.scope, request.receive) - return await original_route_handler(request) - - return custom_route_handler - - -app = FastAPI() -app.router.route_class = GzipRoute - - -@app.post("/sum") -async def sum_numbers(numbers: List[int] = Body()): - return {"sum": sum(numbers)} diff --git a/docs_src/custom_request_and_route/tutorial001_an.py b/docs_src/custom_request_and_route/tutorial001_an.py deleted file mode 100644 index 6224ba8254..0000000000 --- a/docs_src/custom_request_and_route/tutorial001_an.py +++ /dev/null @@ -1,36 +0,0 @@ -import gzip -from typing import Callable, List - -from fastapi import Body, FastAPI, Request, Response -from fastapi.routing import APIRoute -from typing_extensions import Annotated - - -class GzipRequest(Request): - async def body(self) -> bytes: - if not hasattr(self, "_body"): - body = await super().body() - if "gzip" in self.headers.getlist("Content-Encoding"): - body = gzip.decompress(body) - self._body = body - return self._body - - -class GzipRoute(APIRoute): - def get_route_handler(self) -> Callable: - original_route_handler = super().get_route_handler() - - async def custom_route_handler(request: Request) -> Response: - request = GzipRequest(request.scope, request.receive) - return await original_route_handler(request) - - return custom_route_handler - - -app = FastAPI() -app.router.route_class = GzipRoute - - -@app.post("/sum") -async def sum_numbers(numbers: Annotated[List[int], Body()]): - return {"sum": sum(numbers)} diff --git a/docs_src/custom_request_and_route/tutorial002.py b/docs_src/custom_request_and_route/tutorial002.py deleted file mode 100644 index cee4a95f08..0000000000 --- a/docs_src/custom_request_and_route/tutorial002.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Callable, List - -from fastapi import Body, FastAPI, HTTPException, Request, Response -from fastapi.exceptions import RequestValidationError -from fastapi.routing import APIRoute - - -class ValidationErrorLoggingRoute(APIRoute): - def get_route_handler(self) -> Callable: - original_route_handler = super().get_route_handler() - - async def custom_route_handler(request: Request) -> Response: - try: - return await original_route_handler(request) - except RequestValidationError as exc: - body = await request.body() - detail = {"errors": exc.errors(), "body": body.decode()} - raise HTTPException(status_code=422, detail=detail) - - return custom_route_handler - - -app = FastAPI() -app.router.route_class = ValidationErrorLoggingRoute - - -@app.post("/") -async def sum_numbers(numbers: List[int] = Body()): - return sum(numbers) diff --git a/docs_src/custom_request_and_route/tutorial002_an.py b/docs_src/custom_request_and_route/tutorial002_an.py deleted file mode 100644 index 127f7a9ce0..0000000000 --- a/docs_src/custom_request_and_route/tutorial002_an.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Callable, List - -from fastapi import Body, FastAPI, HTTPException, Request, Response -from fastapi.exceptions import RequestValidationError -from fastapi.routing import APIRoute -from typing_extensions import Annotated - - -class ValidationErrorLoggingRoute(APIRoute): - def get_route_handler(self) -> Callable: - original_route_handler = super().get_route_handler() - - async def custom_route_handler(request: Request) -> Response: - try: - return await original_route_handler(request) - except RequestValidationError as exc: - body = await request.body() - detail = {"errors": exc.errors(), "body": body.decode()} - raise HTTPException(status_code=422, detail=detail) - - return custom_route_handler - - -app = FastAPI() -app.router.route_class = ValidationErrorLoggingRoute - - -@app.post("/") -async def sum_numbers(numbers: Annotated[List[int], Body()]): - return sum(numbers) diff --git a/docs_src/custom_request_and_route/tutorial003.py b/docs_src/custom_request_and_route/tutorial003_py39.py similarity index 100% rename from docs_src/custom_request_and_route/tutorial003.py rename to docs_src/custom_request_and_route/tutorial003_py39.py diff --git a/docs_src/custom_response/tutorial001.py b/docs_src/custom_response/tutorial001_py39.py similarity index 100% rename from docs_src/custom_response/tutorial001.py rename to docs_src/custom_response/tutorial001_py39.py diff --git a/docs_src/custom_response/tutorial001b.py b/docs_src/custom_response/tutorial001b_py39.py similarity index 100% rename from docs_src/custom_response/tutorial001b.py rename to docs_src/custom_response/tutorial001b_py39.py diff --git a/docs_src/custom_response/tutorial002.py b/docs_src/custom_response/tutorial002_py39.py similarity index 100% rename from docs_src/custom_response/tutorial002.py rename to docs_src/custom_response/tutorial002_py39.py diff --git a/docs_src/custom_response/tutorial003.py b/docs_src/custom_response/tutorial003_py39.py similarity index 100% rename from docs_src/custom_response/tutorial003.py rename to docs_src/custom_response/tutorial003_py39.py diff --git a/docs_src/custom_response/tutorial004.py b/docs_src/custom_response/tutorial004_py39.py similarity index 100% rename from docs_src/custom_response/tutorial004.py rename to docs_src/custom_response/tutorial004_py39.py diff --git a/docs_src/custom_response/tutorial005.py b/docs_src/custom_response/tutorial005_py39.py similarity index 100% rename from docs_src/custom_response/tutorial005.py rename to docs_src/custom_response/tutorial005_py39.py diff --git a/docs_src/custom_response/tutorial006.py b/docs_src/custom_response/tutorial006_py39.py similarity index 100% rename from docs_src/custom_response/tutorial006.py rename to docs_src/custom_response/tutorial006_py39.py diff --git a/docs_src/custom_response/tutorial006b.py b/docs_src/custom_response/tutorial006b_py39.py similarity index 100% rename from docs_src/custom_response/tutorial006b.py rename to docs_src/custom_response/tutorial006b_py39.py diff --git a/docs_src/custom_response/tutorial006c.py b/docs_src/custom_response/tutorial006c_py39.py similarity index 100% rename from docs_src/custom_response/tutorial006c.py rename to docs_src/custom_response/tutorial006c_py39.py diff --git a/docs_src/custom_response/tutorial007.py b/docs_src/custom_response/tutorial007_py39.py similarity index 100% rename from docs_src/custom_response/tutorial007.py rename to docs_src/custom_response/tutorial007_py39.py diff --git a/docs_src/custom_response/tutorial008.py b/docs_src/custom_response/tutorial008_py39.py similarity index 100% rename from docs_src/custom_response/tutorial008.py rename to docs_src/custom_response/tutorial008_py39.py diff --git a/docs_src/custom_response/tutorial009.py b/docs_src/custom_response/tutorial009_py39.py similarity index 100% rename from docs_src/custom_response/tutorial009.py rename to docs_src/custom_response/tutorial009_py39.py diff --git a/docs_src/custom_response/tutorial009b.py b/docs_src/custom_response/tutorial009b_py39.py similarity index 100% rename from docs_src/custom_response/tutorial009b.py rename to docs_src/custom_response/tutorial009b_py39.py diff --git a/docs_src/custom_response/tutorial009c.py b/docs_src/custom_response/tutorial009c_py39.py similarity index 100% rename from docs_src/custom_response/tutorial009c.py rename to docs_src/custom_response/tutorial009c_py39.py diff --git a/docs_src/custom_response/tutorial010.py b/docs_src/custom_response/tutorial010_py39.py similarity index 100% rename from docs_src/custom_response/tutorial010.py rename to docs_src/custom_response/tutorial010_py39.py diff --git a/docs_src/dataclasses/tutorial001.py b/docs_src/dataclasses/tutorial001_py39.py similarity index 100% rename from docs_src/dataclasses/tutorial001.py rename to docs_src/dataclasses/tutorial001_py39.py diff --git a/docs_src/dataclasses/tutorial002.py b/docs_src/dataclasses/tutorial002.py deleted file mode 100644 index ece2f150cc..0000000000 --- a/docs_src/dataclasses/tutorial002.py +++ /dev/null @@ -1,26 +0,0 @@ -from dataclasses import dataclass, field -from typing import List, Union - -from fastapi import FastAPI - - -@dataclass -class Item: - name: str - price: float - tags: List[str] = field(default_factory=list) - description: Union[str, None] = None - tax: Union[float, None] = None - - -app = FastAPI() - - -@app.get("/items/next", response_model=Item) -async def read_next_item(): - return { - "name": "Island In The Moon", - "price": 12.99, - "description": "A place to be playin' and havin' fun", - "tags": ["breater"], - } diff --git a/docs_src/dataclasses/tutorial003.py b/docs_src/dataclasses/tutorial003.py deleted file mode 100644 index c613155133..0000000000 --- a/docs_src/dataclasses/tutorial003.py +++ /dev/null @@ -1,55 +0,0 @@ -from dataclasses import field # (1) -from typing import List, Union - -from fastapi import FastAPI -from pydantic.dataclasses import dataclass # (2) - - -@dataclass -class Item: - name: str - description: Union[str, None] = None - - -@dataclass -class Author: - name: str - items: List[Item] = field(default_factory=list) # (3) - - -app = FastAPI() - - -@app.post("/authors/{author_id}/items/", response_model=Author) # (4) -async def create_author_items(author_id: str, items: List[Item]): # (5) - return {"name": author_id, "items": items} # (6) - - -@app.get("/authors/", response_model=List[Author]) # (7) -def get_authors(): # (8) - return [ # (9) - { - "name": "Breaters", - "items": [ - { - "name": "Island In The Moon", - "description": "A place to be playin' and havin' fun", - }, - {"name": "Holy Buddies"}, - ], - }, - { - "name": "System of an Up", - "items": [ - { - "name": "Salt", - "description": "The kombucha mushroom people's favorite", - }, - {"name": "Pad Thai"}, - { - "name": "Lonely Night", - "description": "The mostests lonliest nightiest of allest", - }, - ], - }, - ] diff --git a/docs_src/debugging/tutorial001.py b/docs_src/debugging/tutorial001_py39.py similarity index 100% rename from docs_src/debugging/tutorial001.py rename to docs_src/debugging/tutorial001_py39.py diff --git a/docs_src/dependencies/tutorial001_02_an.py b/docs_src/dependencies/tutorial001_02_an.py deleted file mode 100644 index 455d60c822..0000000000 --- a/docs_src/dependencies/tutorial001_02_an.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -async def common_parameters( - q: Union[str, None] = None, skip: int = 0, limit: int = 100 -): - return {"q": q, "skip": skip, "limit": limit} - - -CommonsDep = Annotated[dict, Depends(common_parameters)] - - -@app.get("/items/") -async def read_items(commons: CommonsDep): - return commons - - -@app.get("/users/") -async def read_users(commons: CommonsDep): - return commons diff --git a/docs_src/dependencies/tutorial001_an.py b/docs_src/dependencies/tutorial001_an.py deleted file mode 100644 index 81e24fe86c..0000000000 --- a/docs_src/dependencies/tutorial001_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -async def common_parameters( - q: Union[str, None] = None, skip: int = 0, limit: int = 100 -): - return {"q": q, "skip": skip, "limit": limit} - - -@app.get("/items/") -async def read_items(commons: Annotated[dict, Depends(common_parameters)]): - return commons - - -@app.get("/users/") -async def read_users(commons: Annotated[dict, Depends(common_parameters)]): - return commons diff --git a/docs_src/dependencies/tutorial001.py b/docs_src/dependencies/tutorial001_py39.py similarity index 100% rename from docs_src/dependencies/tutorial001.py rename to docs_src/dependencies/tutorial001_py39.py diff --git a/docs_src/dependencies/tutorial002_an.py b/docs_src/dependencies/tutorial002_an.py deleted file mode 100644 index 964ccf66ca..0000000000 --- a/docs_src/dependencies/tutorial002_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] - - -class CommonQueryParams: - def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100): - self.q = q - self.skip = skip - self.limit = limit - - -@app.get("/items/") -async def read_items(commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]): - response = {} - if commons.q: - response.update({"q": commons.q}) - items = fake_items_db[commons.skip : commons.skip + commons.limit] - response.update({"items": items}) - return response diff --git a/docs_src/dependencies/tutorial002.py b/docs_src/dependencies/tutorial002_py39.py similarity index 100% rename from docs_src/dependencies/tutorial002.py rename to docs_src/dependencies/tutorial002_py39.py diff --git a/docs_src/dependencies/tutorial003_an.py b/docs_src/dependencies/tutorial003_an.py deleted file mode 100644 index ba8e9f7174..0000000000 --- a/docs_src/dependencies/tutorial003_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Any, Union - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] - - -class CommonQueryParams: - def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100): - self.q = q - self.skip = skip - self.limit = limit - - -@app.get("/items/") -async def read_items(commons: Annotated[Any, Depends(CommonQueryParams)]): - response = {} - if commons.q: - response.update({"q": commons.q}) - items = fake_items_db[commons.skip : commons.skip + commons.limit] - response.update({"items": items}) - return response diff --git a/docs_src/dependencies/tutorial003.py b/docs_src/dependencies/tutorial003_py39.py similarity index 100% rename from docs_src/dependencies/tutorial003.py rename to docs_src/dependencies/tutorial003_py39.py diff --git a/docs_src/dependencies/tutorial004_an.py b/docs_src/dependencies/tutorial004_an.py deleted file mode 100644 index 78881a354c..0000000000 --- a/docs_src/dependencies/tutorial004_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] - - -class CommonQueryParams: - def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100): - self.q = q - self.skip = skip - self.limit = limit - - -@app.get("/items/") -async def read_items(commons: Annotated[CommonQueryParams, Depends()]): - response = {} - if commons.q: - response.update({"q": commons.q}) - items = fake_items_db[commons.skip : commons.skip + commons.limit] - response.update({"items": items}) - return response diff --git a/docs_src/dependencies/tutorial004.py b/docs_src/dependencies/tutorial004_py39.py similarity index 100% rename from docs_src/dependencies/tutorial004.py rename to docs_src/dependencies/tutorial004_py39.py diff --git a/docs_src/dependencies/tutorial005_an.py b/docs_src/dependencies/tutorial005_an.py deleted file mode 100644 index 1d78c17a2a..0000000000 --- a/docs_src/dependencies/tutorial005_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Union - -from fastapi import Cookie, Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -def query_extractor(q: Union[str, None] = None): - return q - - -def query_or_cookie_extractor( - q: Annotated[str, Depends(query_extractor)], - last_query: Annotated[Union[str, None], Cookie()] = None, -): - if not q: - return last_query - return q - - -@app.get("/items/") -async def read_query( - query_or_default: Annotated[str, Depends(query_or_cookie_extractor)], -): - return {"q_or_cookie": query_or_default} diff --git a/docs_src/dependencies/tutorial005.py b/docs_src/dependencies/tutorial005_py39.py similarity index 100% rename from docs_src/dependencies/tutorial005.py rename to docs_src/dependencies/tutorial005_py39.py diff --git a/docs_src/dependencies/tutorial006_an.py b/docs_src/dependencies/tutorial006_an.py deleted file mode 100644 index 5aaea04d16..0000000000 --- a/docs_src/dependencies/tutorial006_an.py +++ /dev/null @@ -1,20 +0,0 @@ -from fastapi import Depends, FastAPI, Header, HTTPException -from typing_extensions import Annotated - -app = FastAPI() - - -async def verify_token(x_token: Annotated[str, Header()]): - if x_token != "fake-super-secret-token": - raise HTTPException(status_code=400, detail="X-Token header invalid") - - -async def verify_key(x_key: Annotated[str, Header()]): - if x_key != "fake-super-secret-key": - raise HTTPException(status_code=400, detail="X-Key header invalid") - return x_key - - -@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)]) -async def read_items(): - return [{"item": "Foo"}, {"item": "Bar"}] diff --git a/docs_src/dependencies/tutorial006.py b/docs_src/dependencies/tutorial006_py39.py similarity index 100% rename from docs_src/dependencies/tutorial006.py rename to docs_src/dependencies/tutorial006_py39.py diff --git a/docs_src/dependencies/tutorial007.py b/docs_src/dependencies/tutorial007_py39.py similarity index 100% rename from docs_src/dependencies/tutorial007.py rename to docs_src/dependencies/tutorial007_py39.py diff --git a/docs_src/dependencies/tutorial008_an.py b/docs_src/dependencies/tutorial008_an.py deleted file mode 100644 index 2de86f042d..0000000000 --- a/docs_src/dependencies/tutorial008_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from fastapi import Depends -from typing_extensions import Annotated - - -async def dependency_a(): - dep_a = generate_dep_a() - try: - yield dep_a - finally: - dep_a.close() - - -async def dependency_b(dep_a: Annotated[DepA, Depends(dependency_a)]): - dep_b = generate_dep_b() - try: - yield dep_b - finally: - dep_b.close(dep_a) - - -async def dependency_c(dep_b: Annotated[DepB, Depends(dependency_b)]): - dep_c = generate_dep_c() - try: - yield dep_c - finally: - dep_c.close(dep_b) diff --git a/docs_src/dependencies/tutorial008.py b/docs_src/dependencies/tutorial008_py39.py similarity index 100% rename from docs_src/dependencies/tutorial008.py rename to docs_src/dependencies/tutorial008_py39.py diff --git a/docs_src/dependencies/tutorial008b_an.py b/docs_src/dependencies/tutorial008b_an.py deleted file mode 100644 index 84d8f12c14..0000000000 --- a/docs_src/dependencies/tutorial008b_an.py +++ /dev/null @@ -1,31 +0,0 @@ -from fastapi import Depends, FastAPI, HTTPException -from typing_extensions import Annotated - -app = FastAPI() - - -data = { - "plumbus": {"description": "Freshly pickled plumbus", "owner": "Morty"}, - "portal-gun": {"description": "Gun to create portals", "owner": "Rick"}, -} - - -class OwnerError(Exception): - pass - - -def get_username(): - try: - yield "Rick" - except OwnerError as e: - raise HTTPException(status_code=400, detail=f"Owner error: {e}") - - -@app.get("/items/{item_id}") -def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): - if item_id not in data: - raise HTTPException(status_code=404, detail="Item not found") - item = data[item_id] - if item["owner"] != username: - raise OwnerError(username) - return item diff --git a/docs_src/dependencies/tutorial008b.py b/docs_src/dependencies/tutorial008b_py39.py similarity index 100% rename from docs_src/dependencies/tutorial008b.py rename to docs_src/dependencies/tutorial008b_py39.py diff --git a/docs_src/dependencies/tutorial008c_an.py b/docs_src/dependencies/tutorial008c_an.py deleted file mode 100644 index 94f59f9aa6..0000000000 --- a/docs_src/dependencies/tutorial008c_an.py +++ /dev/null @@ -1,28 +0,0 @@ -from fastapi import Depends, FastAPI, HTTPException -from typing_extensions import Annotated - -app = FastAPI() - - -class InternalError(Exception): - pass - - -def get_username(): - try: - yield "Rick" - except InternalError: - print("Oops, we didn't raise again, Britney 😱") - - -@app.get("/items/{item_id}") -def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): - if item_id == "portal-gun": - raise InternalError( - f"The portal gun is too dangerous to be owned by {username}" - ) - if item_id != "plumbus": - raise HTTPException( - status_code=404, detail="Item not found, there's only a plumbus here" - ) - return item_id diff --git a/docs_src/dependencies/tutorial008c.py b/docs_src/dependencies/tutorial008c_py39.py similarity index 100% rename from docs_src/dependencies/tutorial008c.py rename to docs_src/dependencies/tutorial008c_py39.py diff --git a/docs_src/dependencies/tutorial008d_an.py b/docs_src/dependencies/tutorial008d_an.py deleted file mode 100644 index c354245744..0000000000 --- a/docs_src/dependencies/tutorial008d_an.py +++ /dev/null @@ -1,29 +0,0 @@ -from fastapi import Depends, FastAPI, HTTPException -from typing_extensions import Annotated - -app = FastAPI() - - -class InternalError(Exception): - pass - - -def get_username(): - try: - yield "Rick" - except InternalError: - print("We don't swallow the internal error here, we raise again 😎") - raise - - -@app.get("/items/{item_id}") -def get_item(item_id: str, username: Annotated[str, Depends(get_username)]): - if item_id == "portal-gun": - raise InternalError( - f"The portal gun is too dangerous to be owned by {username}" - ) - if item_id != "plumbus": - raise HTTPException( - status_code=404, detail="Item not found, there's only a plumbus here" - ) - return item_id diff --git a/docs_src/dependencies/tutorial008d.py b/docs_src/dependencies/tutorial008d_py39.py similarity index 100% rename from docs_src/dependencies/tutorial008d.py rename to docs_src/dependencies/tutorial008d_py39.py diff --git a/docs_src/dependencies/tutorial008e_an.py b/docs_src/dependencies/tutorial008e_an.py deleted file mode 100644 index c8a0af2b3b..0000000000 --- a/docs_src/dependencies/tutorial008e_an.py +++ /dev/null @@ -1,16 +0,0 @@ -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -def get_username(): - try: - yield "Rick" - finally: - print("Cleanup up before response is sent") - - -@app.get("/users/me") -def get_user_me(username: Annotated[str, Depends(get_username, scope="function")]): - return username diff --git a/docs_src/dependencies/tutorial008e.py b/docs_src/dependencies/tutorial008e_py39.py similarity index 100% rename from docs_src/dependencies/tutorial008e.py rename to docs_src/dependencies/tutorial008e_py39.py diff --git a/docs_src/dependencies/tutorial009.py b/docs_src/dependencies/tutorial009.py deleted file mode 100644 index 8472f642de..0000000000 --- a/docs_src/dependencies/tutorial009.py +++ /dev/null @@ -1,25 +0,0 @@ -from fastapi import Depends - - -async def dependency_a(): - dep_a = generate_dep_a() - try: - yield dep_a - finally: - dep_a.close() - - -async def dependency_b(dep_a=Depends(dependency_a)): - dep_b = generate_dep_b() - try: - yield dep_b - finally: - dep_b.close(dep_a) - - -async def dependency_c(dep_b=Depends(dependency_b)): - dep_c = generate_dep_c() - try: - yield dep_c - finally: - dep_c.close(dep_b) diff --git a/docs_src/dependencies/tutorial010.py b/docs_src/dependencies/tutorial010_py39.py similarity index 100% rename from docs_src/dependencies/tutorial010.py rename to docs_src/dependencies/tutorial010_py39.py diff --git a/docs_src/dependencies/tutorial011_an.py b/docs_src/dependencies/tutorial011_an.py deleted file mode 100644 index 6c13d9033f..0000000000 --- a/docs_src/dependencies/tutorial011_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -class FixedContentQueryChecker: - def __init__(self, fixed_content: str): - self.fixed_content = fixed_content - - def __call__(self, q: str = ""): - if q: - return self.fixed_content in q - return False - - -checker = FixedContentQueryChecker("bar") - - -@app.get("/query-checker/") -async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]): - return {"fixed_content_in_query": fixed_content_included} diff --git a/docs_src/dependencies/tutorial011.py b/docs_src/dependencies/tutorial011_py39.py similarity index 100% rename from docs_src/dependencies/tutorial011.py rename to docs_src/dependencies/tutorial011_py39.py diff --git a/docs_src/dependencies/tutorial012_an.py b/docs_src/dependencies/tutorial012_an.py deleted file mode 100644 index 7541e6bf41..0000000000 --- a/docs_src/dependencies/tutorial012_an.py +++ /dev/null @@ -1,26 +0,0 @@ -from fastapi import Depends, FastAPI, Header, HTTPException -from typing_extensions import Annotated - - -async def verify_token(x_token: Annotated[str, Header()]): - if x_token != "fake-super-secret-token": - raise HTTPException(status_code=400, detail="X-Token header invalid") - - -async def verify_key(x_key: Annotated[str, Header()]): - if x_key != "fake-super-secret-key": - raise HTTPException(status_code=400, detail="X-Key header invalid") - return x_key - - -app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)]) - - -@app.get("/items/") -async def read_items(): - return [{"item": "Portal Gun"}, {"item": "Plumbus"}] - - -@app.get("/users/") -async def read_users(): - return [{"username": "Rick"}, {"username": "Morty"}] diff --git a/docs_src/dependencies/tutorial012_an_py39.py b/docs_src/dependencies/tutorial012_an_py39.py index 7541e6bf41..6503591fc3 100644 --- a/docs_src/dependencies/tutorial012_an_py39.py +++ b/docs_src/dependencies/tutorial012_an_py39.py @@ -1,5 +1,6 @@ +from typing import Annotated + from fastapi import Depends, FastAPI, Header, HTTPException -from typing_extensions import Annotated async def verify_token(x_token: Annotated[str, Header()]): diff --git a/docs_src/dependencies/tutorial012.py b/docs_src/dependencies/tutorial012_py39.py similarity index 100% rename from docs_src/dependencies/tutorial012.py rename to docs_src/dependencies/tutorial012_py39.py diff --git a/docs_src/dependency_testing/tutorial001_an.py b/docs_src/dependency_testing/tutorial001_an.py deleted file mode 100644 index 4c76a87ff5..0000000000 --- a/docs_src/dependency_testing/tutorial001_an.py +++ /dev/null @@ -1,60 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI -from fastapi.testclient import TestClient -from typing_extensions import Annotated - -app = FastAPI() - - -async def common_parameters( - q: Union[str, None] = None, skip: int = 0, limit: int = 100 -): - return {"q": q, "skip": skip, "limit": limit} - - -@app.get("/items/") -async def read_items(commons: Annotated[dict, Depends(common_parameters)]): - return {"message": "Hello Items!", "params": commons} - - -@app.get("/users/") -async def read_users(commons: Annotated[dict, Depends(common_parameters)]): - return {"message": "Hello Users!", "params": commons} - - -client = TestClient(app) - - -async def override_dependency(q: Union[str, None] = None): - return {"q": q, "skip": 5, "limit": 10} - - -app.dependency_overrides[common_parameters] = override_dependency - - -def test_override_in_items(): - response = client.get("/items/") - assert response.status_code == 200 - assert response.json() == { - "message": "Hello Items!", - "params": {"q": None, "skip": 5, "limit": 10}, - } - - -def test_override_in_items_with_q(): - response = client.get("/items/?q=foo") - assert response.status_code == 200 - assert response.json() == { - "message": "Hello Items!", - "params": {"q": "foo", "skip": 5, "limit": 10}, - } - - -def test_override_in_items_with_params(): - response = client.get("/items/?q=foo&skip=100&limit=200") - assert response.status_code == 200 - assert response.json() == { - "message": "Hello Items!", - "params": {"q": "foo", "skip": 5, "limit": 10}, - } diff --git a/docs_src/dependency_testing/tutorial001.py b/docs_src/dependency_testing/tutorial001_py39.py similarity index 100% rename from docs_src/dependency_testing/tutorial001.py rename to docs_src/dependency_testing/tutorial001_py39.py diff --git a/docs_src/encoder/tutorial001.py b/docs_src/encoder/tutorial001_py39.py similarity index 100% rename from docs_src/encoder/tutorial001.py rename to docs_src/encoder/tutorial001_py39.py diff --git a/docs_src/events/tutorial001.py b/docs_src/events/tutorial001_py39.py similarity index 100% rename from docs_src/events/tutorial001.py rename to docs_src/events/tutorial001_py39.py diff --git a/docs_src/events/tutorial002.py b/docs_src/events/tutorial002_py39.py similarity index 100% rename from docs_src/events/tutorial002.py rename to docs_src/events/tutorial002_py39.py diff --git a/docs_src/events/tutorial003.py b/docs_src/events/tutorial003_py39.py similarity index 100% rename from docs_src/events/tutorial003.py rename to docs_src/events/tutorial003_py39.py diff --git a/docs_src/extending_openapi/tutorial001.py b/docs_src/extending_openapi/tutorial001_py39.py similarity index 100% rename from docs_src/extending_openapi/tutorial001.py rename to docs_src/extending_openapi/tutorial001_py39.py diff --git a/docs_src/extra_data_types/tutorial001_an.py b/docs_src/extra_data_types/tutorial001_an.py deleted file mode 100644 index 257d0c7c86..0000000000 --- a/docs_src/extra_data_types/tutorial001_an.py +++ /dev/null @@ -1,29 +0,0 @@ -from datetime import datetime, time, timedelta -from typing import Union -from uuid import UUID - -from fastapi import Body, FastAPI -from typing_extensions import Annotated - -app = FastAPI() - - -@app.put("/items/{item_id}") -async def read_items( - item_id: UUID, - start_datetime: Annotated[datetime, Body()], - end_datetime: Annotated[datetime, Body()], - process_after: Annotated[timedelta, Body()], - repeat_at: Annotated[Union[time, None], Body()] = None, -): - start_process = start_datetime + process_after - duration = end_datetime - start_process - return { - "item_id": item_id, - "start_datetime": start_datetime, - "end_datetime": end_datetime, - "process_after": process_after, - "repeat_at": repeat_at, - "start_process": start_process, - "duration": duration, - } diff --git a/docs_src/extra_data_types/tutorial001.py b/docs_src/extra_data_types/tutorial001_py39.py similarity index 100% rename from docs_src/extra_data_types/tutorial001.py rename to docs_src/extra_data_types/tutorial001_py39.py diff --git a/docs_src/extra_models/tutorial001.py b/docs_src/extra_models/tutorial001_py39.py similarity index 100% rename from docs_src/extra_models/tutorial001.py rename to docs_src/extra_models/tutorial001_py39.py diff --git a/docs_src/extra_models/tutorial002.py b/docs_src/extra_models/tutorial002_py39.py similarity index 100% rename from docs_src/extra_models/tutorial002.py rename to docs_src/extra_models/tutorial002_py39.py diff --git a/docs_src/extra_models/tutorial003.py b/docs_src/extra_models/tutorial003_py39.py similarity index 100% rename from docs_src/extra_models/tutorial003.py rename to docs_src/extra_models/tutorial003_py39.py diff --git a/docs_src/extra_models/tutorial004.py b/docs_src/extra_models/tutorial004.py deleted file mode 100644 index a8e0f7af5a..0000000000 --- a/docs_src/extra_models/tutorial004.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: str - - -items = [ - {"name": "Foo", "description": "There comes my hero"}, - {"name": "Red", "description": "It's my aeroplane"}, -] - - -@app.get("/items/", response_model=List[Item]) -async def read_items(): - return items diff --git a/docs_src/extra_models/tutorial005.py b/docs_src/extra_models/tutorial005.py deleted file mode 100644 index a81cbc2c58..0000000000 --- a/docs_src/extra_models/tutorial005.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import Dict - -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/keyword-weights/", response_model=Dict[str, float]) -async def read_keyword_weights(): - return {"foo": 2.3, "bar": 3.4} diff --git a/docs_src/first_steps/tutorial001.py b/docs_src/first_steps/tutorial001_py39.py similarity index 100% rename from docs_src/first_steps/tutorial001.py rename to docs_src/first_steps/tutorial001_py39.py diff --git a/docs_src/first_steps/tutorial002.py b/docs_src/first_steps/tutorial002.py deleted file mode 100644 index ca7d48cff9..0000000000 --- a/docs_src/first_steps/tutorial002.py +++ /dev/null @@ -1,8 +0,0 @@ -from fastapi import FastAPI - -my_awesome_api = FastAPI() - - -@my_awesome_api.get("/") -async def root(): - return {"message": "Hello World"} diff --git a/docs_src/first_steps/tutorial003.py b/docs_src/first_steps/tutorial003_py39.py similarity index 100% rename from docs_src/first_steps/tutorial003.py rename to docs_src/first_steps/tutorial003_py39.py diff --git a/docs_src/generate_clients/tutorial001.py b/docs_src/generate_clients/tutorial001.py deleted file mode 100644 index 2d1f91bc6c..0000000000 --- a/docs_src/generate_clients/tutorial001.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import List - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - price: float - - -class ResponseMessage(BaseModel): - message: str - - -@app.post("/items/", response_model=ResponseMessage) -async def create_item(item: Item): - return {"message": "item received"} - - -@app.get("/items/", response_model=List[Item]) -async def get_items(): - return [ - {"name": "Plumbus", "price": 3}, - {"name": "Portal Gun", "price": 9001}, - ] diff --git a/docs_src/generate_clients/tutorial002.py b/docs_src/generate_clients/tutorial002.py deleted file mode 100644 index bd80449af9..0000000000 --- a/docs_src/generate_clients/tutorial002.py +++ /dev/null @@ -1,38 +0,0 @@ -from typing import List - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - price: float - - -class ResponseMessage(BaseModel): - message: str - - -class User(BaseModel): - username: str - email: str - - -@app.post("/items/", response_model=ResponseMessage, tags=["items"]) -async def create_item(item: Item): - return {"message": "Item received"} - - -@app.get("/items/", response_model=List[Item], tags=["items"]) -async def get_items(): - return [ - {"name": "Plumbus", "price": 3}, - {"name": "Portal Gun", "price": 9001}, - ] - - -@app.post("/users/", response_model=ResponseMessage, tags=["users"]) -async def create_user(user: User): - return {"message": "User received"} diff --git a/docs_src/generate_clients/tutorial003.py b/docs_src/generate_clients/tutorial003.py deleted file mode 100644 index 49eab73a1b..0000000000 --- a/docs_src/generate_clients/tutorial003.py +++ /dev/null @@ -1,44 +0,0 @@ -from typing import List - -from fastapi import FastAPI -from fastapi.routing import APIRoute -from pydantic import BaseModel - - -def custom_generate_unique_id(route: APIRoute): - return f"{route.tags[0]}-{route.name}" - - -app = FastAPI(generate_unique_id_function=custom_generate_unique_id) - - -class Item(BaseModel): - name: str - price: float - - -class ResponseMessage(BaseModel): - message: str - - -class User(BaseModel): - username: str - email: str - - -@app.post("/items/", response_model=ResponseMessage, tags=["items"]) -async def create_item(item: Item): - return {"message": "Item received"} - - -@app.get("/items/", response_model=List[Item], tags=["items"]) -async def get_items(): - return [ - {"name": "Plumbus", "price": 3}, - {"name": "Portal Gun", "price": 9001}, - ] - - -@app.post("/users/", response_model=ResponseMessage, tags=["users"]) -async def create_user(user: User): - return {"message": "User received"} diff --git a/docs_src/generate_clients/tutorial004.py b/docs_src/generate_clients/tutorial004_py39.py similarity index 100% rename from docs_src/generate_clients/tutorial004.py rename to docs_src/generate_clients/tutorial004_py39.py diff --git a/docs_src/graphql/tutorial001.py b/docs_src/graphql/tutorial001_py39.py similarity index 100% rename from docs_src/graphql/tutorial001.py rename to docs_src/graphql/tutorial001_py39.py diff --git a/docs_src/handling_errors/tutorial001.py b/docs_src/handling_errors/tutorial001_py39.py similarity index 100% rename from docs_src/handling_errors/tutorial001.py rename to docs_src/handling_errors/tutorial001_py39.py diff --git a/docs_src/handling_errors/tutorial002.py b/docs_src/handling_errors/tutorial002_py39.py similarity index 100% rename from docs_src/handling_errors/tutorial002.py rename to docs_src/handling_errors/tutorial002_py39.py diff --git a/docs_src/handling_errors/tutorial003.py b/docs_src/handling_errors/tutorial003_py39.py similarity index 100% rename from docs_src/handling_errors/tutorial003.py rename to docs_src/handling_errors/tutorial003_py39.py diff --git a/docs_src/handling_errors/tutorial004.py b/docs_src/handling_errors/tutorial004_py39.py similarity index 100% rename from docs_src/handling_errors/tutorial004.py rename to docs_src/handling_errors/tutorial004_py39.py diff --git a/docs_src/handling_errors/tutorial005.py b/docs_src/handling_errors/tutorial005_py39.py similarity index 100% rename from docs_src/handling_errors/tutorial005.py rename to docs_src/handling_errors/tutorial005_py39.py diff --git a/docs_src/handling_errors/tutorial006.py b/docs_src/handling_errors/tutorial006_py39.py similarity index 100% rename from docs_src/handling_errors/tutorial006.py rename to docs_src/handling_errors/tutorial006_py39.py diff --git a/docs_src/header_param_models/tutorial001.py b/docs_src/header_param_models/tutorial001.py deleted file mode 100644 index 4caaba87b9..0000000000 --- a/docs_src/header_param_models/tutorial001.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel - -app = FastAPI() - - -class CommonHeaders(BaseModel): - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: CommonHeaders = Header()): - return headers diff --git a/docs_src/header_param_models/tutorial001_an.py b/docs_src/header_param_models/tutorial001_an.py deleted file mode 100644 index b55c6b56b1..0000000000 --- a/docs_src/header_param_models/tutorial001_an.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class CommonHeaders(BaseModel): - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: Annotated[CommonHeaders, Header()]): - return headers diff --git a/docs_src/header_param_models/tutorial002.py b/docs_src/header_param_models/tutorial002.py deleted file mode 100644 index 3f9aac58d2..0000000000 --- a/docs_src/header_param_models/tutorial002.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel - -app = FastAPI() - - -class CommonHeaders(BaseModel): - model_config = {"extra": "forbid"} - - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: CommonHeaders = Header()): - return headers diff --git a/docs_src/header_param_models/tutorial002_an.py b/docs_src/header_param_models/tutorial002_an.py deleted file mode 100644 index 771135d770..0000000000 --- a/docs_src/header_param_models/tutorial002_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class CommonHeaders(BaseModel): - model_config = {"extra": "forbid"} - - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: Annotated[CommonHeaders, Header()]): - return headers diff --git a/docs_src/header_param_models/tutorial002_pv1.py b/docs_src/header_param_models/tutorial002_pv1.py deleted file mode 100644 index 7e56cd993b..0000000000 --- a/docs_src/header_param_models/tutorial002_pv1.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel - -app = FastAPI() - - -class CommonHeaders(BaseModel): - class Config: - extra = "forbid" - - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: CommonHeaders = Header()): - return headers diff --git a/docs_src/header_param_models/tutorial002_pv1_an.py b/docs_src/header_param_models/tutorial002_pv1_an.py deleted file mode 100644 index 236778231a..0000000000 --- a/docs_src/header_param_models/tutorial002_pv1_an.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class CommonHeaders(BaseModel): - class Config: - extra = "forbid" - - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: Annotated[CommonHeaders, Header()]): - return headers diff --git a/docs_src/header_param_models/tutorial003.py b/docs_src/header_param_models/tutorial003.py deleted file mode 100644 index dc2eb74bd1..0000000000 --- a/docs_src/header_param_models/tutorial003.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel - -app = FastAPI() - - -class CommonHeaders(BaseModel): - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items(headers: CommonHeaders = Header(convert_underscores=False)): - return headers diff --git a/docs_src/header_param_models/tutorial003_an.py b/docs_src/header_param_models/tutorial003_an.py deleted file mode 100644 index e3edb11891..0000000000 --- a/docs_src/header_param_models/tutorial003_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class CommonHeaders(BaseModel): - host: str - save_data: bool - if_modified_since: Union[str, None] = None - traceparent: Union[str, None] = None - x_tag: List[str] = [] - - -@app.get("/items/") -async def read_items( - headers: Annotated[CommonHeaders, Header(convert_underscores=False)], -): - return headers diff --git a/docs_src/header_params/tutorial001_an.py b/docs_src/header_params/tutorial001_an.py deleted file mode 100644 index 816c000862..0000000000 --- a/docs_src/header_params/tutorial001_an.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Header -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(user_agent: Annotated[Union[str, None], Header()] = None): - return {"User-Agent": user_agent} diff --git a/docs_src/header_params/tutorial001.py b/docs_src/header_params/tutorial001_py39.py similarity index 100% rename from docs_src/header_params/tutorial001.py rename to docs_src/header_params/tutorial001_py39.py diff --git a/docs_src/header_params/tutorial002_an.py b/docs_src/header_params/tutorial002_an.py deleted file mode 100644 index 82fe49ba2b..0000000000 --- a/docs_src/header_params/tutorial002_an.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Header -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - strange_header: Annotated[ - Union[str, None], Header(convert_underscores=False) - ] = None, -): - return {"strange_header": strange_header} diff --git a/docs_src/header_params/tutorial002.py b/docs_src/header_params/tutorial002_py39.py similarity index 100% rename from docs_src/header_params/tutorial002.py rename to docs_src/header_params/tutorial002_py39.py diff --git a/docs_src/header_params/tutorial003.py b/docs_src/header_params/tutorial003.py deleted file mode 100644 index a61314aedb..0000000000 --- a/docs_src/header_params/tutorial003.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header - -app = FastAPI() - - -@app.get("/items/") -async def read_items(x_token: Union[List[str], None] = Header(default=None)): - return {"X-Token values": x_token} diff --git a/docs_src/header_params/tutorial003_an.py b/docs_src/header_params/tutorial003_an.py deleted file mode 100644 index 5406fd1f88..0000000000 --- a/docs_src/header_params/tutorial003_an.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Header -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(x_token: Annotated[Union[List[str], None], Header()] = None): - return {"X-Token values": x_token} diff --git a/docs_src/metadata/tutorial001_1.py b/docs_src/metadata/tutorial001_1_py39.py similarity index 100% rename from docs_src/metadata/tutorial001_1.py rename to docs_src/metadata/tutorial001_1_py39.py diff --git a/docs_src/metadata/tutorial001.py b/docs_src/metadata/tutorial001_py39.py similarity index 100% rename from docs_src/metadata/tutorial001.py rename to docs_src/metadata/tutorial001_py39.py diff --git a/docs_src/metadata/tutorial002.py b/docs_src/metadata/tutorial002_py39.py similarity index 100% rename from docs_src/metadata/tutorial002.py rename to docs_src/metadata/tutorial002_py39.py diff --git a/docs_src/metadata/tutorial003.py b/docs_src/metadata/tutorial003_py39.py similarity index 100% rename from docs_src/metadata/tutorial003.py rename to docs_src/metadata/tutorial003_py39.py diff --git a/docs_src/metadata/tutorial004.py b/docs_src/metadata/tutorial004_py39.py similarity index 100% rename from docs_src/metadata/tutorial004.py rename to docs_src/metadata/tutorial004_py39.py diff --git a/docs_src/middleware/tutorial001.py b/docs_src/middleware/tutorial001_py39.py similarity index 100% rename from docs_src/middleware/tutorial001.py rename to docs_src/middleware/tutorial001_py39.py diff --git a/docs_src/openapi_callbacks/tutorial001.py b/docs_src/openapi_callbacks/tutorial001_py39.py similarity index 100% rename from docs_src/openapi_callbacks/tutorial001.py rename to docs_src/openapi_callbacks/tutorial001_py39.py diff --git a/docs_src/openapi_webhooks/tutorial001.py b/docs_src/openapi_webhooks/tutorial001_py39.py similarity index 100% rename from docs_src/openapi_webhooks/tutorial001.py rename to docs_src/openapi_webhooks/tutorial001_py39.py diff --git a/docs_src/path_operation_advanced_configuration/tutorial001.py b/docs_src/path_operation_advanced_configuration/tutorial001_py39.py similarity index 100% rename from docs_src/path_operation_advanced_configuration/tutorial001.py rename to docs_src/path_operation_advanced_configuration/tutorial001_py39.py diff --git a/docs_src/path_operation_advanced_configuration/tutorial002.py b/docs_src/path_operation_advanced_configuration/tutorial002_py39.py similarity index 100% rename from docs_src/path_operation_advanced_configuration/tutorial002.py rename to docs_src/path_operation_advanced_configuration/tutorial002_py39.py diff --git a/docs_src/path_operation_advanced_configuration/tutorial003.py b/docs_src/path_operation_advanced_configuration/tutorial003_py39.py similarity index 100% rename from docs_src/path_operation_advanced_configuration/tutorial003.py rename to docs_src/path_operation_advanced_configuration/tutorial003_py39.py diff --git a/docs_src/path_operation_advanced_configuration/tutorial004.py b/docs_src/path_operation_advanced_configuration/tutorial004.py deleted file mode 100644 index a3aad4ac40..0000000000 --- a/docs_src/path_operation_advanced_configuration/tutorial004.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.post("/items/", response_model=Item, summary="Create an item") -async def create_item(item: Item): - """ - Create an item with all the information: - - - **name**: each item must have a name - - **description**: a long description - - **price**: required - - **tax**: if the item doesn't have tax, you can omit this - - **tags**: a set of unique tag strings for this item - \f - :param item: User input. - """ - return item diff --git a/docs_src/path_operation_advanced_configuration/tutorial005.py b/docs_src/path_operation_advanced_configuration/tutorial005_py39.py similarity index 100% rename from docs_src/path_operation_advanced_configuration/tutorial005.py rename to docs_src/path_operation_advanced_configuration/tutorial005_py39.py diff --git a/docs_src/path_operation_advanced_configuration/tutorial006.py b/docs_src/path_operation_advanced_configuration/tutorial006_py39.py similarity index 100% rename from docs_src/path_operation_advanced_configuration/tutorial006.py rename to docs_src/path_operation_advanced_configuration/tutorial006_py39.py diff --git a/docs_src/path_operation_advanced_configuration/tutorial007.py b/docs_src/path_operation_advanced_configuration/tutorial007.py deleted file mode 100644 index 54e2e9399e..0000000000 --- a/docs_src/path_operation_advanced_configuration/tutorial007.py +++ /dev/null @@ -1,34 +0,0 @@ -from typing import List - -import yaml -from fastapi import FastAPI, HTTPException, Request -from pydantic import BaseModel, ValidationError - -app = FastAPI() - - -class Item(BaseModel): - name: str - tags: List[str] - - -@app.post( - "/items/", - openapi_extra={ - "requestBody": { - "content": {"application/x-yaml": {"schema": Item.model_json_schema()}}, - "required": True, - }, - }, -) -async def create_item(request: Request): - raw_body = await request.body() - try: - data = yaml.safe_load(raw_body) - except yaml.YAMLError: - raise HTTPException(status_code=422, detail="Invalid YAML") - try: - item = Item.model_validate(data) - except ValidationError as e: - raise HTTPException(status_code=422, detail=e.errors(include_url=False)) - return item diff --git a/docs_src/path_operation_advanced_configuration/tutorial007_pv1.py b/docs_src/path_operation_advanced_configuration/tutorial007_pv1.py deleted file mode 100644 index d51752bb87..0000000000 --- a/docs_src/path_operation_advanced_configuration/tutorial007_pv1.py +++ /dev/null @@ -1,34 +0,0 @@ -from typing import List - -import yaml -from fastapi import FastAPI, HTTPException, Request -from pydantic import BaseModel, ValidationError - -app = FastAPI() - - -class Item(BaseModel): - name: str - tags: List[str] - - -@app.post( - "/items/", - openapi_extra={ - "requestBody": { - "content": {"application/x-yaml": {"schema": Item.schema()}}, - "required": True, - }, - }, -) -async def create_item(request: Request): - raw_body = await request.body() - try: - data = yaml.safe_load(raw_body) - except yaml.YAMLError: - raise HTTPException(status_code=422, detail="Invalid YAML") - try: - item = Item.parse_obj(data) - except ValidationError as e: - raise HTTPException(status_code=422, detail=e.errors()) - return item diff --git a/docs_src/path_operation_configuration/tutorial001.py b/docs_src/path_operation_configuration/tutorial001.py deleted file mode 100644 index 83fd8377ab..0000000000 --- a/docs_src/path_operation_configuration/tutorial001.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI, status -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED) -async def create_item(item: Item): - return item diff --git a/docs_src/path_operation_configuration/tutorial002.py b/docs_src/path_operation_configuration/tutorial002.py deleted file mode 100644 index 798b0c2311..0000000000 --- a/docs_src/path_operation_configuration/tutorial002.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.post("/items/", response_model=Item, tags=["items"]) -async def create_item(item: Item): - return item - - -@app.get("/items/", tags=["items"]) -async def read_items(): - return [{"name": "Foo", "price": 42}] - - -@app.get("/users/", tags=["users"]) -async def read_users(): - return [{"username": "johndoe"}] diff --git a/docs_src/path_operation_configuration/tutorial002b.py b/docs_src/path_operation_configuration/tutorial002b_py39.py similarity index 100% rename from docs_src/path_operation_configuration/tutorial002b.py rename to docs_src/path_operation_configuration/tutorial002b_py39.py diff --git a/docs_src/path_operation_configuration/tutorial003.py b/docs_src/path_operation_configuration/tutorial003.py deleted file mode 100644 index 26bf7dabae..0000000000 --- a/docs_src/path_operation_configuration/tutorial003.py +++ /dev/null @@ -1,24 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.post( - "/items/", - response_model=Item, - summary="Create an item", - description="Create an item with all the information, name, description, price, tax and a set of unique tags", -) -async def create_item(item: Item): - return item diff --git a/docs_src/path_operation_configuration/tutorial004.py b/docs_src/path_operation_configuration/tutorial004.py deleted file mode 100644 index 8f865c58a6..0000000000 --- a/docs_src/path_operation_configuration/tutorial004.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.post("/items/", response_model=Item, summary="Create an item") -async def create_item(item: Item): - """ - Create an item with all the information: - - - **name**: each item must have a name - - **description**: a long description - - **price**: required - - **tax**: if the item doesn't have tax, you can omit this - - **tags**: a set of unique tag strings for this item - """ - return item diff --git a/docs_src/path_operation_configuration/tutorial005.py b/docs_src/path_operation_configuration/tutorial005.py deleted file mode 100644 index 2c1be4a34b..0000000000 --- a/docs_src/path_operation_configuration/tutorial005.py +++ /dev/null @@ -1,33 +0,0 @@ -from typing import Set, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: Set[str] = set() - - -@app.post( - "/items/", - response_model=Item, - summary="Create an item", - response_description="The created item", -) -async def create_item(item: Item): - """ - Create an item with all the information: - - - **name**: each item must have a name - - **description**: a long description - - **price**: required - - **tax**: if the item doesn't have tax, you can omit this - - **tags**: a set of unique tag strings for this item - """ - return item diff --git a/docs_src/path_operation_configuration/tutorial006.py b/docs_src/path_operation_configuration/tutorial006_py39.py similarity index 100% rename from docs_src/path_operation_configuration/tutorial006.py rename to docs_src/path_operation_configuration/tutorial006_py39.py diff --git a/docs_src/path_params/tutorial001.py b/docs_src/path_params/tutorial001_py39.py similarity index 100% rename from docs_src/path_params/tutorial001.py rename to docs_src/path_params/tutorial001_py39.py diff --git a/docs_src/path_params/tutorial002.py b/docs_src/path_params/tutorial002_py39.py similarity index 100% rename from docs_src/path_params/tutorial002.py rename to docs_src/path_params/tutorial002_py39.py diff --git a/docs_src/path_params/tutorial003.py b/docs_src/path_params/tutorial003_py39.py similarity index 100% rename from docs_src/path_params/tutorial003.py rename to docs_src/path_params/tutorial003_py39.py diff --git a/docs_src/path_params/tutorial003b.py b/docs_src/path_params/tutorial003b_py39.py similarity index 100% rename from docs_src/path_params/tutorial003b.py rename to docs_src/path_params/tutorial003b_py39.py diff --git a/docs_src/path_params/tutorial004.py b/docs_src/path_params/tutorial004_py39.py similarity index 100% rename from docs_src/path_params/tutorial004.py rename to docs_src/path_params/tutorial004_py39.py diff --git a/docs_src/path_params/tutorial005.py b/docs_src/path_params/tutorial005_py39.py similarity index 100% rename from docs_src/path_params/tutorial005.py rename to docs_src/path_params/tutorial005_py39.py diff --git a/docs_src/path_params_numeric_validations/tutorial001_an.py b/docs_src/path_params_numeric_validations/tutorial001_an.py deleted file mode 100644 index 621be7b045..0000000000 --- a/docs_src/path_params_numeric_validations/tutorial001_an.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Path, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_items( - item_id: Annotated[int, Path(title="The ID of the item to get")], - q: Annotated[Union[str, None], Query(alias="item-query")] = None, -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/path_params_numeric_validations/tutorial001.py b/docs_src/path_params_numeric_validations/tutorial001_py39.py similarity index 100% rename from docs_src/path_params_numeric_validations/tutorial001.py rename to docs_src/path_params_numeric_validations/tutorial001_py39.py diff --git a/docs_src/path_params_numeric_validations/tutorial002_an.py b/docs_src/path_params_numeric_validations/tutorial002_an.py deleted file mode 100644 index 322f8cf0bb..0000000000 --- a/docs_src/path_params_numeric_validations/tutorial002_an.py +++ /dev/null @@ -1,14 +0,0 @@ -from fastapi import FastAPI, Path -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_items( - q: str, item_id: Annotated[int, Path(title="The ID of the item to get")] -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/path_params_numeric_validations/tutorial002.py b/docs_src/path_params_numeric_validations/tutorial002_py39.py similarity index 100% rename from docs_src/path_params_numeric_validations/tutorial002.py rename to docs_src/path_params_numeric_validations/tutorial002_py39.py diff --git a/docs_src/path_params_numeric_validations/tutorial003_an.py b/docs_src/path_params_numeric_validations/tutorial003_an.py deleted file mode 100644 index d0fa8b3db9..0000000000 --- a/docs_src/path_params_numeric_validations/tutorial003_an.py +++ /dev/null @@ -1,14 +0,0 @@ -from fastapi import FastAPI, Path -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_items( - item_id: Annotated[int, Path(title="The ID of the item to get")], q: str -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/path_params_numeric_validations/tutorial003.py b/docs_src/path_params_numeric_validations/tutorial003_py39.py similarity index 100% rename from docs_src/path_params_numeric_validations/tutorial003.py rename to docs_src/path_params_numeric_validations/tutorial003_py39.py diff --git a/docs_src/path_params_numeric_validations/tutorial004_an.py b/docs_src/path_params_numeric_validations/tutorial004_an.py deleted file mode 100644 index ffc50f6c5b..0000000000 --- a/docs_src/path_params_numeric_validations/tutorial004_an.py +++ /dev/null @@ -1,14 +0,0 @@ -from fastapi import FastAPI, Path -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_items( - item_id: Annotated[int, Path(title="The ID of the item to get", ge=1)], q: str -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/path_params_numeric_validations/tutorial004.py b/docs_src/path_params_numeric_validations/tutorial004_py39.py similarity index 100% rename from docs_src/path_params_numeric_validations/tutorial004.py rename to docs_src/path_params_numeric_validations/tutorial004_py39.py diff --git a/docs_src/path_params_numeric_validations/tutorial005_an.py b/docs_src/path_params_numeric_validations/tutorial005_an.py deleted file mode 100644 index 433c69129f..0000000000 --- a/docs_src/path_params_numeric_validations/tutorial005_an.py +++ /dev/null @@ -1,15 +0,0 @@ -from fastapi import FastAPI, Path -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_items( - item_id: Annotated[int, Path(title="The ID of the item to get", gt=0, le=1000)], - q: str, -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/path_params_numeric_validations/tutorial005.py b/docs_src/path_params_numeric_validations/tutorial005_py39.py similarity index 100% rename from docs_src/path_params_numeric_validations/tutorial005.py rename to docs_src/path_params_numeric_validations/tutorial005_py39.py diff --git a/docs_src/path_params_numeric_validations/tutorial006_an.py b/docs_src/path_params_numeric_validations/tutorial006_an.py deleted file mode 100644 index ac47325732..0000000000 --- a/docs_src/path_params_numeric_validations/tutorial006_an.py +++ /dev/null @@ -1,19 +0,0 @@ -from fastapi import FastAPI, Path, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_items( - *, - item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)], - q: str, - size: Annotated[float, Query(gt=0, lt=10.5)], -): - results = {"item_id": item_id} - if q: - results.update({"q": q}) - if size: - results.update({"size": size}) - return results diff --git a/docs_src/path_params_numeric_validations/tutorial006.py b/docs_src/path_params_numeric_validations/tutorial006_py39.py similarity index 100% rename from docs_src/path_params_numeric_validations/tutorial006.py rename to docs_src/path_params_numeric_validations/tutorial006_py39.py diff --git a/docs_src/pydantic_v1_in_v2/tutorial001_an.py b/docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py similarity index 100% rename from docs_src/pydantic_v1_in_v2/tutorial001_an.py rename to docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py diff --git a/docs_src/pydantic_v1_in_v2/tutorial002_an.py b/docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py similarity index 100% rename from docs_src/pydantic_v1_in_v2/tutorial002_an.py rename to docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py diff --git a/docs_src/pydantic_v1_in_v2/tutorial003_an.py b/docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py similarity index 100% rename from docs_src/pydantic_v1_in_v2/tutorial003_an.py rename to docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py diff --git a/docs_src/pydantic_v1_in_v2/tutorial004_an.py b/docs_src/pydantic_v1_in_v2/tutorial004_an.py deleted file mode 100644 index cca8a9ea80..0000000000 --- a/docs_src/pydantic_v1_in_v2/tutorial004_an.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Union - -from fastapi import FastAPI -from fastapi.temp_pydantic_v1_params import Body -from pydantic.v1 import BaseModel -from typing_extensions import Annotated - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - size: float - - -app = FastAPI() - - -@app.post("/items/") -async def create_item(item: Annotated[Item, Body(embed=True)]) -> Item: - return item diff --git a/docs_src/python_types/tutorial001.py b/docs_src/python_types/tutorial001_py39.py similarity index 100% rename from docs_src/python_types/tutorial001.py rename to docs_src/python_types/tutorial001_py39.py diff --git a/docs_src/python_types/tutorial002.py b/docs_src/python_types/tutorial002_py39.py similarity index 100% rename from docs_src/python_types/tutorial002.py rename to docs_src/python_types/tutorial002_py39.py diff --git a/docs_src/python_types/tutorial003.py b/docs_src/python_types/tutorial003_py39.py similarity index 100% rename from docs_src/python_types/tutorial003.py rename to docs_src/python_types/tutorial003_py39.py diff --git a/docs_src/python_types/tutorial004.py b/docs_src/python_types/tutorial004_py39.py similarity index 100% rename from docs_src/python_types/tutorial004.py rename to docs_src/python_types/tutorial004_py39.py diff --git a/docs_src/python_types/tutorial005.py b/docs_src/python_types/tutorial005_py39.py similarity index 100% rename from docs_src/python_types/tutorial005.py rename to docs_src/python_types/tutorial005_py39.py diff --git a/docs_src/python_types/tutorial006.py b/docs_src/python_types/tutorial006.py deleted file mode 100644 index 87394ecb0c..0000000000 --- a/docs_src/python_types/tutorial006.py +++ /dev/null @@ -1,6 +0,0 @@ -from typing import List - - -def process_items(items: List[str]): - for item in items: - print(item) diff --git a/docs_src/python_types/tutorial007.py b/docs_src/python_types/tutorial007.py deleted file mode 100644 index 5b13f15494..0000000000 --- a/docs_src/python_types/tutorial007.py +++ /dev/null @@ -1,5 +0,0 @@ -from typing import Set, Tuple - - -def process_items(items_t: Tuple[int, int, str], items_s: Set[bytes]): - return items_t, items_s diff --git a/docs_src/python_types/tutorial008.py b/docs_src/python_types/tutorial008.py deleted file mode 100644 index 9fb1043bb8..0000000000 --- a/docs_src/python_types/tutorial008.py +++ /dev/null @@ -1,7 +0,0 @@ -from typing import Dict - - -def process_items(prices: Dict[str, float]): - for item_name, item_price in prices.items(): - print(item_name) - print(item_price) diff --git a/docs_src/python_types/tutorial008b.py b/docs_src/python_types/tutorial008b_py39.py similarity index 100% rename from docs_src/python_types/tutorial008b.py rename to docs_src/python_types/tutorial008b_py39.py diff --git a/docs_src/python_types/tutorial009.py b/docs_src/python_types/tutorial009_py39.py similarity index 100% rename from docs_src/python_types/tutorial009.py rename to docs_src/python_types/tutorial009_py39.py diff --git a/docs_src/python_types/tutorial009b.py b/docs_src/python_types/tutorial009b_py39.py similarity index 100% rename from docs_src/python_types/tutorial009b.py rename to docs_src/python_types/tutorial009b_py39.py diff --git a/docs_src/python_types/tutorial009c.py b/docs_src/python_types/tutorial009c_py39.py similarity index 100% rename from docs_src/python_types/tutorial009c.py rename to docs_src/python_types/tutorial009c_py39.py diff --git a/docs_src/python_types/tutorial010.py b/docs_src/python_types/tutorial010_py39.py similarity index 100% rename from docs_src/python_types/tutorial010.py rename to docs_src/python_types/tutorial010_py39.py diff --git a/docs_src/python_types/tutorial011.py b/docs_src/python_types/tutorial011.py deleted file mode 100644 index 297a84db68..0000000000 --- a/docs_src/python_types/tutorial011.py +++ /dev/null @@ -1,23 +0,0 @@ -from datetime import datetime -from typing import List, Union - -from pydantic import BaseModel - - -class User(BaseModel): - id: int - name: str = "John Doe" - signup_ts: Union[datetime, None] = None - friends: List[int] = [] - - -external_data = { - "id": "123", - "signup_ts": "2017-06-01 12:22", - "friends": [1, "2", b"3"], -} -user = User(**external_data) -print(user) -# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] -print(user.id) -# > 123 diff --git a/docs_src/python_types/tutorial012.py b/docs_src/python_types/tutorial012_py39.py similarity index 100% rename from docs_src/python_types/tutorial012.py rename to docs_src/python_types/tutorial012_py39.py diff --git a/docs_src/python_types/tutorial013.py b/docs_src/python_types/tutorial013.py deleted file mode 100644 index 0ec7735199..0000000000 --- a/docs_src/python_types/tutorial013.py +++ /dev/null @@ -1,5 +0,0 @@ -from typing_extensions import Annotated - - -def say_hello(name: Annotated[str, "this is just metadata"]) -> str: - return f"Hello {name}" diff --git a/docs_src/query_param_models/tutorial001.py b/docs_src/query_param_models/tutorial001.py deleted file mode 100644 index 0c0ab315e8..0000000000 --- a/docs_src/query_param_models/tutorial001.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field -from typing_extensions import Literal - -app = FastAPI() - - -class FilterParams(BaseModel): - limit: int = Field(100, gt=0, le=100) - offset: int = Field(0, ge=0) - order_by: Literal["created_at", "updated_at"] = "created_at" - tags: List[str] = [] - - -@app.get("/items/") -async def read_items(filter_query: FilterParams = Query()): - return filter_query diff --git a/docs_src/query_param_models/tutorial001_an.py b/docs_src/query_param_models/tutorial001_an.py deleted file mode 100644 index 28375057c1..0000000000 --- a/docs_src/query_param_models/tutorial001_an.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field -from typing_extensions import Annotated, Literal - -app = FastAPI() - - -class FilterParams(BaseModel): - limit: int = Field(100, gt=0, le=100) - offset: int = Field(0, ge=0) - order_by: Literal["created_at", "updated_at"] = "created_at" - tags: List[str] = [] - - -@app.get("/items/") -async def read_items(filter_query: Annotated[FilterParams, Query()]): - return filter_query diff --git a/docs_src/query_param_models/tutorial001_an_py39.py b/docs_src/query_param_models/tutorial001_an_py39.py index ba690d3e3f..71427acae1 100644 --- a/docs_src/query_param_models/tutorial001_an_py39.py +++ b/docs_src/query_param_models/tutorial001_an_py39.py @@ -1,6 +1,7 @@ +from typing import Annotated, Literal + from fastapi import FastAPI, Query from pydantic import BaseModel, Field -from typing_extensions import Annotated, Literal app = FastAPI() diff --git a/docs_src/query_param_models/tutorial001_py39.py b/docs_src/query_param_models/tutorial001_py39.py index 54b52a054c..3ebf9f4d70 100644 --- a/docs_src/query_param_models/tutorial001_py39.py +++ b/docs_src/query_param_models/tutorial001_py39.py @@ -1,6 +1,7 @@ +from typing import Literal + from fastapi import FastAPI, Query from pydantic import BaseModel, Field -from typing_extensions import Literal app = FastAPI() diff --git a/docs_src/query_param_models/tutorial002.py b/docs_src/query_param_models/tutorial002.py deleted file mode 100644 index 1633bc4644..0000000000 --- a/docs_src/query_param_models/tutorial002.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field -from typing_extensions import Literal - -app = FastAPI() - - -class FilterParams(BaseModel): - model_config = {"extra": "forbid"} - - limit: int = Field(100, gt=0, le=100) - offset: int = Field(0, ge=0) - order_by: Literal["created_at", "updated_at"] = "created_at" - tags: List[str] = [] - - -@app.get("/items/") -async def read_items(filter_query: FilterParams = Query()): - return filter_query diff --git a/docs_src/query_param_models/tutorial002_an.py b/docs_src/query_param_models/tutorial002_an.py deleted file mode 100644 index 69705d4b4b..0000000000 --- a/docs_src/query_param_models/tutorial002_an.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field -from typing_extensions import Annotated, Literal - -app = FastAPI() - - -class FilterParams(BaseModel): - model_config = {"extra": "forbid"} - - limit: int = Field(100, gt=0, le=100) - offset: int = Field(0, ge=0) - order_by: Literal["created_at", "updated_at"] = "created_at" - tags: List[str] = [] - - -@app.get("/items/") -async def read_items(filter_query: Annotated[FilterParams, Query()]): - return filter_query diff --git a/docs_src/query_param_models/tutorial002_an_py39.py b/docs_src/query_param_models/tutorial002_an_py39.py index 2d4c1a62b5..9759565023 100644 --- a/docs_src/query_param_models/tutorial002_an_py39.py +++ b/docs_src/query_param_models/tutorial002_an_py39.py @@ -1,6 +1,7 @@ +from typing import Annotated, Literal + from fastapi import FastAPI, Query from pydantic import BaseModel, Field -from typing_extensions import Annotated, Literal app = FastAPI() diff --git a/docs_src/query_param_models/tutorial002_pv1.py b/docs_src/query_param_models/tutorial002_pv1.py deleted file mode 100644 index 71ccd961d3..0000000000 --- a/docs_src/query_param_models/tutorial002_pv1.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field -from typing_extensions import Literal - -app = FastAPI() - - -class FilterParams(BaseModel): - class Config: - extra = "forbid" - - limit: int = Field(100, gt=0, le=100) - offset: int = Field(0, ge=0) - order_by: Literal["created_at", "updated_at"] = "created_at" - tags: List[str] = [] - - -@app.get("/items/") -async def read_items(filter_query: FilterParams = Query()): - return filter_query diff --git a/docs_src/query_param_models/tutorial002_pv1_an.py b/docs_src/query_param_models/tutorial002_pv1_an.py deleted file mode 100644 index 1dd29157a4..0000000000 --- a/docs_src/query_param_models/tutorial002_pv1_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field -from typing_extensions import Annotated, Literal - -app = FastAPI() - - -class FilterParams(BaseModel): - class Config: - extra = "forbid" - - limit: int = Field(100, gt=0, le=100) - offset: int = Field(0, ge=0) - order_by: Literal["created_at", "updated_at"] = "created_at" - tags: List[str] = [] - - -@app.get("/items/") -async def read_items(filter_query: Annotated[FilterParams, Query()]): - return filter_query diff --git a/docs_src/query_param_models/tutorial002_pv1_an_py39.py b/docs_src/query_param_models/tutorial002_pv1_an_py39.py index 494fef11fc..d635aae88f 100644 --- a/docs_src/query_param_models/tutorial002_pv1_an_py39.py +++ b/docs_src/query_param_models/tutorial002_pv1_an_py39.py @@ -1,6 +1,7 @@ +from typing import Annotated, Literal + from fastapi import FastAPI, Query from pydantic import BaseModel, Field -from typing_extensions import Annotated, Literal app = FastAPI() diff --git a/docs_src/query_param_models/tutorial002_pv1_py39.py b/docs_src/query_param_models/tutorial002_pv1_py39.py index 7fa456a791..9ffdeefc06 100644 --- a/docs_src/query_param_models/tutorial002_pv1_py39.py +++ b/docs_src/query_param_models/tutorial002_pv1_py39.py @@ -1,6 +1,7 @@ +from typing import Literal + from fastapi import FastAPI, Query from pydantic import BaseModel, Field -from typing_extensions import Literal app = FastAPI() diff --git a/docs_src/query_param_models/tutorial002_py39.py b/docs_src/query_param_models/tutorial002_py39.py index f9bba028c2..6ec4184991 100644 --- a/docs_src/query_param_models/tutorial002_py39.py +++ b/docs_src/query_param_models/tutorial002_py39.py @@ -1,6 +1,7 @@ +from typing import Literal + from fastapi import FastAPI, Query from pydantic import BaseModel, Field -from typing_extensions import Literal app = FastAPI() diff --git a/docs_src/query_params/tutorial001.py b/docs_src/query_params/tutorial001_py39.py similarity index 100% rename from docs_src/query_params/tutorial001.py rename to docs_src/query_params/tutorial001_py39.py diff --git a/docs_src/query_params/tutorial002.py b/docs_src/query_params/tutorial002_py39.py similarity index 100% rename from docs_src/query_params/tutorial002.py rename to docs_src/query_params/tutorial002_py39.py diff --git a/docs_src/query_params/tutorial003.py b/docs_src/query_params/tutorial003_py39.py similarity index 100% rename from docs_src/query_params/tutorial003.py rename to docs_src/query_params/tutorial003_py39.py diff --git a/docs_src/query_params/tutorial004.py b/docs_src/query_params/tutorial004_py39.py similarity index 100% rename from docs_src/query_params/tutorial004.py rename to docs_src/query_params/tutorial004_py39.py diff --git a/docs_src/query_params/tutorial005.py b/docs_src/query_params/tutorial005_py39.py similarity index 100% rename from docs_src/query_params/tutorial005.py rename to docs_src/query_params/tutorial005_py39.py diff --git a/docs_src/query_params/tutorial006.py b/docs_src/query_params/tutorial006_py39.py similarity index 100% rename from docs_src/query_params/tutorial006.py rename to docs_src/query_params/tutorial006_py39.py diff --git a/docs_src/query_params/tutorial006b.py b/docs_src/query_params/tutorial006b.py deleted file mode 100644 index f0dbfe08fe..0000000000 --- a/docs_src/query_params/tutorial006b.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Union - -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_user_item( - item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None -): - item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit} - return item diff --git a/docs_src/query_params_str_validations/tutorial001.py b/docs_src/query_params_str_validations/tutorial001_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial001.py rename to docs_src/query_params_str_validations/tutorial001_py39.py diff --git a/docs_src/query_params_str_validations/tutorial002_an.py b/docs_src/query_params_str_validations/tutorial002_an_py39.py similarity index 81% rename from docs_src/query_params_str_validations/tutorial002_an.py rename to docs_src/query_params_str_validations/tutorial002_an_py39.py index cb1b38940c..2d8fc97985 100644 --- a/docs_src/query_params_str_validations/tutorial002_an.py +++ b/docs_src/query_params_str_validations/tutorial002_an_py39.py @@ -1,7 +1,6 @@ -from typing import Union +from typing import Annotated, Union from fastapi import FastAPI, Query -from typing_extensions import Annotated app = FastAPI() diff --git a/docs_src/query_params_str_validations/tutorial002.py b/docs_src/query_params_str_validations/tutorial002_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial002.py rename to docs_src/query_params_str_validations/tutorial002_py39.py diff --git a/docs_src/query_params_str_validations/tutorial003_an.py b/docs_src/query_params_str_validations/tutorial003_an.py deleted file mode 100644 index 0dd14086cf..0000000000 --- a/docs_src/query_params_str_validations/tutorial003_an.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - q: Annotated[Union[str, None], Query(min_length=3, max_length=50)] = None, -): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial003.py b/docs_src/query_params_str_validations/tutorial003_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial003.py rename to docs_src/query_params_str_validations/tutorial003_py39.py diff --git a/docs_src/query_params_str_validations/tutorial004_an.py b/docs_src/query_params_str_validations/tutorial004_an.py deleted file mode 100644 index c75d45d63e..0000000000 --- a/docs_src/query_params_str_validations/tutorial004_an.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - q: Annotated[ - Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$") - ] = None, -): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial004.py b/docs_src/query_params_str_validations/tutorial004_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial004.py rename to docs_src/query_params_str_validations/tutorial004_py39.py diff --git a/docs_src/query_params_str_validations/tutorial005_an.py b/docs_src/query_params_str_validations/tutorial005_an.py deleted file mode 100644 index 452d4d38d7..0000000000 --- a/docs_src/query_params_str_validations/tutorial005_an.py +++ /dev/null @@ -1,12 +0,0 @@ -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[str, Query(min_length=3)] = "fixedquery"): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial005.py b/docs_src/query_params_str_validations/tutorial005_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial005.py rename to docs_src/query_params_str_validations/tutorial005_py39.py diff --git a/docs_src/query_params_str_validations/tutorial006_an.py b/docs_src/query_params_str_validations/tutorial006_an.py deleted file mode 100644 index 559480d2bf..0000000000 --- a/docs_src/query_params_str_validations/tutorial006_an.py +++ /dev/null @@ -1,12 +0,0 @@ -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[str, Query(min_length=3)]): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial006.py b/docs_src/query_params_str_validations/tutorial006_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial006.py rename to docs_src/query_params_str_validations/tutorial006_py39.py diff --git a/docs_src/query_params_str_validations/tutorial006c_an.py b/docs_src/query_params_str_validations/tutorial006c_an.py deleted file mode 100644 index 55c4f4adca..0000000000 --- a/docs_src/query_params_str_validations/tutorial006c_an.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[Union[str, None], Query(min_length=3)]): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial006c.py b/docs_src/query_params_str_validations/tutorial006c_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial006c.py rename to docs_src/query_params_str_validations/tutorial006c_py39.py diff --git a/docs_src/query_params_str_validations/tutorial007_an.py b/docs_src/query_params_str_validations/tutorial007_an.py deleted file mode 100644 index 4b3c8de4b9..0000000000 --- a/docs_src/query_params_str_validations/tutorial007_an.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - q: Annotated[Union[str, None], Query(title="Query string", min_length=3)] = None, -): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial007.py b/docs_src/query_params_str_validations/tutorial007_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial007.py rename to docs_src/query_params_str_validations/tutorial007_py39.py diff --git a/docs_src/query_params_str_validations/tutorial008_an.py b/docs_src/query_params_str_validations/tutorial008_an.py deleted file mode 100644 index 01606a9203..0000000000 --- a/docs_src/query_params_str_validations/tutorial008_an.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - q: Annotated[ - Union[str, None], - Query( - title="Query string", - description="Query string for the items to search in the database that have a good match", - min_length=3, - ), - ] = None, -): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial008.py b/docs_src/query_params_str_validations/tutorial008_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial008.py rename to docs_src/query_params_str_validations/tutorial008_py39.py diff --git a/docs_src/query_params_str_validations/tutorial009_an.py b/docs_src/query_params_str_validations/tutorial009_an.py deleted file mode 100644 index 2894e2d51a..0000000000 --- a/docs_src/query_params_str_validations/tutorial009_an.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[Union[str, None], Query(alias="item-query")] = None): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial009.py b/docs_src/query_params_str_validations/tutorial009_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial009.py rename to docs_src/query_params_str_validations/tutorial009_py39.py diff --git a/docs_src/query_params_str_validations/tutorial010_an.py b/docs_src/query_params_str_validations/tutorial010_an.py deleted file mode 100644 index ed343230f4..0000000000 --- a/docs_src/query_params_str_validations/tutorial010_an.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - q: Annotated[ - Union[str, None], - Query( - alias="item-query", - title="Query string", - description="Query string for the items to search in the database that have a good match", - min_length=3, - max_length=50, - pattern="^fixedquery$", - deprecated=True, - ), - ] = None, -): - results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} - if q: - results.update({"q": q}) - return results diff --git a/docs_src/query_params_str_validations/tutorial010.py b/docs_src/query_params_str_validations/tutorial010_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial010.py rename to docs_src/query_params_str_validations/tutorial010_py39.py diff --git a/docs_src/query_params_str_validations/tutorial011.py b/docs_src/query_params_str_validations/tutorial011.py deleted file mode 100644 index 65bbce781a..0000000000 --- a/docs_src/query_params_str_validations/tutorial011.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Query - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Union[List[str], None] = Query(default=None)): - query_items = {"q": q} - return query_items diff --git a/docs_src/query_params_str_validations/tutorial011_an.py b/docs_src/query_params_str_validations/tutorial011_an.py deleted file mode 100644 index 8ed699337d..0000000000 --- a/docs_src/query_params_str_validations/tutorial011_an.py +++ /dev/null @@ -1,12 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[Union[List[str], None], Query()] = None): - query_items = {"q": q} - return query_items diff --git a/docs_src/query_params_str_validations/tutorial012.py b/docs_src/query_params_str_validations/tutorial012.py deleted file mode 100644 index e77d56974d..0000000000 --- a/docs_src/query_params_str_validations/tutorial012.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: List[str] = Query(default=["foo", "bar"])): - query_items = {"q": q} - return query_items diff --git a/docs_src/query_params_str_validations/tutorial012_an.py b/docs_src/query_params_str_validations/tutorial012_an.py deleted file mode 100644 index 261af250a1..0000000000 --- a/docs_src/query_params_str_validations/tutorial012_an.py +++ /dev/null @@ -1,12 +0,0 @@ -from typing import List - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[List[str], Query()] = ["foo", "bar"]): - query_items = {"q": q} - return query_items diff --git a/docs_src/query_params_str_validations/tutorial013_an.py b/docs_src/query_params_str_validations/tutorial013_an.py deleted file mode 100644 index f12a250559..0000000000 --- a/docs_src/query_params_str_validations/tutorial013_an.py +++ /dev/null @@ -1,10 +0,0 @@ -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items(q: Annotated[list, Query()] = []): - query_items = {"q": q} - return query_items diff --git a/docs_src/query_params_str_validations/tutorial013.py b/docs_src/query_params_str_validations/tutorial013_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial013.py rename to docs_src/query_params_str_validations/tutorial013_py39.py diff --git a/docs_src/query_params_str_validations/tutorial014_an.py b/docs_src/query_params_str_validations/tutorial014_an.py deleted file mode 100644 index 2eaa585407..0000000000 --- a/docs_src/query_params_str_validations/tutorial014_an.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, Query -from typing_extensions import Annotated - -app = FastAPI() - - -@app.get("/items/") -async def read_items( - hidden_query: Annotated[Union[str, None], Query(include_in_schema=False)] = None, -): - if hidden_query: - return {"hidden_query": hidden_query} - else: - return {"hidden_query": "Not found"} diff --git a/docs_src/query_params_str_validations/tutorial014.py b/docs_src/query_params_str_validations/tutorial014_py39.py similarity index 100% rename from docs_src/query_params_str_validations/tutorial014.py rename to docs_src/query_params_str_validations/tutorial014_py39.py diff --git a/docs_src/query_params_str_validations/tutorial015_an.py b/docs_src/query_params_str_validations/tutorial015_an.py deleted file mode 100644 index f2ec6db123..0000000000 --- a/docs_src/query_params_str_validations/tutorial015_an.py +++ /dev/null @@ -1,31 +0,0 @@ -import random -from typing import Union - -from fastapi import FastAPI -from pydantic import AfterValidator -from typing_extensions import Annotated - -app = FastAPI() - -data = { - "isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy", - "imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy", - "isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2", -} - - -def check_valid_id(id: str): - if not id.startswith(("isbn-", "imdb-")): - raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"') - return id - - -@app.get("/items/") -async def read_items( - id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None, -): - if id: - item = data.get(id) - else: - id, item = random.choice(list(data.items())) - return {"id": id, "name": item} diff --git a/docs_src/request_files/tutorial001_02_an.py b/docs_src/request_files/tutorial001_02_an.py deleted file mode 100644 index 5007fef159..0000000000 --- a/docs_src/request_files/tutorial001_02_an.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import Union - -from fastapi import FastAPI, File, UploadFile -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/files/") -async def create_file(file: Annotated[Union[bytes, None], File()] = None): - if not file: - return {"message": "No file sent"} - else: - return {"file_size": len(file)} - - -@app.post("/uploadfile/") -async def create_upload_file(file: Union[UploadFile, None] = None): - if not file: - return {"message": "No upload file sent"} - else: - return {"filename": file.filename} diff --git a/docs_src/request_files/tutorial001_02.py b/docs_src/request_files/tutorial001_02_py39.py similarity index 100% rename from docs_src/request_files/tutorial001_02.py rename to docs_src/request_files/tutorial001_02_py39.py diff --git a/docs_src/request_files/tutorial001_03_an.py b/docs_src/request_files/tutorial001_03_an.py deleted file mode 100644 index 8a6b0a2455..0000000000 --- a/docs_src/request_files/tutorial001_03_an.py +++ /dev/null @@ -1,16 +0,0 @@ -from fastapi import FastAPI, File, UploadFile -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/files/") -async def create_file(file: Annotated[bytes, File(description="A file read as bytes")]): - return {"file_size": len(file)} - - -@app.post("/uploadfile/") -async def create_upload_file( - file: Annotated[UploadFile, File(description="A file read as UploadFile")], -): - return {"filename": file.filename} diff --git a/docs_src/request_files/tutorial001_03.py b/docs_src/request_files/tutorial001_03_py39.py similarity index 100% rename from docs_src/request_files/tutorial001_03.py rename to docs_src/request_files/tutorial001_03_py39.py diff --git a/docs_src/request_files/tutorial001_an.py b/docs_src/request_files/tutorial001_an.py deleted file mode 100644 index ca2f76d5c6..0000000000 --- a/docs_src/request_files/tutorial001_an.py +++ /dev/null @@ -1,14 +0,0 @@ -from fastapi import FastAPI, File, UploadFile -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/files/") -async def create_file(file: Annotated[bytes, File()]): - return {"file_size": len(file)} - - -@app.post("/uploadfile/") -async def create_upload_file(file: UploadFile): - return {"filename": file.filename} diff --git a/docs_src/request_files/tutorial001.py b/docs_src/request_files/tutorial001_py39.py similarity index 100% rename from docs_src/request_files/tutorial001.py rename to docs_src/request_files/tutorial001_py39.py diff --git a/docs_src/request_files/tutorial002.py b/docs_src/request_files/tutorial002.py deleted file mode 100644 index b4d0acc68f..0000000000 --- a/docs_src/request_files/tutorial002.py +++ /dev/null @@ -1,33 +0,0 @@ -from typing import List - -from fastapi import FastAPI, File, UploadFile -from fastapi.responses import HTMLResponse - -app = FastAPI() - - -@app.post("/files/") -async def create_files(files: List[bytes] = File()): - return {"file_sizes": [len(file) for file in files]} - - -@app.post("/uploadfiles/") -async def create_upload_files(files: List[UploadFile]): - return {"filenames": [file.filename for file in files]} - - -@app.get("/") -async def main(): - content = """ - -
- - -
-
- - -
- - """ - return HTMLResponse(content=content) diff --git a/docs_src/request_files/tutorial002_an.py b/docs_src/request_files/tutorial002_an.py deleted file mode 100644 index eaa90da2b6..0000000000 --- a/docs_src/request_files/tutorial002_an.py +++ /dev/null @@ -1,34 +0,0 @@ -from typing import List - -from fastapi import FastAPI, File, UploadFile -from fastapi.responses import HTMLResponse -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/files/") -async def create_files(files: Annotated[List[bytes], File()]): - return {"file_sizes": [len(file) for file in files]} - - -@app.post("/uploadfiles/") -async def create_upload_files(files: List[UploadFile]): - return {"filenames": [file.filename for file in files]} - - -@app.get("/") -async def main(): - content = """ - -
- - -
-
- - -
- - """ - return HTMLResponse(content=content) diff --git a/docs_src/request_files/tutorial003.py b/docs_src/request_files/tutorial003.py deleted file mode 100644 index e3f805f605..0000000000 --- a/docs_src/request_files/tutorial003.py +++ /dev/null @@ -1,37 +0,0 @@ -from typing import List - -from fastapi import FastAPI, File, UploadFile -from fastapi.responses import HTMLResponse - -app = FastAPI() - - -@app.post("/files/") -async def create_files( - files: List[bytes] = File(description="Multiple files as bytes"), -): - return {"file_sizes": [len(file) for file in files]} - - -@app.post("/uploadfiles/") -async def create_upload_files( - files: List[UploadFile] = File(description="Multiple files as UploadFile"), -): - return {"filenames": [file.filename for file in files]} - - -@app.get("/") -async def main(): - content = """ - -
- - -
-
- - -
- - """ - return HTMLResponse(content=content) diff --git a/docs_src/request_files/tutorial003_an.py b/docs_src/request_files/tutorial003_an.py deleted file mode 100644 index 2238e3c94b..0000000000 --- a/docs_src/request_files/tutorial003_an.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import List - -from fastapi import FastAPI, File, UploadFile -from fastapi.responses import HTMLResponse -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/files/") -async def create_files( - files: Annotated[List[bytes], File(description="Multiple files as bytes")], -): - return {"file_sizes": [len(file) for file in files]} - - -@app.post("/uploadfiles/") -async def create_upload_files( - files: Annotated[ - List[UploadFile], File(description="Multiple files as UploadFile") - ], -): - return {"filenames": [file.filename for file in files]} - - -@app.get("/") -async def main(): - content = """ - -
- - -
-
- - -
- - """ - return HTMLResponse(content=content) diff --git a/docs_src/request_form_models/tutorial001_an.py b/docs_src/request_form_models/tutorial001_an.py deleted file mode 100644 index 30483d4455..0000000000 --- a/docs_src/request_form_models/tutorial001_an.py +++ /dev/null @@ -1,15 +0,0 @@ -from fastapi import FastAPI, Form -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class FormData(BaseModel): - username: str - password: str - - -@app.post("/login/") -async def login(data: Annotated[FormData, Form()]): - return data diff --git a/docs_src/request_form_models/tutorial001.py b/docs_src/request_form_models/tutorial001_py39.py similarity index 100% rename from docs_src/request_form_models/tutorial001.py rename to docs_src/request_form_models/tutorial001_py39.py diff --git a/docs_src/request_form_models/tutorial002_an.py b/docs_src/request_form_models/tutorial002_an.py deleted file mode 100644 index bcb0227959..0000000000 --- a/docs_src/request_form_models/tutorial002_an.py +++ /dev/null @@ -1,16 +0,0 @@ -from fastapi import FastAPI, Form -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class FormData(BaseModel): - username: str - password: str - model_config = {"extra": "forbid"} - - -@app.post("/login/") -async def login(data: Annotated[FormData, Form()]): - return data diff --git a/docs_src/request_form_models/tutorial002_pv1_an.py b/docs_src/request_form_models/tutorial002_pv1_an.py deleted file mode 100644 index fe9dbc344b..0000000000 --- a/docs_src/request_form_models/tutorial002_pv1_an.py +++ /dev/null @@ -1,18 +0,0 @@ -from fastapi import FastAPI, Form -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class FormData(BaseModel): - username: str - password: str - - class Config: - extra = "forbid" - - -@app.post("/login/") -async def login(data: Annotated[FormData, Form()]): - return data diff --git a/docs_src/request_form_models/tutorial002_pv1.py b/docs_src/request_form_models/tutorial002_pv1_py39.py similarity index 100% rename from docs_src/request_form_models/tutorial002_pv1.py rename to docs_src/request_form_models/tutorial002_pv1_py39.py diff --git a/docs_src/request_form_models/tutorial002.py b/docs_src/request_form_models/tutorial002_py39.py similarity index 100% rename from docs_src/request_form_models/tutorial002.py rename to docs_src/request_form_models/tutorial002_py39.py diff --git a/docs_src/request_forms/tutorial001_an.py b/docs_src/request_forms/tutorial001_an.py deleted file mode 100644 index 677fbf2db8..0000000000 --- a/docs_src/request_forms/tutorial001_an.py +++ /dev/null @@ -1,9 +0,0 @@ -from fastapi import FastAPI, Form -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/login/") -async def login(username: Annotated[str, Form()], password: Annotated[str, Form()]): - return {"username": username} diff --git a/docs_src/request_forms/tutorial001.py b/docs_src/request_forms/tutorial001_py39.py similarity index 100% rename from docs_src/request_forms/tutorial001.py rename to docs_src/request_forms/tutorial001_py39.py diff --git a/docs_src/request_forms_and_files/tutorial001_an.py b/docs_src/request_forms_and_files/tutorial001_an.py deleted file mode 100644 index 0ea285ac87..0000000000 --- a/docs_src/request_forms_and_files/tutorial001_an.py +++ /dev/null @@ -1,17 +0,0 @@ -from fastapi import FastAPI, File, Form, UploadFile -from typing_extensions import Annotated - -app = FastAPI() - - -@app.post("/files/") -async def create_file( - file: Annotated[bytes, File()], - fileb: Annotated[UploadFile, File()], - token: Annotated[str, Form()], -): - return { - "file_size": len(file), - "token": token, - "fileb_content_type": fileb.content_type, - } diff --git a/docs_src/request_forms_and_files/tutorial001.py b/docs_src/request_forms_and_files/tutorial001_py39.py similarity index 100% rename from docs_src/request_forms_and_files/tutorial001.py rename to docs_src/request_forms_and_files/tutorial001_py39.py diff --git a/docs_src/response_change_status_code/tutorial001.py b/docs_src/response_change_status_code/tutorial001_py39.py similarity index 100% rename from docs_src/response_change_status_code/tutorial001.py rename to docs_src/response_change_status_code/tutorial001_py39.py diff --git a/docs_src/response_cookies/tutorial001.py b/docs_src/response_cookies/tutorial001_py39.py similarity index 100% rename from docs_src/response_cookies/tutorial001.py rename to docs_src/response_cookies/tutorial001_py39.py diff --git a/docs_src/response_cookies/tutorial002.py b/docs_src/response_cookies/tutorial002_py39.py similarity index 100% rename from docs_src/response_cookies/tutorial002.py rename to docs_src/response_cookies/tutorial002_py39.py diff --git a/docs_src/response_directly/tutorial001.py b/docs_src/response_directly/tutorial001_py39.py similarity index 100% rename from docs_src/response_directly/tutorial001.py rename to docs_src/response_directly/tutorial001_py39.py diff --git a/docs_src/response_directly/tutorial002.py b/docs_src/response_directly/tutorial002_py39.py similarity index 100% rename from docs_src/response_directly/tutorial002.py rename to docs_src/response_directly/tutorial002_py39.py diff --git a/docs_src/response_headers/tutorial001.py b/docs_src/response_headers/tutorial001_py39.py similarity index 100% rename from docs_src/response_headers/tutorial001.py rename to docs_src/response_headers/tutorial001_py39.py diff --git a/docs_src/response_headers/tutorial002.py b/docs_src/response_headers/tutorial002_py39.py similarity index 100% rename from docs_src/response_headers/tutorial002.py rename to docs_src/response_headers/tutorial002_py39.py diff --git a/docs_src/response_model/tutorial001.py b/docs_src/response_model/tutorial001.py deleted file mode 100644 index fd1c902a52..0000000000 --- a/docs_src/response_model/tutorial001.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Any, List, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: List[str] = [] - - -@app.post("/items/", response_model=Item) -async def create_item(item: Item) -> Any: - return item - - -@app.get("/items/", response_model=List[Item]) -async def read_items() -> Any: - return [ - {"name": "Portal Gun", "price": 42.0}, - {"name": "Plumbus", "price": 32.0}, - ] diff --git a/docs_src/response_model/tutorial001_01.py b/docs_src/response_model/tutorial001_01.py deleted file mode 100644 index 98d30d540f..0000000000 --- a/docs_src/response_model/tutorial001_01.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - tags: List[str] = [] - - -@app.post("/items/") -async def create_item(item: Item) -> Item: - return item - - -@app.get("/items/") -async def read_items() -> List[Item]: - return [ - Item(name="Portal Gun", price=42.0), - Item(name="Plumbus", price=32.0), - ] diff --git a/docs_src/response_model/tutorial002.py b/docs_src/response_model/tutorial002_py39.py similarity index 100% rename from docs_src/response_model/tutorial002.py rename to docs_src/response_model/tutorial002_py39.py diff --git a/docs_src/response_model/tutorial003_01.py b/docs_src/response_model/tutorial003_01_py39.py similarity index 100% rename from docs_src/response_model/tutorial003_01.py rename to docs_src/response_model/tutorial003_01_py39.py diff --git a/docs_src/response_model/tutorial003_02.py b/docs_src/response_model/tutorial003_02_py39.py similarity index 100% rename from docs_src/response_model/tutorial003_02.py rename to docs_src/response_model/tutorial003_02_py39.py diff --git a/docs_src/response_model/tutorial003_03.py b/docs_src/response_model/tutorial003_03_py39.py similarity index 100% rename from docs_src/response_model/tutorial003_03.py rename to docs_src/response_model/tutorial003_03_py39.py diff --git a/docs_src/response_model/tutorial003_04.py b/docs_src/response_model/tutorial003_04_py39.py similarity index 100% rename from docs_src/response_model/tutorial003_04.py rename to docs_src/response_model/tutorial003_04_py39.py diff --git a/docs_src/response_model/tutorial003_05.py b/docs_src/response_model/tutorial003_05_py39.py similarity index 100% rename from docs_src/response_model/tutorial003_05.py rename to docs_src/response_model/tutorial003_05_py39.py diff --git a/docs_src/response_model/tutorial003.py b/docs_src/response_model/tutorial003_py39.py similarity index 100% rename from docs_src/response_model/tutorial003.py rename to docs_src/response_model/tutorial003_py39.py diff --git a/docs_src/response_model/tutorial004.py b/docs_src/response_model/tutorial004.py deleted file mode 100644 index 10b48039ae..0000000000 --- a/docs_src/response_model/tutorial004.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: float = 10.5 - tags: List[str] = [] - - -items = { - "foo": {"name": "Foo", "price": 50.2}, - "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, - "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, -} - - -@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True) -async def read_item(item_id: str): - return items[item_id] diff --git a/docs_src/response_model/tutorial005.py b/docs_src/response_model/tutorial005_py39.py similarity index 100% rename from docs_src/response_model/tutorial005.py rename to docs_src/response_model/tutorial005_py39.py diff --git a/docs_src/response_model/tutorial006.py b/docs_src/response_model/tutorial006_py39.py similarity index 100% rename from docs_src/response_model/tutorial006.py rename to docs_src/response_model/tutorial006_py39.py diff --git a/docs_src/response_status_code/tutorial001.py b/docs_src/response_status_code/tutorial001_py39.py similarity index 100% rename from docs_src/response_status_code/tutorial001.py rename to docs_src/response_status_code/tutorial001_py39.py diff --git a/docs_src/response_status_code/tutorial002.py b/docs_src/response_status_code/tutorial002_py39.py similarity index 100% rename from docs_src/response_status_code/tutorial002.py rename to docs_src/response_status_code/tutorial002_py39.py diff --git a/docs_src/schema_extra_example/tutorial001_pv1.py b/docs_src/schema_extra_example/tutorial001_pv1_py39.py similarity index 100% rename from docs_src/schema_extra_example/tutorial001_pv1.py rename to docs_src/schema_extra_example/tutorial001_pv1_py39.py diff --git a/docs_src/schema_extra_example/tutorial001.py b/docs_src/schema_extra_example/tutorial001_py39.py similarity index 100% rename from docs_src/schema_extra_example/tutorial001.py rename to docs_src/schema_extra_example/tutorial001_py39.py diff --git a/docs_src/schema_extra_example/tutorial002.py b/docs_src/schema_extra_example/tutorial002_py39.py similarity index 100% rename from docs_src/schema_extra_example/tutorial002.py rename to docs_src/schema_extra_example/tutorial002_py39.py diff --git a/docs_src/schema_extra_example/tutorial003_an.py b/docs_src/schema_extra_example/tutorial003_an.py deleted file mode 100644 index 23675aba14..0000000000 --- a/docs_src/schema_extra_example/tutorial003_an.py +++ /dev/null @@ -1,35 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -@app.put("/items/{item_id}") -async def update_item( - item_id: int, - item: Annotated[ - Item, - Body( - examples=[ - { - "name": "Foo", - "description": "A very nice Item", - "price": 35.4, - "tax": 3.2, - } - ], - ), - ], -): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/schema_extra_example/tutorial003.py b/docs_src/schema_extra_example/tutorial003_py39.py similarity index 100% rename from docs_src/schema_extra_example/tutorial003.py rename to docs_src/schema_extra_example/tutorial003_py39.py diff --git a/docs_src/schema_extra_example/tutorial004_an.py b/docs_src/schema_extra_example/tutorial004_an.py deleted file mode 100644 index e817302a22..0000000000 --- a/docs_src/schema_extra_example/tutorial004_an.py +++ /dev/null @@ -1,44 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -@app.put("/items/{item_id}") -async def update_item( - *, - item_id: int, - item: Annotated[ - Item, - Body( - examples=[ - { - "name": "Foo", - "description": "A very nice Item", - "price": 35.4, - "tax": 3.2, - }, - { - "name": "Bar", - "price": "35.4", - }, - { - "name": "Baz", - "price": "thirty five point four", - }, - ], - ), - ], -): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/schema_extra_example/tutorial004.py b/docs_src/schema_extra_example/tutorial004_py39.py similarity index 100% rename from docs_src/schema_extra_example/tutorial004.py rename to docs_src/schema_extra_example/tutorial004_py39.py diff --git a/docs_src/schema_extra_example/tutorial005_an.py b/docs_src/schema_extra_example/tutorial005_an.py deleted file mode 100644 index 4b2d9c662b..0000000000 --- a/docs_src/schema_extra_example/tutorial005_an.py +++ /dev/null @@ -1,55 +0,0 @@ -from typing import Union - -from fastapi import Body, FastAPI -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - price: float - tax: Union[float, None] = None - - -@app.put("/items/{item_id}") -async def update_item( - *, - item_id: int, - item: Annotated[ - Item, - Body( - openapi_examples={ - "normal": { - "summary": "A normal example", - "description": "A **normal** item works correctly.", - "value": { - "name": "Foo", - "description": "A very nice Item", - "price": 35.4, - "tax": 3.2, - }, - }, - "converted": { - "summary": "An example with converted data", - "description": "FastAPI can convert price `strings` to actual `numbers` automatically", - "value": { - "name": "Bar", - "price": "35.4", - }, - }, - "invalid": { - "summary": "Invalid data is rejected with an error", - "value": { - "name": "Baz", - "price": "thirty five point four", - }, - }, - }, - ), - ], -): - results = {"item_id": item_id, "item": item} - return results diff --git a/docs_src/schema_extra_example/tutorial005.py b/docs_src/schema_extra_example/tutorial005_py39.py similarity index 100% rename from docs_src/schema_extra_example/tutorial005.py rename to docs_src/schema_extra_example/tutorial005_py39.py diff --git a/docs_src/security/tutorial001_an.py b/docs_src/security/tutorial001_an.py deleted file mode 100644 index dac915b7ca..0000000000 --- a/docs_src/security/tutorial001_an.py +++ /dev/null @@ -1,12 +0,0 @@ -from fastapi import Depends, FastAPI -from fastapi.security import OAuth2PasswordBearer -from typing_extensions import Annotated - -app = FastAPI() - -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") - - -@app.get("/items/") -async def read_items(token: Annotated[str, Depends(oauth2_scheme)]): - return {"token": token} diff --git a/docs_src/security/tutorial001.py b/docs_src/security/tutorial001_py39.py similarity index 100% rename from docs_src/security/tutorial001.py rename to docs_src/security/tutorial001_py39.py diff --git a/docs_src/security/tutorial002_an.py b/docs_src/security/tutorial002_an.py deleted file mode 100644 index 291b3bf530..0000000000 --- a/docs_src/security/tutorial002_an.py +++ /dev/null @@ -1,33 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI -from fastapi.security import OAuth2PasswordBearer -from pydantic import BaseModel -from typing_extensions import Annotated - -app = FastAPI() - -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") - - -class User(BaseModel): - username: str - email: Union[str, None] = None - full_name: Union[str, None] = None - disabled: Union[bool, None] = None - - -def fake_decode_token(token): - return User( - username=token + "fakedecoded", email="john@example.com", full_name="John Doe" - ) - - -async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]): - user = fake_decode_token(token) - return user - - -@app.get("/users/me") -async def read_users_me(current_user: Annotated[User, Depends(get_current_user)]): - return current_user diff --git a/docs_src/security/tutorial002.py b/docs_src/security/tutorial002_py39.py similarity index 100% rename from docs_src/security/tutorial002.py rename to docs_src/security/tutorial002_py39.py diff --git a/docs_src/security/tutorial003_an.py b/docs_src/security/tutorial003_an.py deleted file mode 100644 index 1b7056a209..0000000000 --- a/docs_src/security/tutorial003_an.py +++ /dev/null @@ -1,95 +0,0 @@ -from typing import Union - -from fastapi import Depends, FastAPI, HTTPException, status -from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from pydantic import BaseModel -from typing_extensions import Annotated - -fake_users_db = { - "johndoe": { - "username": "johndoe", - "full_name": "John Doe", - "email": "johndoe@example.com", - "hashed_password": "fakehashedsecret", - "disabled": False, - }, - "alice": { - "username": "alice", - "full_name": "Alice Wonderson", - "email": "alice@example.com", - "hashed_password": "fakehashedsecret2", - "disabled": True, - }, -} - -app = FastAPI() - - -def fake_hash_password(password: str): - return "fakehashed" + password - - -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") - - -class User(BaseModel): - username: str - email: Union[str, None] = None - full_name: Union[str, None] = None - disabled: Union[bool, None] = None - - -class UserInDB(User): - hashed_password: str - - -def get_user(db, username: str): - if username in db: - user_dict = db[username] - return UserInDB(**user_dict) - - -def fake_decode_token(token): - # This doesn't provide any security at all - # Check the next version - user = get_user(fake_users_db, token) - return user - - -async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]): - user = fake_decode_token(token) - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Not authenticated", - headers={"WWW-Authenticate": "Bearer"}, - ) - return user - - -async def get_current_active_user( - current_user: Annotated[User, Depends(get_current_user)], -): - if current_user.disabled: - raise HTTPException(status_code=400, detail="Inactive user") - return current_user - - -@app.post("/token") -async def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]): - user_dict = fake_users_db.get(form_data.username) - if not user_dict: - raise HTTPException(status_code=400, detail="Incorrect username or password") - user = UserInDB(**user_dict) - hashed_password = fake_hash_password(form_data.password) - if not hashed_password == user.hashed_password: - raise HTTPException(status_code=400, detail="Incorrect username or password") - - return {"access_token": user.username, "token_type": "bearer"} - - -@app.get("/users/me") -async def read_users_me( - current_user: Annotated[User, Depends(get_current_active_user)], -): - return current_user diff --git a/docs_src/security/tutorial003.py b/docs_src/security/tutorial003_py39.py similarity index 100% rename from docs_src/security/tutorial003.py rename to docs_src/security/tutorial003_py39.py diff --git a/docs_src/security/tutorial004_an.py b/docs_src/security/tutorial004_an.py deleted file mode 100644 index 018234e300..0000000000 --- a/docs_src/security/tutorial004_an.py +++ /dev/null @@ -1,148 +0,0 @@ -from datetime import datetime, timedelta, timezone -from typing import Union - -import jwt -from fastapi import Depends, FastAPI, HTTPException, status -from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from jwt.exceptions import InvalidTokenError -from pwdlib import PasswordHash -from pydantic import BaseModel -from typing_extensions import Annotated - -# to get a string like this run: -# openssl rand -hex 32 -SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" -ALGORITHM = "HS256" -ACCESS_TOKEN_EXPIRE_MINUTES = 30 - - -fake_users_db = { - "johndoe": { - "username": "johndoe", - "full_name": "John Doe", - "email": "johndoe@example.com", - "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", - "disabled": False, - } -} - - -class Token(BaseModel): - access_token: str - token_type: str - - -class TokenData(BaseModel): - username: Union[str, None] = None - - -class User(BaseModel): - username: str - email: Union[str, None] = None - full_name: Union[str, None] = None - disabled: Union[bool, None] = None - - -class UserInDB(User): - hashed_password: str - - -password_hash = PasswordHash.recommended() - -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") - -app = FastAPI() - - -def verify_password(plain_password, hashed_password): - return password_hash.verify(plain_password, hashed_password) - - -def get_password_hash(password): - return password_hash.hash(password) - - -def get_user(db, username: str): - if username in db: - user_dict = db[username] - return UserInDB(**user_dict) - - -def authenticate_user(fake_db, username: str, password: str): - user = get_user(fake_db, username) - if not user: - return False - if not verify_password(password, user.hashed_password): - return False - return user - - -def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None): - to_encode = data.copy() - if expires_delta: - expire = datetime.now(timezone.utc) + expires_delta - else: - expire = datetime.now(timezone.utc) + timedelta(minutes=15) - to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) - return encoded_jwt - - -async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]): - credentials_exception = HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Could not validate credentials", - headers={"WWW-Authenticate": "Bearer"}, - ) - try: - payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) - username = payload.get("sub") - if username is None: - raise credentials_exception - token_data = TokenData(username=username) - except InvalidTokenError: - raise credentials_exception - user = get_user(fake_users_db, username=token_data.username) - if user is None: - raise credentials_exception - return user - - -async def get_current_active_user( - current_user: Annotated[User, Depends(get_current_user)], -): - if current_user.disabled: - raise HTTPException(status_code=400, detail="Inactive user") - return current_user - - -@app.post("/token") -async def login_for_access_token( - form_data: Annotated[OAuth2PasswordRequestForm, Depends()], -) -> Token: - user = authenticate_user(fake_users_db, form_data.username, form_data.password) - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Incorrect username or password", - headers={"WWW-Authenticate": "Bearer"}, - ) - access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.username}, expires_delta=access_token_expires - ) - return Token(access_token=access_token, token_type="bearer") - - -@app.get("/users/me/", response_model=User) -async def read_users_me( - current_user: Annotated[User, Depends(get_current_active_user)], -): - return current_user - - -@app.get("/users/me/items/") -async def read_own_items( - current_user: Annotated[User, Depends(get_current_active_user)], -): - return [{"item_id": "Foo", "owner": current_user.username}] diff --git a/docs_src/security/tutorial004.py b/docs_src/security/tutorial004_py39.py similarity index 100% rename from docs_src/security/tutorial004.py rename to docs_src/security/tutorial004_py39.py diff --git a/docs_src/security/tutorial005.py b/docs_src/security/tutorial005.py deleted file mode 100644 index fdd73bcd8a..0000000000 --- a/docs_src/security/tutorial005.py +++ /dev/null @@ -1,177 +0,0 @@ -from datetime import datetime, timedelta, timezone -from typing import List, Union - -import jwt -from fastapi import Depends, FastAPI, HTTPException, Security, status -from fastapi.security import ( - OAuth2PasswordBearer, - OAuth2PasswordRequestForm, - SecurityScopes, -) -from jwt.exceptions import InvalidTokenError -from pwdlib import PasswordHash -from pydantic import BaseModel, ValidationError - -# to get a string like this run: -# openssl rand -hex 32 -SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" -ALGORITHM = "HS256" -ACCESS_TOKEN_EXPIRE_MINUTES = 30 - - -fake_users_db = { - "johndoe": { - "username": "johndoe", - "full_name": "John Doe", - "email": "johndoe@example.com", - "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", - "disabled": False, - }, - "alice": { - "username": "alice", - "full_name": "Alice Chains", - "email": "alicechains@example.com", - "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", - "disabled": True, - }, -} - - -class Token(BaseModel): - access_token: str - token_type: str - - -class TokenData(BaseModel): - username: Union[str, None] = None - scopes: List[str] = [] - - -class User(BaseModel): - username: str - email: Union[str, None] = None - full_name: Union[str, None] = None - disabled: Union[bool, None] = None - - -class UserInDB(User): - hashed_password: str - - -password_hash = PasswordHash.recommended() - -oauth2_scheme = OAuth2PasswordBearer( - tokenUrl="token", - scopes={"me": "Read information about the current user.", "items": "Read items."}, -) - -app = FastAPI() - - -def verify_password(plain_password, hashed_password): - return password_hash.verify(plain_password, hashed_password) - - -def get_password_hash(password): - return password_hash.hash(password) - - -def get_user(db, username: str): - if username in db: - user_dict = db[username] - return UserInDB(**user_dict) - - -def authenticate_user(fake_db, username: str, password: str): - user = get_user(fake_db, username) - if not user: - return False - if not verify_password(password, user.hashed_password): - return False - return user - - -def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None): - to_encode = data.copy() - if expires_delta: - expire = datetime.now(timezone.utc) + expires_delta - else: - expire = datetime.now(timezone.utc) + timedelta(minutes=15) - to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) - return encoded_jwt - - -async def get_current_user( - security_scopes: SecurityScopes, token: str = Depends(oauth2_scheme) -): - if security_scopes.scopes: - authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' - else: - authenticate_value = "Bearer" - credentials_exception = HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Could not validate credentials", - headers={"WWW-Authenticate": authenticate_value}, - ) - try: - payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) - username: str = payload.get("sub") - if username is None: - raise credentials_exception - scope: str = payload.get("scope", "") - token_scopes = scope.split(" ") - token_data = TokenData(scopes=token_scopes, username=username) - except (InvalidTokenError, ValidationError): - raise credentials_exception - user = get_user(fake_users_db, username=token_data.username) - if user is None: - raise credentials_exception - for scope in security_scopes.scopes: - if scope not in token_data.scopes: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Not enough permissions", - headers={"WWW-Authenticate": authenticate_value}, - ) - return user - - -async def get_current_active_user( - current_user: User = Security(get_current_user, scopes=["me"]), -): - if current_user.disabled: - raise HTTPException(status_code=400, detail="Inactive user") - return current_user - - -@app.post("/token") -async def login_for_access_token( - form_data: OAuth2PasswordRequestForm = Depends(), -) -> Token: - user = authenticate_user(fake_users_db, form_data.username, form_data.password) - if not user: - raise HTTPException(status_code=400, detail="Incorrect username or password") - access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.username, "scope": " ".join(form_data.scopes)}, - expires_delta=access_token_expires, - ) - return Token(access_token=access_token, token_type="bearer") - - -@app.get("/users/me/", response_model=User) -async def read_users_me(current_user: User = Depends(get_current_active_user)): - return current_user - - -@app.get("/users/me/items/") -async def read_own_items( - current_user: User = Security(get_current_active_user, scopes=["items"]), -): - return [{"item_id": "Foo", "owner": current_user.username}] - - -@app.get("/status/") -async def read_system_status(current_user: User = Depends(get_current_user)): - return {"status": "ok"} diff --git a/docs_src/security/tutorial005_an.py b/docs_src/security/tutorial005_an.py deleted file mode 100644 index e1d7b4f62a..0000000000 --- a/docs_src/security/tutorial005_an.py +++ /dev/null @@ -1,180 +0,0 @@ -from datetime import datetime, timedelta, timezone -from typing import List, Union - -import jwt -from fastapi import Depends, FastAPI, HTTPException, Security, status -from fastapi.security import ( - OAuth2PasswordBearer, - OAuth2PasswordRequestForm, - SecurityScopes, -) -from jwt.exceptions import InvalidTokenError -from pwdlib import PasswordHash -from pydantic import BaseModel, ValidationError -from typing_extensions import Annotated - -# to get a string like this run: -# openssl rand -hex 32 -SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" -ALGORITHM = "HS256" -ACCESS_TOKEN_EXPIRE_MINUTES = 30 - - -fake_users_db = { - "johndoe": { - "username": "johndoe", - "full_name": "John Doe", - "email": "johndoe@example.com", - "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc", - "disabled": False, - }, - "alice": { - "username": "alice", - "full_name": "Alice Chains", - "email": "alicechains@example.com", - "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE", - "disabled": True, - }, -} - - -class Token(BaseModel): - access_token: str - token_type: str - - -class TokenData(BaseModel): - username: Union[str, None] = None - scopes: List[str] = [] - - -class User(BaseModel): - username: str - email: Union[str, None] = None - full_name: Union[str, None] = None - disabled: Union[bool, None] = None - - -class UserInDB(User): - hashed_password: str - - -password_hash = PasswordHash.recommended() - -oauth2_scheme = OAuth2PasswordBearer( - tokenUrl="token", - scopes={"me": "Read information about the current user.", "items": "Read items."}, -) - -app = FastAPI() - - -def verify_password(plain_password, hashed_password): - return password_hash.verify(plain_password, hashed_password) - - -def get_password_hash(password): - return password_hash.hash(password) - - -def get_user(db, username: str): - if username in db: - user_dict = db[username] - return UserInDB(**user_dict) - - -def authenticate_user(fake_db, username: str, password: str): - user = get_user(fake_db, username) - if not user: - return False - if not verify_password(password, user.hashed_password): - return False - return user - - -def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None): - to_encode = data.copy() - if expires_delta: - expire = datetime.now(timezone.utc) + expires_delta - else: - expire = datetime.now(timezone.utc) + timedelta(minutes=15) - to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) - return encoded_jwt - - -async def get_current_user( - security_scopes: SecurityScopes, token: Annotated[str, Depends(oauth2_scheme)] -): - if security_scopes.scopes: - authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' - else: - authenticate_value = "Bearer" - credentials_exception = HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Could not validate credentials", - headers={"WWW-Authenticate": authenticate_value}, - ) - try: - payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) - username = payload.get("sub") - if username is None: - raise credentials_exception - scope: str = payload.get("scope", "") - token_scopes = scope.split(" ") - token_data = TokenData(scopes=token_scopes, username=username) - except (InvalidTokenError, ValidationError): - raise credentials_exception - user = get_user(fake_users_db, username=token_data.username) - if user is None: - raise credentials_exception - for scope in security_scopes.scopes: - if scope not in token_data.scopes: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Not enough permissions", - headers={"WWW-Authenticate": authenticate_value}, - ) - return user - - -async def get_current_active_user( - current_user: Annotated[User, Security(get_current_user, scopes=["me"])], -): - if current_user.disabled: - raise HTTPException(status_code=400, detail="Inactive user") - return current_user - - -@app.post("/token") -async def login_for_access_token( - form_data: Annotated[OAuth2PasswordRequestForm, Depends()], -) -> Token: - user = authenticate_user(fake_users_db, form_data.username, form_data.password) - if not user: - raise HTTPException(status_code=400, detail="Incorrect username or password") - access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.username, "scope": " ".join(form_data.scopes)}, - expires_delta=access_token_expires, - ) - return Token(access_token=access_token, token_type="bearer") - - -@app.get("/users/me/", response_model=User) -async def read_users_me( - current_user: Annotated[User, Depends(get_current_active_user)], -): - return current_user - - -@app.get("/users/me/items/") -async def read_own_items( - current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])], -): - return [{"item_id": "Foo", "owner": current_user.username}] - - -@app.get("/status/") -async def read_system_status(current_user: Annotated[User, Depends(get_current_user)]): - return {"status": "ok"} diff --git a/docs_src/security/tutorial006_an.py b/docs_src/security/tutorial006_an.py deleted file mode 100644 index 985e4b2ad2..0000000000 --- a/docs_src/security/tutorial006_an.py +++ /dev/null @@ -1,12 +0,0 @@ -from fastapi import Depends, FastAPI -from fastapi.security import HTTPBasic, HTTPBasicCredentials -from typing_extensions import Annotated - -app = FastAPI() - -security = HTTPBasic() - - -@app.get("/users/me") -def read_current_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]): - return {"username": credentials.username, "password": credentials.password} diff --git a/docs_src/security/tutorial006.py b/docs_src/security/tutorial006_py39.py similarity index 100% rename from docs_src/security/tutorial006.py rename to docs_src/security/tutorial006_py39.py diff --git a/docs_src/security/tutorial007_an.py b/docs_src/security/tutorial007_an.py deleted file mode 100644 index 0d211dfde5..0000000000 --- a/docs_src/security/tutorial007_an.py +++ /dev/null @@ -1,36 +0,0 @@ -import secrets - -from fastapi import Depends, FastAPI, HTTPException, status -from fastapi.security import HTTPBasic, HTTPBasicCredentials -from typing_extensions import Annotated - -app = FastAPI() - -security = HTTPBasic() - - -def get_current_username( - credentials: Annotated[HTTPBasicCredentials, Depends(security)], -): - current_username_bytes = credentials.username.encode("utf8") - correct_username_bytes = b"stanleyjobson" - is_correct_username = secrets.compare_digest( - current_username_bytes, correct_username_bytes - ) - current_password_bytes = credentials.password.encode("utf8") - correct_password_bytes = b"swordfish" - is_correct_password = secrets.compare_digest( - current_password_bytes, correct_password_bytes - ) - if not (is_correct_username and is_correct_password): - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Incorrect username or password", - headers={"WWW-Authenticate": "Basic"}, - ) - return credentials.username - - -@app.get("/users/me") -def read_current_user(username: Annotated[str, Depends(get_current_username)]): - return {"username": username} diff --git a/docs_src/security/tutorial007.py b/docs_src/security/tutorial007_py39.py similarity index 100% rename from docs_src/security/tutorial007.py rename to docs_src/security/tutorial007_py39.py diff --git a/docs_src/separate_openapi_schemas/tutorial001.py b/docs_src/separate_openapi_schemas/tutorial001.py deleted file mode 100644 index 415eef8e28..0000000000 --- a/docs_src/separate_openapi_schemas/tutorial001.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from pydantic import BaseModel - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - - -app = FastAPI() - - -@app.post("/items/") -def create_item(item: Item): - return item - - -@app.get("/items/") -def read_items() -> List[Item]: - return [ - Item( - name="Portal Gun", - description="Device to travel through the multi-rick-verse", - ), - Item(name="Plumbus"), - ] diff --git a/docs_src/separate_openapi_schemas/tutorial002.py b/docs_src/separate_openapi_schemas/tutorial002.py deleted file mode 100644 index 7df93783b9..0000000000 --- a/docs_src/separate_openapi_schemas/tutorial002.py +++ /dev/null @@ -1,28 +0,0 @@ -from typing import List, Union - -from fastapi import FastAPI -from pydantic import BaseModel - - -class Item(BaseModel): - name: str - description: Union[str, None] = None - - -app = FastAPI(separate_input_output_schemas=False) - - -@app.post("/items/") -def create_item(item: Item): - return item - - -@app.get("/items/") -def read_items() -> List[Item]: - return [ - Item( - name="Portal Gun", - description="Device to travel through the multi-rick-verse", - ), - Item(name="Plumbus"), - ] diff --git a/docs_src/bigger_applications/app_an/internal/__init__.py b/docs_src/settings/app01_py39/__init__.py similarity index 100% rename from docs_src/bigger_applications/app_an/internal/__init__.py rename to docs_src/settings/app01_py39/__init__.py diff --git a/docs_src/settings/app01/config.py b/docs_src/settings/app01_py39/config.py similarity index 100% rename from docs_src/settings/app01/config.py rename to docs_src/settings/app01_py39/config.py diff --git a/docs_src/settings/app01/main.py b/docs_src/settings/app01_py39/main.py similarity index 100% rename from docs_src/settings/app01/main.py rename to docs_src/settings/app01_py39/main.py diff --git a/docs_src/settings/app02/__init__.py b/docs_src/settings/app02/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs_src/settings/app02_an/__init__.py b/docs_src/settings/app02_an/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs_src/settings/app02_an/config.py b/docs_src/settings/app02_an/config.py deleted file mode 100644 index e17b5035dc..0000000000 --- a/docs_src/settings/app02_an/config.py +++ /dev/null @@ -1,7 +0,0 @@ -from pydantic_settings import BaseSettings - - -class Settings(BaseSettings): - app_name: str = "Awesome API" - admin_email: str - items_per_user: int = 50 diff --git a/docs_src/settings/app02_an/main.py b/docs_src/settings/app02_an/main.py deleted file mode 100644 index 3a578cc338..0000000000 --- a/docs_src/settings/app02_an/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from functools import lru_cache - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -from .config import Settings - -app = FastAPI() - - -@lru_cache -def get_settings(): - return Settings() - - -@app.get("/info") -async def info(settings: Annotated[Settings, Depends(get_settings)]): - return { - "app_name": settings.app_name, - "admin_email": settings.admin_email, - "items_per_user": settings.items_per_user, - } diff --git a/docs_src/settings/app02_an/test_main.py b/docs_src/settings/app02_an/test_main.py deleted file mode 100644 index 7a04d7e8ee..0000000000 --- a/docs_src/settings/app02_an/test_main.py +++ /dev/null @@ -1,23 +0,0 @@ -from fastapi.testclient import TestClient - -from .config import Settings -from .main import app, get_settings - -client = TestClient(app) - - -def get_settings_override(): - return Settings(admin_email="testing_admin@example.com") - - -app.dependency_overrides[get_settings] = get_settings_override - - -def test_app(): - response = client.get("/info") - data = response.json() - assert data == { - "app_name": "Awesome API", - "admin_email": "testing_admin@example.com", - "items_per_user": 50, - } diff --git a/docs_src/bigger_applications/app_an/routers/__init__.py b/docs_src/settings/app02_py39/__init__.py similarity index 100% rename from docs_src/bigger_applications/app_an/routers/__init__.py rename to docs_src/settings/app02_py39/__init__.py diff --git a/docs_src/settings/app02/config.py b/docs_src/settings/app02_py39/config.py similarity index 100% rename from docs_src/settings/app02/config.py rename to docs_src/settings/app02_py39/config.py diff --git a/docs_src/settings/app02/main.py b/docs_src/settings/app02_py39/main.py similarity index 100% rename from docs_src/settings/app02/main.py rename to docs_src/settings/app02_py39/main.py diff --git a/docs_src/settings/app02/test_main.py b/docs_src/settings/app02_py39/test_main.py similarity index 100% rename from docs_src/settings/app02/test_main.py rename to docs_src/settings/app02_py39/test_main.py diff --git a/docs_src/settings/app03/__init__.py b/docs_src/settings/app03/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs_src/settings/app03_an/__init__.py b/docs_src/settings/app03_an/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs_src/settings/app03_an/config.py b/docs_src/settings/app03_an/config.py deleted file mode 100644 index 08f8f88c28..0000000000 --- a/docs_src/settings/app03_an/config.py +++ /dev/null @@ -1,9 +0,0 @@ -from pydantic_settings import BaseSettings, SettingsConfigDict - - -class Settings(BaseSettings): - app_name: str = "Awesome API" - admin_email: str - items_per_user: int = 50 - - model_config = SettingsConfigDict(env_file=".env") diff --git a/docs_src/settings/app03_an/config_pv1.py b/docs_src/settings/app03_an/config_pv1.py deleted file mode 100644 index e1c3ee3006..0000000000 --- a/docs_src/settings/app03_an/config_pv1.py +++ /dev/null @@ -1,10 +0,0 @@ -from pydantic import BaseSettings - - -class Settings(BaseSettings): - app_name: str = "Awesome API" - admin_email: str - items_per_user: int = 50 - - class Config: - env_file = ".env" diff --git a/docs_src/settings/app03_an/main.py b/docs_src/settings/app03_an/main.py deleted file mode 100644 index 62f3476396..0000000000 --- a/docs_src/settings/app03_an/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from functools import lru_cache - -from fastapi import Depends, FastAPI -from typing_extensions import Annotated - -from . import config - -app = FastAPI() - - -@lru_cache -def get_settings(): - return config.Settings() - - -@app.get("/info") -async def info(settings: Annotated[config.Settings, Depends(get_settings)]): - return { - "app_name": settings.app_name, - "admin_email": settings.admin_email, - "items_per_user": settings.items_per_user, - } diff --git a/docs_src/settings/app01/__init__.py b/docs_src/settings/app03_py39/__init__.py similarity index 100% rename from docs_src/settings/app01/__init__.py rename to docs_src/settings/app03_py39/__init__.py diff --git a/docs_src/settings/app03/config.py b/docs_src/settings/app03_py39/config.py similarity index 100% rename from docs_src/settings/app03/config.py rename to docs_src/settings/app03_py39/config.py diff --git a/docs_src/settings/app03/config_pv1.py b/docs_src/settings/app03_py39/config_pv1.py similarity index 100% rename from docs_src/settings/app03/config_pv1.py rename to docs_src/settings/app03_py39/config_pv1.py diff --git a/docs_src/settings/app03/main.py b/docs_src/settings/app03_py39/main.py similarity index 100% rename from docs_src/settings/app03/main.py rename to docs_src/settings/app03_py39/main.py diff --git a/docs_src/settings/tutorial001_pv1.py b/docs_src/settings/tutorial001_pv1_py39.py similarity index 100% rename from docs_src/settings/tutorial001_pv1.py rename to docs_src/settings/tutorial001_pv1_py39.py diff --git a/docs_src/settings/tutorial001.py b/docs_src/settings/tutorial001_py39.py similarity index 100% rename from docs_src/settings/tutorial001.py rename to docs_src/settings/tutorial001_py39.py diff --git a/docs_src/sql_databases/tutorial001.py b/docs_src/sql_databases/tutorial001.py deleted file mode 100644 index be86ec0eeb..0000000000 --- a/docs_src/sql_databases/tutorial001.py +++ /dev/null @@ -1,71 +0,0 @@ -from typing import List, Union - -from fastapi import Depends, FastAPI, HTTPException, Query -from sqlmodel import Field, Session, SQLModel, create_engine, select - - -class Hero(SQLModel, table=True): - id: Union[int, None] = Field(default=None, primary_key=True) - name: str = Field(index=True) - age: Union[int, None] = Field(default=None, index=True) - secret_name: str - - -sqlite_file_name = "database.db" -sqlite_url = f"sqlite:///{sqlite_file_name}" - -connect_args = {"check_same_thread": False} -engine = create_engine(sqlite_url, connect_args=connect_args) - - -def create_db_and_tables(): - SQLModel.metadata.create_all(engine) - - -def get_session(): - with Session(engine) as session: - yield session - - -app = FastAPI() - - -@app.on_event("startup") -def on_startup(): - create_db_and_tables() - - -@app.post("/heroes/") -def create_hero(hero: Hero, session: Session = Depends(get_session)) -> Hero: - session.add(hero) - session.commit() - session.refresh(hero) - return hero - - -@app.get("/heroes/") -def read_heroes( - session: Session = Depends(get_session), - offset: int = 0, - limit: int = Query(default=100, le=100), -) -> List[Hero]: - heroes = session.exec(select(Hero).offset(offset).limit(limit)).all() - return heroes - - -@app.get("/heroes/{hero_id}") -def read_hero(hero_id: int, session: Session = Depends(get_session)) -> Hero: - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - return hero - - -@app.delete("/heroes/{hero_id}") -def delete_hero(hero_id: int, session: Session = Depends(get_session)): - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - session.delete(hero) - session.commit() - return {"ok": True} diff --git a/docs_src/sql_databases/tutorial001_an.py b/docs_src/sql_databases/tutorial001_an.py deleted file mode 100644 index 8c000d31c7..0000000000 --- a/docs_src/sql_databases/tutorial001_an.py +++ /dev/null @@ -1,74 +0,0 @@ -from typing import List, Union - -from fastapi import Depends, FastAPI, HTTPException, Query -from sqlmodel import Field, Session, SQLModel, create_engine, select -from typing_extensions import Annotated - - -class Hero(SQLModel, table=True): - id: Union[int, None] = Field(default=None, primary_key=True) - name: str = Field(index=True) - age: Union[int, None] = Field(default=None, index=True) - secret_name: str - - -sqlite_file_name = "database.db" -sqlite_url = f"sqlite:///{sqlite_file_name}" - -connect_args = {"check_same_thread": False} -engine = create_engine(sqlite_url, connect_args=connect_args) - - -def create_db_and_tables(): - SQLModel.metadata.create_all(engine) - - -def get_session(): - with Session(engine) as session: - yield session - - -SessionDep = Annotated[Session, Depends(get_session)] - -app = FastAPI() - - -@app.on_event("startup") -def on_startup(): - create_db_and_tables() - - -@app.post("/heroes/") -def create_hero(hero: Hero, session: SessionDep) -> Hero: - session.add(hero) - session.commit() - session.refresh(hero) - return hero - - -@app.get("/heroes/") -def read_heroes( - session: SessionDep, - offset: int = 0, - limit: Annotated[int, Query(le=100)] = 100, -) -> List[Hero]: - heroes = session.exec(select(Hero).offset(offset).limit(limit)).all() - return heroes - - -@app.get("/heroes/{hero_id}") -def read_hero(hero_id: int, session: SessionDep) -> Hero: - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - return hero - - -@app.delete("/heroes/{hero_id}") -def delete_hero(hero_id: int, session: SessionDep): - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - session.delete(hero) - session.commit() - return {"ok": True} diff --git a/docs_src/sql_databases/tutorial002.py b/docs_src/sql_databases/tutorial002.py deleted file mode 100644 index 4350d19c61..0000000000 --- a/docs_src/sql_databases/tutorial002.py +++ /dev/null @@ -1,104 +0,0 @@ -from typing import List, Union - -from fastapi import Depends, FastAPI, HTTPException, Query -from sqlmodel import Field, Session, SQLModel, create_engine, select - - -class HeroBase(SQLModel): - name: str = Field(index=True) - age: Union[int, None] = Field(default=None, index=True) - - -class Hero(HeroBase, table=True): - id: Union[int, None] = Field(default=None, primary_key=True) - secret_name: str - - -class HeroPublic(HeroBase): - id: int - - -class HeroCreate(HeroBase): - secret_name: str - - -class HeroUpdate(HeroBase): - name: Union[str, None] = None - age: Union[int, None] = None - secret_name: Union[str, None] = None - - -sqlite_file_name = "database.db" -sqlite_url = f"sqlite:///{sqlite_file_name}" - -connect_args = {"check_same_thread": False} -engine = create_engine(sqlite_url, connect_args=connect_args) - - -def create_db_and_tables(): - SQLModel.metadata.create_all(engine) - - -def get_session(): - with Session(engine) as session: - yield session - - -app = FastAPI() - - -@app.on_event("startup") -def on_startup(): - create_db_and_tables() - - -@app.post("/heroes/", response_model=HeroPublic) -def create_hero(hero: HeroCreate, session: Session = Depends(get_session)): - db_hero = Hero.model_validate(hero) - session.add(db_hero) - session.commit() - session.refresh(db_hero) - return db_hero - - -@app.get("/heroes/", response_model=List[HeroPublic]) -def read_heroes( - session: Session = Depends(get_session), - offset: int = 0, - limit: int = Query(default=100, le=100), -): - heroes = session.exec(select(Hero).offset(offset).limit(limit)).all() - return heroes - - -@app.get("/heroes/{hero_id}", response_model=HeroPublic) -def read_hero(hero_id: int, session: Session = Depends(get_session)): - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - return hero - - -@app.patch("/heroes/{hero_id}", response_model=HeroPublic) -def update_hero( - hero_id: int, hero: HeroUpdate, session: Session = Depends(get_session) -): - hero_db = session.get(Hero, hero_id) - if not hero_db: - raise HTTPException(status_code=404, detail="Hero not found") - hero_data = hero.model_dump(exclude_unset=True) - hero_db.sqlmodel_update(hero_data) - session.add(hero_db) - session.commit() - session.refresh(hero_db) - return hero_db - - -@app.delete("/heroes/{hero_id}") -def delete_hero(hero_id: int, session: Session = Depends(get_session)): - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - session.delete(hero) - session.commit() - return {"ok": True} diff --git a/docs_src/sql_databases/tutorial002_an.py b/docs_src/sql_databases/tutorial002_an.py deleted file mode 100644 index 15e3d7c3a5..0000000000 --- a/docs_src/sql_databases/tutorial002_an.py +++ /dev/null @@ -1,104 +0,0 @@ -from typing import List, Union - -from fastapi import Depends, FastAPI, HTTPException, Query -from sqlmodel import Field, Session, SQLModel, create_engine, select -from typing_extensions import Annotated - - -class HeroBase(SQLModel): - name: str = Field(index=True) - age: Union[int, None] = Field(default=None, index=True) - - -class Hero(HeroBase, table=True): - id: Union[int, None] = Field(default=None, primary_key=True) - secret_name: str - - -class HeroPublic(HeroBase): - id: int - - -class HeroCreate(HeroBase): - secret_name: str - - -class HeroUpdate(HeroBase): - name: Union[str, None] = None - age: Union[int, None] = None - secret_name: Union[str, None] = None - - -sqlite_file_name = "database.db" -sqlite_url = f"sqlite:///{sqlite_file_name}" - -connect_args = {"check_same_thread": False} -engine = create_engine(sqlite_url, connect_args=connect_args) - - -def create_db_and_tables(): - SQLModel.metadata.create_all(engine) - - -def get_session(): - with Session(engine) as session: - yield session - - -SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() - - -@app.on_event("startup") -def on_startup(): - create_db_and_tables() - - -@app.post("/heroes/", response_model=HeroPublic) -def create_hero(hero: HeroCreate, session: SessionDep): - db_hero = Hero.model_validate(hero) - session.add(db_hero) - session.commit() - session.refresh(db_hero) - return db_hero - - -@app.get("/heroes/", response_model=List[HeroPublic]) -def read_heroes( - session: SessionDep, - offset: int = 0, - limit: Annotated[int, Query(le=100)] = 100, -): - heroes = session.exec(select(Hero).offset(offset).limit(limit)).all() - return heroes - - -@app.get("/heroes/{hero_id}", response_model=HeroPublic) -def read_hero(hero_id: int, session: SessionDep): - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - return hero - - -@app.patch("/heroes/{hero_id}", response_model=HeroPublic) -def update_hero(hero_id: int, hero: HeroUpdate, session: SessionDep): - hero_db = session.get(Hero, hero_id) - if not hero_db: - raise HTTPException(status_code=404, detail="Hero not found") - hero_data = hero.model_dump(exclude_unset=True) - hero_db.sqlmodel_update(hero_data) - session.add(hero_db) - session.commit() - session.refresh(hero_db) - return hero_db - - -@app.delete("/heroes/{hero_id}") -def delete_hero(hero_id: int, session: SessionDep): - hero = session.get(Hero, hero_id) - if not hero: - raise HTTPException(status_code=404, detail="Hero not found") - session.delete(hero) - session.commit() - return {"ok": True} diff --git a/docs_src/static_files/tutorial001.py b/docs_src/static_files/tutorial001_py39.py similarity index 100% rename from docs_src/static_files/tutorial001.py rename to docs_src/static_files/tutorial001_py39.py diff --git a/docs_src/sub_applications/tutorial001.py b/docs_src/sub_applications/tutorial001_py39.py similarity index 100% rename from docs_src/sub_applications/tutorial001.py rename to docs_src/sub_applications/tutorial001_py39.py diff --git a/docs_src/templates/tutorial001.py b/docs_src/templates/tutorial001_py39.py similarity index 100% rename from docs_src/templates/tutorial001.py rename to docs_src/templates/tutorial001_py39.py diff --git a/docs_src/using_request_directly/tutorial001.py b/docs_src/using_request_directly/tutorial001_py39.py similarity index 100% rename from docs_src/using_request_directly/tutorial001.py rename to docs_src/using_request_directly/tutorial001_py39.py diff --git a/docs_src/websockets/tutorial001.py b/docs_src/websockets/tutorial001_py39.py similarity index 100% rename from docs_src/websockets/tutorial001.py rename to docs_src/websockets/tutorial001_py39.py diff --git a/docs_src/websockets/tutorial002_an.py b/docs_src/websockets/tutorial002_an.py deleted file mode 100644 index c838fbd306..0000000000 --- a/docs_src/websockets/tutorial002_an.py +++ /dev/null @@ -1,93 +0,0 @@ -from typing import Union - -from fastapi import ( - Cookie, - Depends, - FastAPI, - Query, - WebSocket, - WebSocketException, - status, -) -from fastapi.responses import HTMLResponse -from typing_extensions import Annotated - -app = FastAPI() - -html = """ - - - - Chat - - -

WebSocket Chat

-
- - - -
- - -
- - - - -""" - - -@app.get("/") -async def get(): - return HTMLResponse(html) - - -async def get_cookie_or_token( - websocket: WebSocket, - session: Annotated[Union[str, None], Cookie()] = None, - token: Annotated[Union[str, None], Query()] = None, -): - if session is None and token is None: - raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) - return session or token - - -@app.websocket("/items/{item_id}/ws") -async def websocket_endpoint( - *, - websocket: WebSocket, - item_id: str, - q: Union[int, None] = None, - cookie_or_token: Annotated[str, Depends(get_cookie_or_token)], -): - await websocket.accept() - while True: - data = await websocket.receive_text() - await websocket.send_text( - f"Session cookie or query token value is: {cookie_or_token}" - ) - if q is not None: - await websocket.send_text(f"Query parameter q is: {q}") - await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}") diff --git a/docs_src/websockets/tutorial002.py b/docs_src/websockets/tutorial002_py39.py similarity index 100% rename from docs_src/websockets/tutorial002.py rename to docs_src/websockets/tutorial002_py39.py diff --git a/docs_src/websockets/tutorial003.py b/docs_src/websockets/tutorial003.py deleted file mode 100644 index d561633a8d..0000000000 --- a/docs_src/websockets/tutorial003.py +++ /dev/null @@ -1,83 +0,0 @@ -from typing import List - -from fastapi import FastAPI, WebSocket, WebSocketDisconnect -from fastapi.responses import HTMLResponse - -app = FastAPI() - -html = """ - - - - Chat - - -

WebSocket Chat

-

Your ID:

-
- - -
- - - - -""" - - -class ConnectionManager: - def __init__(self): - self.active_connections: List[WebSocket] = [] - - async def connect(self, websocket: WebSocket): - await websocket.accept() - self.active_connections.append(websocket) - - def disconnect(self, websocket: WebSocket): - self.active_connections.remove(websocket) - - async def send_personal_message(self, message: str, websocket: WebSocket): - await websocket.send_text(message) - - async def broadcast(self, message: str): - for connection in self.active_connections: - await connection.send_text(message) - - -manager = ConnectionManager() - - -@app.get("/") -async def get(): - return HTMLResponse(html) - - -@app.websocket("/ws/{client_id}") -async def websocket_endpoint(websocket: WebSocket, client_id: int): - await manager.connect(websocket) - try: - while True: - data = await websocket.receive_text() - await manager.send_personal_message(f"You wrote: {data}", websocket) - await manager.broadcast(f"Client #{client_id} says: {data}") - except WebSocketDisconnect: - manager.disconnect(websocket) - await manager.broadcast(f"Client #{client_id} left the chat") diff --git a/docs_src/wsgi/tutorial001.py b/docs_src/wsgi/tutorial001_py39.py similarity index 100% rename from docs_src/wsgi/tutorial001.py rename to docs_src/wsgi/tutorial001_py39.py diff --git a/fastapi/_compat/shared.py b/fastapi/_compat/shared.py index cabf482283..c4dd54dec6 100644 --- a/fastapi/_compat/shared.py +++ b/fastapi/_compat/shared.py @@ -24,13 +24,7 @@ from starlette.datastructures import UploadFile from typing_extensions import Annotated, get_args, get_origin # Copy from Pydantic v2, compatible with v1 -if sys.version_info < (3, 9): - # Pydantic no longer supports Python 3.8, this might be incorrect, but the code - # this is used for is also never reached in this codebase, as it's a copy of - # Pydantic's lenient_issubclass, just for compatibility with v1 - # TODO: remove when dropping support for Python 3.8 - WithArgsTypes: Tuple[Any, ...] = () -elif sys.version_info < (3, 10): +if sys.version_info < (3, 10): WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # type: ignore[attr-defined] else: WithArgsTypes: tuple[Any, ...] = ( diff --git a/pyproject.toml b/pyproject.toml index ef4440b1b4..ede080c5b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -200,7 +200,7 @@ relative_files = true context = '${CONTEXT}' dynamic_context = "test_function" omit = [ - "docs_src/response_model/tutorial003_04.py", + "docs_src/response_model/tutorial003_04_py39.py", "docs_src/response_model/tutorial003_04_py310.py", ] @@ -230,41 +230,30 @@ ignore = [ [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] -"docs_src/dependencies/tutorial007.py" = ["F821"] -"docs_src/dependencies/tutorial008.py" = ["F821"] -"docs_src/dependencies/tutorial009.py" = ["F821"] -"docs_src/dependencies/tutorial010.py" = ["F821"] -"docs_src/custom_response/tutorial007.py" = ["B007"] -"docs_src/dataclasses/tutorial003.py" = ["I001"] -"docs_src/path_operation_advanced_configuration/tutorial007.py" = ["B904"] +"docs_src/dependencies/tutorial007_py39.py" = ["F821"] +"docs_src/dependencies/tutorial008_py39.py" = ["F821"] +"docs_src/dependencies/tutorial009_py39.py" = ["F821"] +"docs_src/dependencies/tutorial010_py39.py" = ["F821"] +"docs_src/custom_response/tutorial007_py39.py" = ["B007"] +"docs_src/dataclasses/tutorial003_py39.py" = ["I001"] "docs_src/path_operation_advanced_configuration/tutorial007_py39.py" = ["B904"] -"docs_src/path_operation_advanced_configuration/tutorial007_pv1.py" = ["B904"] "docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py" = ["B904"] -"docs_src/custom_request_and_route/tutorial002.py" = ["B904"] "docs_src/custom_request_and_route/tutorial002_py39.py" = ["B904"] "docs_src/custom_request_and_route/tutorial002_py310.py" = ["B904"] -"docs_src/custom_request_and_route/tutorial002_an.py" = ["B904"] "docs_src/custom_request_and_route/tutorial002_an_py39.py" = ["B904"] "docs_src/custom_request_and_route/tutorial002_an_py310.py" = ["B904"] -"docs_src/dependencies/tutorial008_an.py" = ["F821"] "docs_src/dependencies/tutorial008_an_py39.py" = ["F821"] -"docs_src/query_params_str_validations/tutorial012_an.py" = ["B006"] "docs_src/query_params_str_validations/tutorial012_an_py39.py" = ["B006"] -"docs_src/query_params_str_validations/tutorial013_an.py" = ["B006"] "docs_src/query_params_str_validations/tutorial013_an_py39.py" = ["B006"] -"docs_src/security/tutorial004.py" = ["B904"] -"docs_src/security/tutorial004_an.py" = ["B904"] -"docs_src/security/tutorial004_an_py310.py" = ["B904"] +"docs_src/security/tutorial004_py39.py" = ["B904"] "docs_src/security/tutorial004_an_py39.py" = ["B904"] +"docs_src/security/tutorial004_an_py310.py" = ["B904"] "docs_src/security/tutorial004_py310.py" = ["B904"] -"docs_src/security/tutorial005.py" = ["B904"] -"docs_src/security/tutorial005_an.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_py39.py" = ["B904"] -"docs_src/dependencies/tutorial008b.py" = ["B904"] -"docs_src/dependencies/tutorial008b_an.py" = ["B904"] +"docs_src/dependencies/tutorial008b_py39.py" = ["B904"] "docs_src/dependencies/tutorial008b_an_py39.py" = ["B904"] diff --git a/tests/test_tutorial/test_additional_responses/test_tutorial001.py b/tests/test_tutorial/test_additional_responses/test_tutorial001.py index 3afeaff840..1a18db75ce 100644 --- a/tests/test_tutorial/test_additional_responses/test_tutorial001.py +++ b/tests/test_tutorial/test_additional_responses/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.additional_responses.tutorial001 import app +from docs_src.additional_responses.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_additional_responses/test_tutorial002.py b/tests/test_tutorial/test_additional_responses/test_tutorial002.py index 91d6ff101f..bbcad8f294 100644 --- a/tests/test_tutorial/test_additional_responses/test_tutorial002.py +++ b/tests/test_tutorial/test_additional_responses/test_tutorial002.py @@ -12,7 +12,7 @@ from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial002"), + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_additional_responses/test_tutorial003.py b/tests/test_tutorial/test_additional_responses/test_tutorial003.py index bd34d2938c..90dc4e371e 100644 --- a/tests/test_tutorial/test_additional_responses/test_tutorial003.py +++ b/tests/test_tutorial/test_additional_responses/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.additional_responses.tutorial003 import app +from docs_src.additional_responses.tutorial003_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_additional_responses/test_tutorial004.py b/tests/test_tutorial/test_additional_responses/test_tutorial004.py index 2d9491467e..cbd4fff7d6 100644 --- a/tests/test_tutorial/test_additional_responses/test_tutorial004.py +++ b/tests/test_tutorial/test_additional_responses/test_tutorial004.py @@ -12,7 +12,7 @@ from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial004"), + pytest.param("tutorial004_py39"), pytest.param("tutorial004_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_additional_status_codes/test_tutorial001.py b/tests/test_tutorial/test_additional_status_codes/test_tutorial001.py index b304f70153..bced1f6dfe 100644 --- a/tests/test_tutorial/test_additional_status_codes/test_tutorial001.py +++ b/tests/test_tutorial/test_additional_status_codes/test_tutorial001.py @@ -3,16 +3,15 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_an_py39", pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_advanced_middleware/test_tutorial001.py b/tests/test_tutorial/test_advanced_middleware/test_tutorial001.py index 157fa5caf1..f17391956e 100644 --- a/tests/test_tutorial/test_advanced_middleware/test_tutorial001.py +++ b/tests/test_tutorial/test_advanced_middleware/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.advanced_middleware.tutorial001 import app +from docs_src.advanced_middleware.tutorial001_py39 import app def test_middleware(): diff --git a/tests/test_tutorial/test_advanced_middleware/test_tutorial002.py b/tests/test_tutorial/test_advanced_middleware/test_tutorial002.py index 79be52f4db..bae915406e 100644 --- a/tests/test_tutorial/test_advanced_middleware/test_tutorial002.py +++ b/tests/test_tutorial/test_advanced_middleware/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.advanced_middleware.tutorial002 import app +from docs_src.advanced_middleware.tutorial002_py39 import app def test_middleware(): diff --git a/tests/test_tutorial/test_advanced_middleware/test_tutorial003.py b/tests/test_tutorial/test_advanced_middleware/test_tutorial003.py index 04a922ff7b..66697997c8 100644 --- a/tests/test_tutorial/test_advanced_middleware/test_tutorial003.py +++ b/tests/test_tutorial/test_advanced_middleware/test_tutorial003.py @@ -1,7 +1,7 @@ from fastapi.responses import PlainTextResponse from fastapi.testclient import TestClient -from docs_src.advanced_middleware.tutorial003 import app +from docs_src.advanced_middleware.tutorial003_py39 import app @app.get("/large") diff --git a/tests/test_tutorial/test_async_tests/test_main.py b/tests/test_tutorial/test_async_tests/test_main_a.py similarity index 58% rename from tests/test_tutorial/test_async_tests/test_main.py rename to tests/test_tutorial/test_async_tests/test_main_a.py index 1f5d7186cc..f29acaa9a0 100644 --- a/tests/test_tutorial/test_async_tests/test_main.py +++ b/tests/test_tutorial/test_async_tests/test_main_a.py @@ -1,6 +1,6 @@ import pytest -from docs_src.async_tests.test_main import test_root +from docs_src.async_tests.app_a_py39.test_main import test_root @pytest.mark.anyio diff --git a/tests/test_tutorial/test_authentication_error_status_code/test_tutorial001.py b/tests/test_tutorial/test_authentication_error_status_code/test_tutorial001.py index bbd7bff30f..6f58116313 100644 --- a/tests/test_tutorial/test_authentication_error_status_code/test_tutorial001.py +++ b/tests/test_tutorial/test_authentication_error_status_code/test_tutorial001.py @@ -4,14 +4,11 @@ import pytest from fastapi.testclient import TestClient from inline_snapshot import snapshot -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_background_tasks/test_tutorial001.py b/tests/test_tutorial/test_background_tasks/test_tutorial001.py index 0602cd8aa4..c0ad27a6f5 100644 --- a/tests/test_tutorial/test_background_tasks/test_tutorial001.py +++ b/tests/test_tutorial/test_background_tasks/test_tutorial001.py @@ -3,7 +3,7 @@ from pathlib import Path from fastapi.testclient import TestClient -from docs_src.background_tasks.tutorial001 import app +from docs_src.background_tasks.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_background_tasks/test_tutorial002.py b/tests/test_tutorial/test_background_tasks/test_tutorial002.py index d5ef51ee2b..288a1c244e 100644 --- a/tests/test_tutorial/test_background_tasks/test_tutorial002.py +++ b/tests/test_tutorial/test_background_tasks/test_tutorial002.py @@ -5,16 +5,15 @@ from pathlib import Path import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial002", + "tutorial002_py39", pytest.param("tutorial002_py310", marks=needs_py310), - "tutorial002_an", - pytest.param("tutorial002_an_py39", marks=needs_py39), + "tutorial002_an_py39", pytest.param("tutorial002_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py b/tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py index a070f850f7..00574b5b0f 100644 --- a/tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py +++ b/tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.behind_a_proxy.tutorial001 import app +from docs_src.behind_a_proxy.tutorial001_py39 import app client = TestClient(app, root_path="/api/v1") diff --git a/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py b/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py index f13046e018..da4acb28cc 100644 --- a/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py +++ b/tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.behind_a_proxy.tutorial001_01 import app +from docs_src.behind_a_proxy.tutorial001_01_py39 import app client = TestClient( app, diff --git a/tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py b/tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py index ce791e2157..1a49c0dfeb 100644 --- a/tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py +++ b/tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.behind_a_proxy.tutorial002 import app +from docs_src.behind_a_proxy.tutorial002_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py b/tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py index ec17b41790..2d1d1b03c8 100644 --- a/tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py +++ b/tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py @@ -1,7 +1,7 @@ from dirty_equals import IsOneOf from fastapi.testclient import TestClient -from docs_src.behind_a_proxy.tutorial003 import app +from docs_src.behind_a_proxy.tutorial003_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py b/tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py index 2f8eb46995..e8a03e8112 100644 --- a/tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py +++ b/tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py @@ -1,7 +1,7 @@ from dirty_equals import IsOneOf from fastapi.testclient import TestClient -from docs_src.behind_a_proxy.tutorial004 import app +from docs_src.behind_a_proxy.tutorial004_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_bigger_applications/test_main.py b/tests/test_tutorial/test_bigger_applications/test_main.py index fe40fad7d0..7493a9e661 100644 --- a/tests/test_tutorial/test_bigger_applications/test_main.py +++ b/tests/test_tutorial/test_bigger_applications/test_main.py @@ -4,15 +4,12 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "app_an.main", - pytest.param("app_an_py39.main", marks=needs_py39), - "app.main", + "app_py39.main", + "app_an_py39.main", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_body/test_tutorial001.py b/tests/test_tutorial/test_body/test_tutorial001.py index f8b5aee8d2..6aa9f2593e 100644 --- a/tests/test_tutorial/test_body/test_tutorial001.py +++ b/tests/test_tutorial/test_body/test_tutorial001.py @@ -11,7 +11,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_body_fields/test_tutorial001.py b/tests/test_tutorial/test_body_fields/test_tutorial001.py index fb68f28689..d54ec7191a 100644 --- a/tests/test_tutorial/test_body_fields/test_tutorial001.py +++ b/tests/test_tutorial/test_body_fields/test_tutorial001.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_an_py39", pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial001.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial001.py index 1424055952..2035cf9448 100644 --- a/tests/test_tutorial/test_body_multiple_params/test_tutorial001.py +++ b/tests/test_tutorial/test_body_multiple_params/test_tutorial001.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_an_py39", pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py index d18ceae486..d3e6401af2 100644 --- a/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py +++ b/tests/test_tutorial/test_body_multiple_params/test_tutorial003.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003", + "tutorial003_py39", pytest.param("tutorial003_py310", marks=needs_py310), - "tutorial003_an", - pytest.param("tutorial003_an_py39", marks=needs_py39), + "tutorial003_an_py39", pytest.param("tutorial003_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_body_nested_models/test_tutorial009.py b/tests/test_tutorial/test_body_nested_models/test_tutorial009.py index 38ba3c8875..db9f04546e 100644 --- a/tests/test_tutorial/test_body_nested_models/test_tutorial009.py +++ b/tests/test_tutorial/test_body_nested_models/test_tutorial009.py @@ -4,14 +4,11 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial009", - pytest.param("tutorial009_py39", marks=needs_py39), + "tutorial009_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001.py b/tests/test_tutorial/test_body_updates/test_tutorial001.py index f874dc9bd6..8bbc4d6992 100644 --- a/tests/test_tutorial/test_body_updates/test_tutorial001.py +++ b/tests/test_tutorial/test_body_updates/test_tutorial001.py @@ -3,15 +3,14 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), - pytest.param("tutorial001_py39", marks=needs_py39), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_conditional_openapi/test_tutorial001.py b/tests/test_tutorial/test_conditional_openapi/test_tutorial001.py index b098f259c2..a425e893d8 100644 --- a/tests/test_tutorial/test_conditional_openapi/test_tutorial001.py +++ b/tests/test_tutorial/test_conditional_openapi/test_tutorial001.py @@ -6,11 +6,11 @@ from ...utils import needs_pydanticv2 def get_client() -> TestClient: - from docs_src.conditional_openapi import tutorial001 + from docs_src.conditional_openapi import tutorial001_py39 - importlib.reload(tutorial001) + importlib.reload(tutorial001_py39) - client = TestClient(tutorial001.app) + client = TestClient(tutorial001_py39.app) return client diff --git a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py index a04dba2197..1fa9419a76 100644 --- a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.configure_swagger_ui.tutorial001 import app +from docs_src.configure_swagger_ui.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py index ea56b6f21c..c218cc858c 100644 --- a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.configure_swagger_ui.tutorial002 import app +from docs_src.configure_swagger_ui.tutorial002_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py index 926bbb14f0..8b73685499 100644 --- a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.configure_swagger_ui.tutorial003 import app +from docs_src.configure_swagger_ui.tutorial003_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py b/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py index 60643185a4..265dee944e 100644 --- a/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py +++ b/tests/test_tutorial/test_cookie_param_models/test_tutorial001.py @@ -5,16 +5,15 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient from inline_snapshot import snapshot -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_an_py39", pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py b/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py index cef6f66309..4a826a5374 100644 --- a/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py +++ b/tests/test_tutorial/test_cookie_param_models/test_tutorial002.py @@ -6,7 +6,6 @@ from fastapi.testclient import TestClient from inline_snapshot import snapshot from tests.utils import ( - needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2, @@ -17,15 +16,13 @@ from tests.utils import ( @pytest.fixture( name="client", params=[ - pytest.param("tutorial002", marks=needs_pydanticv2), + pytest.param("tutorial002_py39", marks=needs_pydanticv2), pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]), - pytest.param("tutorial002_an", marks=needs_pydanticv2), - pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]), + pytest.param("tutorial002_an_py39", marks=needs_pydanticv2), pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]), - pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]), + pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1), pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]), - pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]), - pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]), + pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1), pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]), ], ) diff --git a/tests/test_tutorial/test_cookie_params/test_tutorial001.py b/tests/test_tutorial/test_cookie_params/test_tutorial001.py index 90e8dfd37c..a65249d657 100644 --- a/tests/test_tutorial/test_cookie_params/test_tutorial001.py +++ b/tests/test_tutorial/test_cookie_params/test_tutorial001.py @@ -5,16 +5,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="mod", params=[ - "tutorial001", + "tutorial001_py39", pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_an_py39", pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_cors/test_tutorial001.py b/tests/test_tutorial/test_cors/test_tutorial001.py index f62c9df4f9..6a733693ae 100644 --- a/tests/test_tutorial/test_cors/test_tutorial001.py +++ b/tests/test_tutorial/test_cors/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.cors.tutorial001 import app +from docs_src.cors.tutorial001_py39 import app def test_cors(): diff --git a/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py b/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py index cb8e8c2248..1816e5d975 100644 --- a/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py +++ b/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py @@ -10,7 +10,7 @@ def client(): static_dir: Path = Path(os.getcwd()) / "static" print(static_dir) static_dir.mkdir(exist_ok=True) - from docs_src.custom_docs_ui.tutorial001 import app + from docs_src.custom_docs_ui.tutorial001_py39 import app with TestClient(app) as client: yield client diff --git a/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py b/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py index 712618807c..e8b7eb7aa3 100644 --- a/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py +++ b/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py @@ -10,7 +10,7 @@ def client(): static_dir: Path = Path(os.getcwd()) / "static" print(static_dir) static_dir.mkdir(exist_ok=True) - from docs_src.custom_docs_ui.tutorial002 import app + from docs_src.custom_docs_ui.tutorial002_py39 import app with TestClient(app) as client: yield client diff --git a/tests/test_tutorial/test_custom_request_and_route/test_tutorial001.py b/tests/test_tutorial/test_custom_request_and_route/test_tutorial001.py index f9fd0d1af8..b4ea537846 100644 --- a/tests/test_tutorial/test_custom_request_and_route/test_tutorial001.py +++ b/tests/test_tutorial/test_custom_request_and_route/test_tutorial001.py @@ -6,17 +6,15 @@ import pytest from fastapi import Request from fastapi.testclient import TestClient -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial001"), - pytest.param("tutorial001_py39", marks=needs_py39), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - pytest.param("tutorial001_an"), - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py b/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py index c35752ed13..643011637e 100644 --- a/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py +++ b/tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py @@ -4,17 +4,15 @@ import pytest from dirty_equals import IsDict, IsOneOf from fastapi.testclient import TestClient -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial002"), - pytest.param("tutorial002_py39", marks=needs_py39), + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), - pytest.param("tutorial002_an"), - pytest.param("tutorial002_an_py39", marks=needs_py39), + pytest.param("tutorial002_an_py39"), pytest.param("tutorial002_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py b/tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py index 9e895b2daf..6cad7bd3f0 100644 --- a/tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py +++ b/tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py @@ -9,7 +9,7 @@ from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial003"), + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial001.py b/tests/test_tutorial/test_custom_response/test_tutorial001.py index fc83624673..c81e991ebf 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial001.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial001 import app +from docs_src.custom_response.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial001b.py b/tests/test_tutorial/test_custom_response/test_tutorial001b.py index 91e5c501e3..3337f47d5f 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial001b.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial001b.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial001b import app +from docs_src.custom_response.tutorial001b_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial004.py b/tests/test_tutorial/test_custom_response/test_tutorial004.py index de60574f5e..0e7d69791b 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial004.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial004.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial004 import app +from docs_src.custom_response.tutorial004_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial005.py b/tests/test_tutorial/test_custom_response/test_tutorial005.py index 889bf3e929..fea105c28e 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial005.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial005.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial005 import app +from docs_src.custom_response.tutorial005_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial006.py b/tests/test_tutorial/test_custom_response/test_tutorial006.py index 2d0a2cd3f6..e9e6ca1086 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial006.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial006.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial006 import app +from docs_src.custom_response.tutorial006_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial006b.py b/tests/test_tutorial/test_custom_response/test_tutorial006b.py index 1739fd4570..7ca727d2cd 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial006b.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial006b.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial006b import app +from docs_src.custom_response.tutorial006b_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial006c.py b/tests/test_tutorial/test_custom_response/test_tutorial006c.py index 2675f2a93c..e3f76c8403 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial006c.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial006c.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial006c import app +from docs_src.custom_response.tutorial006c_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial007.py b/tests/test_tutorial/test_custom_response/test_tutorial007.py index 4ede820b94..a62476ec14 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial007.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial007.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial007 import app +from docs_src.custom_response.tutorial007_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_custom_response/test_tutorial008.py b/tests/test_tutorial/test_custom_response/test_tutorial008.py index 10d88a5948..d9fe61f539 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial008.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial008.py @@ -2,15 +2,15 @@ from pathlib import Path from fastapi.testclient import TestClient -from docs_src.custom_response import tutorial008 -from docs_src.custom_response.tutorial008 import app +from docs_src.custom_response import tutorial008_py39 +from docs_src.custom_response.tutorial008_py39 import app client = TestClient(app) def test_get(tmp_path: Path): file_path: Path = tmp_path / "large-video-file.mp4" - tutorial008.some_file_path = str(file_path) + tutorial008_py39.some_file_path = str(file_path) test_content = b"Fake video bytes" file_path.write_bytes(test_content) response = client.get("/") diff --git a/tests/test_tutorial/test_custom_response/test_tutorial009.py b/tests/test_tutorial/test_custom_response/test_tutorial009.py index ac20f89e67..cb6a514be6 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial009.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial009.py @@ -2,15 +2,15 @@ from pathlib import Path from fastapi.testclient import TestClient -from docs_src.custom_response import tutorial009 -from docs_src.custom_response.tutorial009 import app +from docs_src.custom_response import tutorial009_py39 +from docs_src.custom_response.tutorial009_py39 import app client = TestClient(app) def test_get(tmp_path: Path): file_path: Path = tmp_path / "large-video-file.mp4" - tutorial009.some_file_path = str(file_path) + tutorial009_py39.some_file_path = str(file_path) test_content = b"Fake video bytes" file_path.write_bytes(test_content) response = client.get("/") diff --git a/tests/test_tutorial/test_custom_response/test_tutorial009b.py b/tests/test_tutorial/test_custom_response/test_tutorial009b.py index 4f56e2f3fe..9918bdb1ac 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial009b.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial009b.py @@ -2,15 +2,15 @@ from pathlib import Path from fastapi.testclient import TestClient -from docs_src.custom_response import tutorial009b -from docs_src.custom_response.tutorial009b import app +from docs_src.custom_response import tutorial009b_py39 +from docs_src.custom_response.tutorial009b_py39 import app client = TestClient(app) def test_get(tmp_path: Path): file_path: Path = tmp_path / "large-video-file.mp4" - tutorial009b.some_file_path = str(file_path) + tutorial009b_py39.some_file_path = str(file_path) test_content = b"Fake video bytes" file_path.write_bytes(test_content) response = client.get("/") diff --git a/tests/test_tutorial/test_custom_response/test_tutorial009c.py b/tests/test_tutorial/test_custom_response/test_tutorial009c.py index 23c711abe9..efc3a6b4a0 100644 --- a/tests/test_tutorial/test_custom_response/test_tutorial009c.py +++ b/tests/test_tutorial/test_custom_response/test_tutorial009c.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.custom_response.tutorial009c import app +from docs_src.custom_response.tutorial009c_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_dataclasses/test_tutorial001.py b/tests/test_tutorial/test_dataclasses/test_tutorial001.py index b36dee7684..d5f230bc42 100644 --- a/tests/test_tutorial/test_dataclasses/test_tutorial001.py +++ b/tests/test_tutorial/test_dataclasses/test_tutorial001.py @@ -10,7 +10,7 @@ from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial001"), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_dataclasses/test_tutorial002.py b/tests/test_tutorial/test_dataclasses/test_tutorial002.py index baaea45d8f..4cf8933805 100644 --- a/tests/test_tutorial/test_dataclasses/test_tutorial002.py +++ b/tests/test_tutorial/test_dataclasses/test_tutorial002.py @@ -4,14 +4,13 @@ import pytest from dirty_equals import IsDict, IsOneOf from fastapi.testclient import TestClient -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - pytest.param("tutorial002"), - pytest.param("tutorial002_py39", marks=needs_py39), + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_dataclasses/test_tutorial003.py b/tests/test_tutorial/test_dataclasses/test_tutorial003.py index 5728d2b6b3..d8cc45dd69 100644 --- a/tests/test_tutorial/test_dataclasses/test_tutorial003.py +++ b/tests/test_tutorial/test_dataclasses/test_tutorial003.py @@ -3,14 +3,13 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial003"), - pytest.param("tutorial003_py39", marks=needs_py39), + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_dependencies/test_tutorial001.py b/tests/test_tutorial/test_dependencies/test_tutorial001.py index ed9944912e..8dac99cf30 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial001.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial001.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_dependencies/test_tutorial004.py b/tests/test_tutorial/test_dependencies/test_tutorial004.py index 8221c83d44..8a1346d0d2 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial004.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial004.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial004", + pytest.param("tutorial004_py39"), pytest.param("tutorial004_py310", marks=needs_py310), - "tutorial004_an", - pytest.param("tutorial004_an_py39", marks=needs_py39), + pytest.param("tutorial004_an_py39"), pytest.param("tutorial004_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_dependencies/test_tutorial006.py b/tests/test_tutorial/test_dependencies/test_tutorial006.py index 4530762f76..46f0066f9f 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial006.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial006.py @@ -4,15 +4,12 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial006", - "tutorial006_an", - pytest.param("tutorial006_an_py39", marks=needs_py39), + pytest.param("tutorial006_py39"), + pytest.param("tutorial006_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008b.py b/tests/test_tutorial/test_dependencies/test_tutorial008b.py index 4d70922657..91e00b3705 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008b.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008b.py @@ -3,15 +3,12 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial008b", - "tutorial008b_an", - pytest.param("tutorial008b_an_py39", marks=needs_py39), + pytest.param("tutorial008b_py39"), + pytest.param("tutorial008b_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008c.py b/tests/test_tutorial/test_dependencies/test_tutorial008c.py index 369b0a221d..aede6f8d25 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008c.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008c.py @@ -5,15 +5,12 @@ import pytest from fastapi.exceptions import FastAPIError from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="mod", params=[ - "tutorial008c", - "tutorial008c_an", - pytest.param("tutorial008c_an_py39", marks=needs_py39), + pytest.param("tutorial008c_py39"), + pytest.param("tutorial008c_an_py39"), ], ) def get_mod(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008d.py b/tests/test_tutorial/test_dependencies/test_tutorial008d.py index bc99bb3835..5477f8b953 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008d.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008d.py @@ -4,15 +4,12 @@ from types import ModuleType import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="mod", params=[ - "tutorial008d", - "tutorial008d_an", - pytest.param("tutorial008d_an_py39", marks=needs_py39), + pytest.param("tutorial008d_py39"), + pytest.param("tutorial008d_an_py39"), ], ) def get_mod(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008e.py b/tests/test_tutorial/test_dependencies/test_tutorial008e.py index 1ae9ab2cd1..c433157ea1 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008e.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008e.py @@ -3,15 +3,12 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial008e", - "tutorial008e_an", - pytest.param("tutorial008e_an_py39", marks=needs_py39), + pytest.param("tutorial008e_py39"), + pytest.param("tutorial008e_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_dependencies/test_tutorial012.py b/tests/test_tutorial/test_dependencies/test_tutorial012.py index 0af17e9bc5..b791ee0aa1 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial012.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial012.py @@ -4,15 +4,12 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial012", - "tutorial012_an", - pytest.param("tutorial012_an_py39", marks=needs_py39), + pytest.param("tutorial012_py39"), + pytest.param("tutorial012_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_events/test_tutorial001.py b/tests/test_tutorial/test_events/test_tutorial001.py index f65b92d127..5fe99d50df 100644 --- a/tests/test_tutorial/test_events/test_tutorial001.py +++ b/tests/test_tutorial/test_events/test_tutorial001.py @@ -6,7 +6,7 @@ from fastapi.testclient import TestClient @pytest.fixture(name="app", scope="module") def get_app(): with pytest.warns(DeprecationWarning): - from docs_src.events.tutorial001 import app + from docs_src.events.tutorial001_py39 import app yield app diff --git a/tests/test_tutorial/test_events/test_tutorial002.py b/tests/test_tutorial/test_events/test_tutorial002.py index 137294d737..0612899b55 100644 --- a/tests/test_tutorial/test_events/test_tutorial002.py +++ b/tests/test_tutorial/test_events/test_tutorial002.py @@ -6,7 +6,7 @@ from fastapi.testclient import TestClient @pytest.fixture(name="app", scope="module") def get_app(): with pytest.warns(DeprecationWarning): - from docs_src.events.tutorial002 import app + from docs_src.events.tutorial002_py39 import app yield app diff --git a/tests/test_tutorial/test_events/test_tutorial003.py b/tests/test_tutorial/test_events/test_tutorial003.py index 0ad1a1f8b2..38710edfea 100644 --- a/tests/test_tutorial/test_events/test_tutorial003.py +++ b/tests/test_tutorial/test_events/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.events.tutorial003 import ( +from docs_src.events.tutorial003_py39 import ( app, fake_answer_to_everything_ml_model, ml_models, diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial001.py b/tests/test_tutorial/test_extending_openapi/test_tutorial001.py index a85a313501..83ecb300ee 100644 --- a/tests/test_tutorial/test_extending_openapi/test_tutorial001.py +++ b/tests/test_tutorial/test_extending_openapi/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.extending_openapi.tutorial001 import app +from docs_src.extending_openapi.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_extra_data_types/test_tutorial001.py b/tests/test_tutorial/test_extra_data_types/test_tutorial001.py index b816c9cab5..e11f73fe35 100644 --- a/tests/test_tutorial/test_extra_data_types/test_tutorial001.py +++ b/tests/test_tutorial/test_extra_data_types/test_tutorial001.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_extra_models/test_tutorial003.py b/tests/test_tutorial/test_extra_models/test_tutorial003.py index 73aa299039..3aa83c0c40 100644 --- a/tests/test_tutorial/test_extra_models/test_tutorial003.py +++ b/tests/test_tutorial/test_extra_models/test_tutorial003.py @@ -10,7 +10,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003", + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_extra_models/test_tutorial004.py b/tests/test_tutorial/test_extra_models/test_tutorial004.py index 7628db30c7..073375ccc9 100644 --- a/tests/test_tutorial/test_extra_models/test_tutorial004.py +++ b/tests/test_tutorial/test_extra_models/test_tutorial004.py @@ -3,14 +3,11 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial004", - pytest.param("tutorial004_py39", marks=needs_py39), + pytest.param("tutorial004_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_extra_models/test_tutorial005.py b/tests/test_tutorial/test_extra_models/test_tutorial005.py index 553e442385..8e52d8d4ba 100644 --- a/tests/test_tutorial/test_extra_models/test_tutorial005.py +++ b/tests/test_tutorial/test_extra_models/test_tutorial005.py @@ -3,14 +3,11 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial005", - pytest.param("tutorial005_py39", marks=needs_py39), + pytest.param("tutorial005_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_first_steps/test_tutorial001.py b/tests/test_tutorial/test_first_steps/test_tutorial001.py index 6cc9fc2282..c102bb9999 100644 --- a/tests/test_tutorial/test_first_steps/test_tutorial001.py +++ b/tests/test_tutorial/test_first_steps/test_tutorial001.py @@ -1,7 +1,7 @@ import pytest from fastapi.testclient import TestClient -from docs_src.first_steps.tutorial001 import app +from docs_src.first_steps.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_generate_clients/test_tutorial003.py b/tests/test_tutorial/test_generate_clients/test_tutorial003.py index 1cd9678a1c..bac52e4fd6 100644 --- a/tests/test_tutorial/test_generate_clients/test_tutorial003.py +++ b/tests/test_tutorial/test_generate_clients/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.generate_clients.tutorial003 import app +from docs_src.generate_clients.tutorial003_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_handling_errors/test_tutorial001.py b/tests/test_tutorial/test_handling_errors/test_tutorial001.py index 8809c135bd..c01850fae6 100644 --- a/tests/test_tutorial/test_handling_errors/test_tutorial001.py +++ b/tests/test_tutorial/test_handling_errors/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.handling_errors.tutorial001 import app +from docs_src.handling_errors.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_handling_errors/test_tutorial002.py b/tests/test_tutorial/test_handling_errors/test_tutorial002.py index efd86ebdec..09366a86fa 100644 --- a/tests/test_tutorial/test_handling_errors/test_tutorial002.py +++ b/tests/test_tutorial/test_handling_errors/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.handling_errors.tutorial002 import app +from docs_src.handling_errors.tutorial002_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_handling_errors/test_tutorial003.py b/tests/test_tutorial/test_handling_errors/test_tutorial003.py index 4763f68f3f..51ac3e7b28 100644 --- a/tests/test_tutorial/test_handling_errors/test_tutorial003.py +++ b/tests/test_tutorial/test_handling_errors/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.handling_errors.tutorial003 import app +from docs_src.handling_errors.tutorial003_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_handling_errors/test_tutorial004.py b/tests/test_tutorial/test_handling_errors/test_tutorial004.py index c04bf37245..376bc8266f 100644 --- a/tests/test_tutorial/test_handling_errors/test_tutorial004.py +++ b/tests/test_tutorial/test_handling_errors/test_tutorial004.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.handling_errors.tutorial004 import app +from docs_src.handling_errors.tutorial004_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_handling_errors/test_tutorial005.py b/tests/test_tutorial/test_handling_errors/test_tutorial005.py index 581b2e4c75..d713c5d876 100644 --- a/tests/test_tutorial/test_handling_errors/test_tutorial005.py +++ b/tests/test_tutorial/test_handling_errors/test_tutorial005.py @@ -1,7 +1,7 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient -from docs_src.handling_errors.tutorial005 import app +from docs_src.handling_errors.tutorial005_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_handling_errors/test_tutorial006.py b/tests/test_tutorial/test_handling_errors/test_tutorial006.py index 7d2f553aac..491e461b3d 100644 --- a/tests/test_tutorial/test_handling_errors/test_tutorial006.py +++ b/tests/test_tutorial/test_handling_errors/test_tutorial006.py @@ -1,7 +1,7 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient -from docs_src.handling_errors.tutorial006 import app +from docs_src.handling_errors.tutorial006_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_header_param_models/test_tutorial001.py b/tests/test_tutorial/test_header_param_models/test_tutorial001.py index bc876897b2..f59d50762c 100644 --- a/tests/test_tutorial/test_header_param_models/test_tutorial001.py +++ b/tests/test_tutorial/test_header_param_models/test_tutorial001.py @@ -5,17 +5,15 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient from inline_snapshot import snapshot -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", - pytest.param("tutorial001_py39", marks=needs_py39), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_header_param_models/test_tutorial002.py b/tests/test_tutorial/test_header_param_models/test_tutorial002.py index 0615521c43..a7a271ba41 100644 --- a/tests/test_tutorial/test_header_param_models/test_tutorial002.py +++ b/tests/test_tutorial/test_header_param_models/test_tutorial002.py @@ -5,21 +5,19 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient from inline_snapshot import snapshot -from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 +from tests.utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial002", marks=needs_pydanticv2), + pytest.param("tutorial002_py39", marks=needs_pydanticv2), pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]), - pytest.param("tutorial002_an", marks=needs_pydanticv2), - pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]), + pytest.param("tutorial002_an_py39", marks=needs_pydanticv2), pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]), - pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]), + pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1), pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]), - pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]), - pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]), + pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1), pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]), ], ) diff --git a/tests/test_tutorial/test_header_param_models/test_tutorial003.py b/tests/test_tutorial/test_header_param_models/test_tutorial003.py index 554a48d2e8..947587504f 100644 --- a/tests/test_tutorial/test_header_param_models/test_tutorial003.py +++ b/tests/test_tutorial/test_header_param_models/test_tutorial003.py @@ -5,17 +5,15 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient from inline_snapshot import snapshot -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003", - pytest.param("tutorial003_py39", marks=needs_py39), + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), - "tutorial003_an", - pytest.param("tutorial003_an_py39", marks=needs_py39), + pytest.param("tutorial003_an_py39"), pytest.param("tutorial003_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_header_params/test_tutorial001.py b/tests/test_tutorial/test_header_params/test_tutorial001.py index d6f7fe6189..beaf917f92 100644 --- a/tests/test_tutorial/test_header_params/test_tutorial001.py +++ b/tests/test_tutorial/test_header_params/test_tutorial001.py @@ -10,9 +10,9 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_header_params/test_tutorial002.py b/tests/test_tutorial/test_header_params/test_tutorial002.py index 7158f8651b..b892ff905f 100644 --- a/tests/test_tutorial/test_header_params/test_tutorial002.py +++ b/tests/test_tutorial/test_header_params/test_tutorial002.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial002", + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), - "tutorial002_an", - pytest.param("tutorial002_an_py39", marks=needs_py39), + pytest.param("tutorial002_an_py39"), pytest.param("tutorial002_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_header_params/test_tutorial003.py b/tests/test_tutorial/test_header_params/test_tutorial003.py index 473b961236..ef76244159 100644 --- a/tests/test_tutorial/test_header_params/test_tutorial003.py +++ b/tests/test_tutorial/test_header_params/test_tutorial003.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003", + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), - "tutorial003_an", - pytest.param("tutorial003_an_py39", marks=needs_py39), + pytest.param("tutorial003_an_py39"), pytest.param("tutorial003_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_metadata/test_tutorial001.py b/tests/test_tutorial/test_metadata/test_tutorial001.py index 04e8ff82b0..ead48577d0 100644 --- a/tests/test_tutorial/test_metadata/test_tutorial001.py +++ b/tests/test_tutorial/test_metadata/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.metadata.tutorial001 import app +from docs_src.metadata.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_metadata/test_tutorial001_1.py b/tests/test_tutorial/test_metadata/test_tutorial001_1.py index 3efb1c4329..40878ccfd4 100644 --- a/tests/test_tutorial/test_metadata/test_tutorial001_1.py +++ b/tests/test_tutorial/test_metadata/test_tutorial001_1.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.metadata.tutorial001_1 import app +from docs_src.metadata.tutorial001_1_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_metadata/test_tutorial004.py b/tests/test_tutorial/test_metadata/test_tutorial004.py index 5072203712..4ef93fd5e3 100644 --- a/tests/test_tutorial/test_metadata/test_tutorial004.py +++ b/tests/test_tutorial/test_metadata/test_tutorial004.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.metadata.tutorial004 import app +from docs_src.metadata.tutorial004_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_openapi_callbacks/test_tutorial001.py b/tests/test_tutorial/test_openapi_callbacks/test_tutorial001.py index 2df2b98893..975e07cbdd 100644 --- a/tests/test_tutorial/test_openapi_callbacks/test_tutorial001.py +++ b/tests/test_tutorial/test_openapi_callbacks/test_tutorial001.py @@ -11,7 +11,7 @@ from tests.utils import needs_py310 @pytest.fixture( name="mod", params=[ - pytest.param("tutorial001"), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_openapi_webhooks/test_tutorial001.py b/tests/test_tutorial/test_openapi_webhooks/test_tutorial001.py index dc67ec401d..27619489fa 100644 --- a/tests/test_tutorial/test_openapi_webhooks/test_tutorial001.py +++ b/tests/test_tutorial/test_openapi_webhooks/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.openapi_webhooks.tutorial001 import app +from docs_src.openapi_webhooks.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial001.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial001.py index 95542398e4..ee0b707108 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial001.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_operation_advanced_configuration.tutorial001 import app +from docs_src.path_operation_advanced_configuration.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial002.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial002.py index d1388c3670..f6580d72e3 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial002.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_operation_advanced_configuration.tutorial002 import app +from docs_src.path_operation_advanced_configuration.tutorial002_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py index 313bb2a04a..104554fce3 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_operation_advanced_configuration.tutorial003 import app +from docs_src.path_operation_advanced_configuration.tutorial003_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py index da5782d189..3805536e76 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py @@ -3,14 +3,13 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial004"), - pytest.param("tutorial004_py39", marks=needs_py39), + pytest.param("tutorial004_py39"), pytest.param("tutorial004_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial005.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial005.py index 07e2d7d202..e2a71236ff 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial005.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial005.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_operation_advanced_configuration.tutorial005 import app +from docs_src.path_operation_advanced_configuration.tutorial005_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial006.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial006.py index f92c59015e..9484f7f573 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial006.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial006.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_operation_advanced_configuration.tutorial006 import app +from docs_src.path_operation_advanced_configuration.tutorial006_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007.py index a90337a63d..204cca09ed 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007.py @@ -3,14 +3,13 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_pydanticv2 +from ...utils import needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial007"), - pytest.param("tutorial007_py39", marks=needs_py39), + pytest.param("tutorial007_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py index b38e4947cc..62b67a98c1 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py @@ -3,14 +3,13 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_pydanticv1 +from ...utils import needs_pydanticv1 @pytest.fixture( name="client", params=[ - pytest.param("tutorial007_pv1"), - pytest.param("tutorial007_pv1_py39", marks=needs_py39), + pytest.param("tutorial007_pv1_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial002b.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial002b.py index 58dec5769d..5a0193adfa 100644 --- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial002b.py +++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial002b.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_operation_configuration.tutorial002b import app +from docs_src.path_operation_configuration.tutorial002b_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py index 0742f5d0e8..2a7a2b78b2 100644 --- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py +++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py @@ -3,14 +3,13 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - "tutorial005", - pytest.param("tutorial005_py39", marks=needs_py39), + pytest.param("tutorial005_py39"), pytest.param("tutorial005_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial006.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial006.py index 91180d1097..5d9c55675f 100644 --- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial006.py +++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial006.py @@ -1,7 +1,7 @@ import pytest from fastapi.testclient import TestClient -from docs_src.path_operation_configuration.tutorial006 import app +from docs_src.path_operation_configuration.tutorial006_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_params/test_tutorial004.py b/tests/test_tutorial/test_path_params/test_tutorial004.py index acbeaca769..f7f233ccff 100644 --- a/tests/test_tutorial/test_path_params/test_tutorial004.py +++ b/tests/test_tutorial/test_path_params/test_tutorial004.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.path_params.tutorial004 import app +from docs_src.path_params.tutorial004_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_path_params/test_tutorial005.py b/tests/test_tutorial/test_path_params/test_tutorial005.py index 2e4b0146be..b3be70471a 100644 --- a/tests/test_tutorial/test_path_params/test_tutorial005.py +++ b/tests/test_tutorial/test_path_params/test_tutorial005.py @@ -1,7 +1,7 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient -from docs_src.path_params.tutorial005 import app +from docs_src.path_params.tutorial005_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py index 3075a05f51..ce53a36eb8 100644 --- a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py +++ b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py @@ -23,7 +23,7 @@ from ...utils import needs_py310 @pytest.fixture( name="mod", params=[ - "tutorial001_an", + "tutorial001_an_py39", pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py index a402c663d1..57720bf489 100644 --- a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py +++ b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py @@ -24,7 +24,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial002_an", + "tutorial002_an_py39", pytest.param("tutorial002_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py index 03155c9249..f020d4a975 100644 --- a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py +++ b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py @@ -23,7 +23,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003_an", + "tutorial003_an_py39", pytest.param("tutorial003_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.py b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.py index d2e204ddaf..daa6f0b050 100644 --- a/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.py +++ b/tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.py @@ -17,14 +17,13 @@ import importlib from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial004_an", - pytest.param("tutorial004_an_py39", marks=needs_py39), + pytest.param("tutorial004_an_py39"), pytest.param("tutorial004_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_query_param_models/test_tutorial001.py b/tests/test_tutorial/test_query_param_models/test_tutorial001.py index 5b7bc7b424..86830b9341 100644 --- a/tests/test_tutorial/test_query_param_models/test_tutorial001.py +++ b/tests/test_tutorial/test_query_param_models/test_tutorial001.py @@ -5,17 +5,15 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient from inline_snapshot import snapshot -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001", - pytest.param("tutorial001_py39", marks=needs_py39), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_query_param_models/test_tutorial002.py b/tests/test_tutorial/test_query_param_models/test_tutorial002.py index 4432c9d8a3..e7de73f804 100644 --- a/tests/test_tutorial/test_query_param_models/test_tutorial002.py +++ b/tests/test_tutorial/test_query_param_models/test_tutorial002.py @@ -5,23 +5,19 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient from inline_snapshot import snapshot -from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 +from tests.utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial002", marks=needs_pydanticv2), - pytest.param("tutorial002_py39", marks=[needs_py39, needs_pydanticv2]), + pytest.param("tutorial002_py39", marks=needs_pydanticv2), pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]), - pytest.param("tutorial002_an", marks=needs_pydanticv2), - pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]), + pytest.param("tutorial002_an_py39", marks=needs_pydanticv2), pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]), - pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]), - pytest.param("tutorial002_pv1_py39", marks=[needs_py39, needs_pydanticv1]), + pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1), pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]), - pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]), - pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]), + pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1), pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]), ], ) diff --git a/tests/test_tutorial/test_query_params/test_tutorial005.py b/tests/test_tutorial/test_query_params/test_tutorial005.py index 05ae85b451..ad4e4efa6b 100644 --- a/tests/test_tutorial/test_query_params/test_tutorial005.py +++ b/tests/test_tutorial/test_query_params/test_tutorial005.py @@ -1,7 +1,7 @@ from dirty_equals import IsDict from fastapi.testclient import TestClient -from docs_src.query_params.tutorial005 import app +from docs_src.query_params.tutorial005_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_query_params/test_tutorial006.py b/tests/test_tutorial/test_query_params/test_tutorial006.py index a0b5ef4943..349f8dd223 100644 --- a/tests/test_tutorial/test_query_params/test_tutorial006.py +++ b/tests/test_tutorial/test_query_params/test_tutorial006.py @@ -10,7 +10,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial006", + pytest.param("tutorial006_py39"), pytest.param("tutorial006_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial010.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial010.py index e08e169633..de5dbbb2ee 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial010.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial010.py @@ -5,16 +5,15 @@ from dirty_equals import IsDict from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial010", + pytest.param("tutorial010_py39"), pytest.param("tutorial010_py310", marks=needs_py310), - "tutorial010_an", - pytest.param("tutorial010_an_py39", marks=needs_py39), + pytest.param("tutorial010_an_py39"), pytest.param("tutorial010_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial011.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial011.py index f4da25752b..50b3c5683c 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial011.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial011.py @@ -4,17 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial011", - pytest.param("tutorial011_py39", marks=needs_py310), + pytest.param("tutorial011_py39"), pytest.param("tutorial011_py310", marks=needs_py310), - "tutorial011_an", - pytest.param("tutorial011_an_py39", marks=needs_py39), + pytest.param("tutorial011_an_py39"), pytest.param("tutorial011_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial012.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial012.py index 549a90519e..1826928611 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial012.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial012.py @@ -3,16 +3,12 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial012", - pytest.param("tutorial012_py39", marks=needs_py39), - "tutorial012_an", - pytest.param("tutorial012_an_py39", marks=needs_py39), + pytest.param("tutorial012_py39"), + pytest.param("tutorial012_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py index f2f5f7a858..46c367c86b 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py @@ -3,15 +3,12 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial013", - "tutorial013_an", - pytest.param("tutorial013_an_py39", marks=needs_py39), + "tutorial013_py39", + "tutorial013_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial014.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial014.py index edd40bb1ab..0feaccfa44 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial014.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial014.py @@ -3,16 +3,15 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial014", + pytest.param("tutorial014_py39"), pytest.param("tutorial014_py310", marks=needs_py310), - "tutorial014_an", - pytest.param("tutorial014_an_py39", marks=needs_py39), + pytest.param("tutorial014_an_py39"), pytest.param("tutorial014_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py index ae1c40286d..50ebf711f5 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py @@ -5,15 +5,14 @@ from dirty_equals import IsStr from fastapi.testclient import TestClient from inline_snapshot import snapshot -from ...utils import needs_py39, needs_py310, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial015_an", marks=needs_pydanticv2), + pytest.param("tutorial015_an_py39", marks=needs_pydanticv2), pytest.param("tutorial015_an_py310", marks=(needs_py310, needs_pydanticv2)), - pytest.param("tutorial015_an_py39", marks=(needs_py39, needs_pydanticv2)), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_files/test_tutorial001.py b/tests/test_tutorial/test_request_files/test_tutorial001.py index b069199612..a16d951dc6 100644 --- a/tests/test_tutorial/test_request_files/test_tutorial001.py +++ b/tests/test_tutorial/test_request_files/test_tutorial001.py @@ -4,15 +4,12 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial001", - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_py39", + "tutorial001_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_02.py b/tests/test_tutorial/test_request_files/test_tutorial001_02.py index 9075a17561..caea0d2e8f 100644 --- a/tests/test_tutorial/test_request_files/test_tutorial001_02.py +++ b/tests/test_tutorial/test_request_files/test_tutorial001_02.py @@ -5,16 +5,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial001_02", + pytest.param("tutorial001_02_py39"), pytest.param("tutorial001_02_py310", marks=needs_py310), - "tutorial001_02_an", - pytest.param("tutorial001_02_an_py39", marks=needs_py39), + pytest.param("tutorial001_02_an_py39"), pytest.param("tutorial001_02_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_03.py b/tests/test_tutorial/test_request_files/test_tutorial001_03.py index 9fbe2166c1..53a7a0cf85 100644 --- a/tests/test_tutorial/test_request_files/test_tutorial001_03.py +++ b/tests/test_tutorial/test_request_files/test_tutorial001_03.py @@ -3,15 +3,12 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial001_03", - "tutorial001_03_an", - pytest.param("tutorial001_03_an_py39", marks=needs_py39), + "tutorial001_03_py39", + "tutorial001_03_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_files/test_tutorial002.py b/tests/test_tutorial/test_request_files/test_tutorial002.py index 446a876578..34dbbb985d 100644 --- a/tests/test_tutorial/test_request_files/test_tutorial002.py +++ b/tests/test_tutorial/test_request_files/test_tutorial002.py @@ -5,16 +5,12 @@ from dirty_equals import IsDict from fastapi import FastAPI from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="app", params=[ - "tutorial002", - "tutorial002_an", - pytest.param("tutorial002_py39", marks=needs_py39), - pytest.param("tutorial002_an_py39", marks=needs_py39), + "tutorial002_py39", + "tutorial002_an_py39", ], ) def get_app(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_files/test_tutorial003.py b/tests/test_tutorial/test_request_files/test_tutorial003.py index 8534ba3e9a..fa4bfd5695 100644 --- a/tests/test_tutorial/test_request_files/test_tutorial003.py +++ b/tests/test_tutorial/test_request_files/test_tutorial003.py @@ -4,16 +4,12 @@ import pytest from fastapi import FastAPI from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="app", params=[ - "tutorial003", - "tutorial003_an", - pytest.param("tutorial003_py39", marks=needs_py39), - pytest.param("tutorial003_an_py39", marks=needs_py39), + "tutorial003_py39", + "tutorial003_an_py39", ], ) def get_app(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_form_models/test_tutorial001.py b/tests/test_tutorial/test_request_form_models/test_tutorial001.py index 1ca3c96d33..a54df8536c 100644 --- a/tests/test_tutorial/test_request_form_models/test_tutorial001.py +++ b/tests/test_tutorial/test_request_form_models/test_tutorial001.py @@ -4,15 +4,12 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial001", - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_py39", + "tutorial001_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_form_models/test_tutorial002.py b/tests/test_tutorial/test_request_form_models/test_tutorial002.py index b3f6be63ab..9bb90fa064 100644 --- a/tests/test_tutorial/test_request_form_models/test_tutorial002.py +++ b/tests/test_tutorial/test_request_form_models/test_tutorial002.py @@ -3,15 +3,14 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_pydanticv2 +from ...utils import needs_pydanticv2 @pytest.fixture( name="client", params=[ - "tutorial002", - "tutorial002_an", - pytest.param("tutorial002_an_py39", marks=needs_py39), + "tutorial002_py39", + "tutorial002_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py index b503f23a53..41c7833bef 100644 --- a/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py +++ b/tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py @@ -3,15 +3,14 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_pydanticv1 +from ...utils import needs_pydanticv1 @pytest.fixture( name="client", params=[ - "tutorial002_pv1", - "tutorial002_pv1_an", - pytest.param("tutorial002_pv1_an_py39", marks=needs_py39), + "tutorial002_pv1_py39", + "tutorial002_pv1_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_forms/test_tutorial001.py b/tests/test_tutorial/test_request_forms/test_tutorial001.py index 321f8022b7..da20535cf8 100644 --- a/tests/test_tutorial/test_request_forms/test_tutorial001.py +++ b/tests/test_tutorial/test_request_forms/test_tutorial001.py @@ -4,15 +4,12 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial001", - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_py39", + "tutorial001_an_py39", ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_request_forms_and_files/test_tutorial001.py b/tests/test_tutorial/test_request_forms_and_files/test_tutorial001.py index d12219245e..f37ffad443 100644 --- a/tests/test_tutorial/test_request_forms_and_files/test_tutorial001.py +++ b/tests/test_tutorial/test_request_forms_and_files/test_tutorial001.py @@ -5,15 +5,12 @@ from dirty_equals import IsDict from fastapi import FastAPI from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="app", params=[ - "tutorial001", - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + "tutorial001_py39", + "tutorial001_an_py39", ], ) def get_app(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_response_change_status_code/test_tutorial001.py b/tests/test_tutorial/test_response_change_status_code/test_tutorial001.py index 8ce3dcf1ab..05d5ca619f 100644 --- a/tests/test_tutorial/test_response_change_status_code/test_tutorial001.py +++ b/tests/test_tutorial/test_response_change_status_code/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_change_status_code.tutorial001 import app +from docs_src.response_change_status_code.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_cookies/test_tutorial001.py b/tests/test_tutorial/test_response_cookies/test_tutorial001.py index eecd1a24c9..6b931c8bda 100644 --- a/tests/test_tutorial/test_response_cookies/test_tutorial001.py +++ b/tests/test_tutorial/test_response_cookies/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_cookies.tutorial001 import app +from docs_src.response_cookies.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_cookies/test_tutorial002.py b/tests/test_tutorial/test_response_cookies/test_tutorial002.py index 3e390025fa..3ee5f500c5 100644 --- a/tests/test_tutorial/test_response_cookies/test_tutorial002.py +++ b/tests/test_tutorial/test_response_cookies/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_cookies.tutorial002 import app +from docs_src.response_cookies.tutorial002_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_directly/test_tutorial001.py b/tests/test_tutorial/test_response_directly/test_tutorial001.py index 2cc4f3b0c1..127f0e4c1d 100644 --- a/tests/test_tutorial/test_response_directly/test_tutorial001.py +++ b/tests/test_tutorial/test_response_directly/test_tutorial001.py @@ -9,7 +9,7 @@ from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="client", params=[ - pytest.param("tutorial001"), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_headers/test_tutorial001.py b/tests/test_tutorial/test_response_headers/test_tutorial001.py index 1549d6b5b1..6232aad23e 100644 --- a/tests/test_tutorial/test_response_headers/test_tutorial001.py +++ b/tests/test_tutorial/test_response_headers/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_headers.tutorial001 import app +from docs_src.response_headers.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_headers/test_tutorial002.py b/tests/test_tutorial/test_response_headers/test_tutorial002.py index 2826833f84..2ac2226cb1 100644 --- a/tests/test_tutorial/test_response_headers/test_tutorial002.py +++ b/tests/test_tutorial/test_response_headers/test_tutorial002.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_headers.tutorial002 import app +from docs_src.response_headers.tutorial002_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_model/test_tutorial003.py b/tests/test_tutorial/test_response_model/test_tutorial003.py index 70cfd6e4cc..0f9eac890b 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003.py @@ -10,7 +10,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003", + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_01.py b/tests/test_tutorial/test_response_model/test_tutorial003_01.py index 3975856b6c..1a7ce4c7a1 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003_01.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003_01.py @@ -10,7 +10,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003_01", + pytest.param("tutorial003_01_py39"), pytest.param("tutorial003_01_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_02.py b/tests/test_tutorial/test_response_model/test_tutorial003_02.py index eabd203456..b7507b7110 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003_02.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003_02.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_model.tutorial003_02 import app +from docs_src.response_model.tutorial003_02_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_03.py b/tests/test_tutorial/test_response_model/test_tutorial003_03.py index 970ff58450..ea3c733b24 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003_03.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003_03.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.response_model.tutorial003_03 import app +from docs_src.response_model.tutorial003_03_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_04.py b/tests/test_tutorial/test_response_model/test_tutorial003_04.py index f32e93ddcb..145af126fd 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003_04.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003_04.py @@ -9,7 +9,7 @@ from ...utils import needs_py310 @pytest.mark.parametrize( "module_name", [ - "tutorial003_04", + pytest.param("tutorial003_04_py39"), pytest.param("tutorial003_04_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_model/test_tutorial003_05.py b/tests/test_tutorial/test_response_model/test_tutorial003_05.py index 9500852e15..19a7c601bb 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial003_05.py +++ b/tests/test_tutorial/test_response_model/test_tutorial003_05.py @@ -9,7 +9,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003_05", + pytest.param("tutorial003_05_py39"), pytest.param("tutorial003_05_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_model/test_tutorial004.py b/tests/test_tutorial/test_response_model/test_tutorial004.py index 449a52b813..19f6998f70 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial004.py +++ b/tests/test_tutorial/test_response_model/test_tutorial004.py @@ -4,14 +4,13 @@ import pytest from dirty_equals import IsDict, IsOneOf from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial004", - pytest.param("tutorial004_py39", marks=needs_py39), + pytest.param("tutorial004_py39"), pytest.param("tutorial004_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_model/test_tutorial005.py b/tests/test_tutorial/test_response_model/test_tutorial005.py index a633a3fddd..47d77dc498 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial005.py +++ b/tests/test_tutorial/test_response_model/test_tutorial005.py @@ -10,7 +10,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial005", + pytest.param("tutorial005_py39"), pytest.param("tutorial005_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_response_model/test_tutorial006.py b/tests/test_tutorial/test_response_model/test_tutorial006.py index 863522d1b4..a03aa41e8c 100644 --- a/tests/test_tutorial/test_response_model/test_tutorial006.py +++ b/tests/test_tutorial/test_response_model/test_tutorial006.py @@ -10,7 +10,7 @@ from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial006", + pytest.param("tutorial006_py39"), pytest.param("tutorial006_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_schema_extra_example/test_tutorial001.py b/tests/test_tutorial/test_schema_extra_example/test_tutorial001.py index c21cbb4bc2..4d1808cf6a 100644 --- a/tests/test_tutorial/test_schema_extra_example/test_tutorial001.py +++ b/tests/test_tutorial/test_schema_extra_example/test_tutorial001.py @@ -9,7 +9,7 @@ from ...utils import needs_py310, needs_pydanticv2 @pytest.fixture( name="client", params=[ - "tutorial001", + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1.py b/tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1.py index b79f42e642..552bb66970 100644 --- a/tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1.py +++ b/tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1.py @@ -9,7 +9,7 @@ from ...utils import needs_py310, needs_pydanticv1 @pytest.fixture( name="client", params=[ - "tutorial001_pv1", + pytest.param("tutorial001_pv1_py39"), pytest.param("tutorial001_pv1_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py b/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py index 61aefd12a8..47ecb9ba73 100644 --- a/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py +++ b/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial004", + pytest.param("tutorial004_py39"), pytest.param("tutorial004_py310", marks=needs_py310), - "tutorial004_an", - pytest.param("tutorial004_an_py39", marks=needs_py39), + pytest.param("tutorial004_an_py39"), pytest.param("tutorial004_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_schema_extra_example/test_tutorial005.py b/tests/test_tutorial/test_schema_extra_example/test_tutorial005.py index 12859227b1..1c964f3d15 100644 --- a/tests/test_tutorial/test_schema_extra_example/test_tutorial005.py +++ b/tests/test_tutorial/test_schema_extra_example/test_tutorial005.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial005", + pytest.param("tutorial005_py39"), pytest.param("tutorial005_py310", marks=needs_py310), - "tutorial005_an", - pytest.param("tutorial005_an_py39", marks=needs_py39), + pytest.param("tutorial005_an_py39"), pytest.param("tutorial005_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_security/test_tutorial001.py b/tests/test_tutorial/test_security/test_tutorial001.py index f572d6e3e1..cdaa50b191 100644 --- a/tests/test_tutorial/test_security/test_tutorial001.py +++ b/tests/test_tutorial/test_security/test_tutorial001.py @@ -3,15 +3,12 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial001", - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_py39"), + pytest.param("tutorial001_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_security/test_tutorial003.py b/tests/test_tutorial/test_security/test_tutorial003.py index 6b87351139..000c8b2ac4 100644 --- a/tests/test_tutorial/test_security/test_tutorial003.py +++ b/tests/test_tutorial/test_security/test_tutorial003.py @@ -4,16 +4,15 @@ import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="client", params=[ - "tutorial003", + pytest.param("tutorial003_py39"), pytest.param("tutorial003_py310", marks=needs_py310), - "tutorial003_an", - pytest.param("tutorial003_an_py39", marks=needs_py39), + pytest.param("tutorial003_an_py39"), pytest.param("tutorial003_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_security/test_tutorial005.py b/tests/test_tutorial/test_security/test_tutorial005.py index ad644d61bb..7953e8e3f6 100644 --- a/tests/test_tutorial/test_security/test_tutorial005.py +++ b/tests/test_tutorial/test_security/test_tutorial005.py @@ -5,17 +5,15 @@ import pytest from dirty_equals import IsDict, IsOneOf from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="mod", params=[ - "tutorial005", + pytest.param("tutorial005_py39"), pytest.param("tutorial005_py310", marks=needs_py310), - "tutorial005_an", - pytest.param("tutorial005_py39", marks=needs_py39), - pytest.param("tutorial005_an_py39", marks=needs_py39), + pytest.param("tutorial005_an_py39"), pytest.param("tutorial005_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_security/test_tutorial006.py b/tests/test_tutorial/test_security/test_tutorial006.py index 9587159dc2..a4b3104bbc 100644 --- a/tests/test_tutorial/test_security/test_tutorial006.py +++ b/tests/test_tutorial/test_security/test_tutorial006.py @@ -4,15 +4,12 @@ from base64 import b64encode import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="client", params=[ - "tutorial006", - "tutorial006_an", - pytest.param("tutorial006_an_py39", marks=needs_py39), + pytest.param("tutorial006_py39"), + pytest.param("tutorial006_an_py39"), ], ) def get_client(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py index 059fb889b3..b59d799a31 100644 --- a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py +++ b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py @@ -3,15 +3,14 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv2 @pytest.fixture( name="client", params=[ - "tutorial001", + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - pytest.param("tutorial001_py39", marks=needs_py39), ], ) def get_client(request: pytest.FixtureRequest) -> TestClient: diff --git a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial002.py b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial002.py index cc9afeab75..61fbacfc34 100644 --- a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial002.py +++ b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial002.py @@ -3,15 +3,14 @@ import importlib import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39, needs_py310, needs_pydanticv2 +from ...utils import needs_py310, needs_pydanticv2 @pytest.fixture( name="client", params=[ - "tutorial002", + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), - pytest.param("tutorial002_py39", marks=needs_py39), ], ) def get_client(request: pytest.FixtureRequest) -> TestClient: diff --git a/tests/test_tutorial/test_settings/test_app02.py b/tests/test_tutorial/test_settings/test_app02.py index 5e1232ea01..9cedc5a526 100644 --- a/tests/test_tutorial/test_settings/test_app02.py +++ b/tests/test_tutorial/test_settings/test_app02.py @@ -4,15 +4,14 @@ from types import ModuleType import pytest from pytest import MonkeyPatch -from ...utils import needs_py39, needs_pydanticv2 +from ...utils import needs_pydanticv2 @pytest.fixture( name="mod_path", params=[ - pytest.param("app02"), - pytest.param("app02_an"), - pytest.param("app02_an_py39", marks=needs_py39), + pytest.param("app02_py39"), + pytest.param("app02_an_py39"), ], ) def get_mod_path(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_settings/test_app03.py b/tests/test_tutorial/test_settings/test_app03.py index d9872c15f2..dbaf8f3f90 100644 --- a/tests/test_tutorial/test_settings/test_app03.py +++ b/tests/test_tutorial/test_settings/test_app03.py @@ -5,15 +5,14 @@ import pytest from fastapi.testclient import TestClient from pytest import MonkeyPatch -from ...utils import needs_py39, needs_pydanticv1, needs_pydanticv2 +from ...utils import needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="mod_path", params=[ - pytest.param("app03"), - pytest.param("app03_an"), - pytest.param("app03_an_py39", marks=needs_py39), + pytest.param("app03_py39"), + pytest.param("app03_an_py39"), ], ) def get_mod_path(request: pytest.FixtureRequest): diff --git a/tests/test_tutorial/test_settings/test_tutorial001.py b/tests/test_tutorial/test_settings/test_tutorial001.py index 92a5782d4d..2c6dce261f 100644 --- a/tests/test_tutorial/test_settings/test_tutorial001.py +++ b/tests/test_tutorial/test_settings/test_tutorial001.py @@ -10,8 +10,8 @@ from ...utils import needs_pydanticv1, needs_pydanticv2 @pytest.fixture( name="app", params=[ - pytest.param("tutorial001", marks=needs_pydanticv2), - pytest.param("tutorial001_pv1", marks=needs_pydanticv1), + pytest.param("tutorial001_py39", marks=needs_pydanticv2), + pytest.param("tutorial001_pv1_py39", marks=needs_pydanticv1), ], ) def get_app(request: pytest.FixtureRequest, monkeypatch: MonkeyPatch): diff --git a/tests/test_tutorial/test_sql_databases/test_tutorial001.py b/tests/test_tutorial/test_sql_databases/test_tutorial001.py index b45be4884d..e3e6bac128 100644 --- a/tests/test_tutorial/test_sql_databases/test_tutorial001.py +++ b/tests/test_tutorial/test_sql_databases/test_tutorial001.py @@ -9,7 +9,7 @@ from sqlalchemy import StaticPool from sqlmodel import SQLModel, create_engine from sqlmodel.main import default_registry -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 def clear_sqlmodel(): @@ -22,11 +22,9 @@ def clear_sqlmodel(): @pytest.fixture( name="client", params=[ - "tutorial001", - pytest.param("tutorial001_py39", marks=needs_py39), + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_sql_databases/test_tutorial002.py b/tests/test_tutorial/test_sql_databases/test_tutorial002.py index da0b8b7ce7..e3b8c7f9e4 100644 --- a/tests/test_tutorial/test_sql_databases/test_tutorial002.py +++ b/tests/test_tutorial/test_sql_databases/test_tutorial002.py @@ -9,7 +9,7 @@ from sqlalchemy import StaticPool from sqlmodel import SQLModel, create_engine from sqlmodel.main import default_registry -from tests.utils import needs_py39, needs_py310 +from tests.utils import needs_py310 def clear_sqlmodel(): @@ -22,11 +22,9 @@ def clear_sqlmodel(): @pytest.fixture( name="client", params=[ - "tutorial002", - pytest.param("tutorial002_py39", marks=needs_py39), + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), - "tutorial002_an", - pytest.param("tutorial002_an_py39", marks=needs_py39), + pytest.param("tutorial002_an_py39"), pytest.param("tutorial002_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_sub_applications/test_tutorial001.py b/tests/test_tutorial/test_sub_applications/test_tutorial001.py index 0790d207be..ef1f80164b 100644 --- a/tests/test_tutorial/test_sub_applications/test_tutorial001.py +++ b/tests/test_tutorial/test_sub_applications/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.sub_applications.tutorial001 import app +from docs_src.sub_applications.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_templates/test_tutorial001.py b/tests/test_tutorial/test_templates/test_tutorial001.py index 4d4729425e..818508037d 100644 --- a/tests/test_tutorial/test_templates/test_tutorial001.py +++ b/tests/test_tutorial/test_templates/test_tutorial001.py @@ -11,7 +11,7 @@ def test_main(): shutil.rmtree("./templates") shutil.copytree("./docs_src/templates/templates/", "./templates") shutil.copytree("./docs_src/templates/static/", "./static") - from docs_src.templates.tutorial001 import app + from docs_src.templates.tutorial001_py39 import app client = TestClient(app) response = client.get("/items/foo") diff --git a/tests/test_tutorial/test_testing/test_main.py b/tests/test_tutorial/test_testing/test_main_a.py similarity index 90% rename from tests/test_tutorial/test_testing/test_main.py rename to tests/test_tutorial/test_testing/test_main_a.py index fe34980813..9b3c796bdc 100644 --- a/tests/test_tutorial/test_testing/test_main.py +++ b/tests/test_tutorial/test_testing/test_main_a.py @@ -1,4 +1,4 @@ -from docs_src.app_testing.test_main import client, test_read_main +from docs_src.app_testing.app_a_py39.test_main import client, test_read_main def test_main(): diff --git a/tests/test_tutorial/test_testing/test_main_b.py b/tests/test_tutorial/test_testing/test_main_b.py index aa7f969c6d..3d679cd5a6 100644 --- a/tests/test_tutorial/test_testing/test_main_b.py +++ b/tests/test_tutorial/test_testing/test_main_b.py @@ -3,16 +3,15 @@ from types import ModuleType import pytest -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="test_module", params=[ - "app_b.test_main", + "app_b_py39.test_main", pytest.param("app_b_py310.test_main", marks=needs_py310), - "app_b_an.test_main", - pytest.param("app_b_an_py39.test_main", marks=needs_py39), + "app_b_an_py39.test_main", pytest.param("app_b_an_py310.test_main", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_testing/test_tutorial001.py b/tests/test_tutorial/test_testing/test_tutorial001.py index 471e896c93..5f6533306e 100644 --- a/tests/test_tutorial/test_testing/test_tutorial001.py +++ b/tests/test_tutorial/test_testing/test_tutorial001.py @@ -1,4 +1,4 @@ -from docs_src.app_testing.tutorial001 import client, test_read_main +from docs_src.app_testing.tutorial001_py39 import client, test_read_main def test_main(): diff --git a/tests/test_tutorial/test_testing/test_tutorial002.py b/tests/test_tutorial/test_testing/test_tutorial002.py index ec4f91ee7f..cc9b5ba27c 100644 --- a/tests/test_tutorial/test_testing/test_tutorial002.py +++ b/tests/test_tutorial/test_testing/test_tutorial002.py @@ -1,4 +1,4 @@ -from docs_src.app_testing.tutorial002 import test_read_main, test_websocket +from docs_src.app_testing.tutorial002_py39 import test_read_main, test_websocket def test_main(): diff --git a/tests/test_tutorial/test_testing/test_tutorial003.py b/tests/test_tutorial/test_testing/test_tutorial003.py index 2a5d670712..4faa820e98 100644 --- a/tests/test_tutorial/test_testing/test_tutorial003.py +++ b/tests/test_tutorial/test_testing/test_tutorial003.py @@ -3,5 +3,5 @@ import pytest def test_main(): with pytest.warns(DeprecationWarning): - from docs_src.app_testing.tutorial003 import test_read_items + from docs_src.app_testing.tutorial003_py39 import test_read_items test_read_items() diff --git a/tests/test_tutorial/test_testing/test_tutorial004.py b/tests/test_tutorial/test_testing/test_tutorial004.py index 812ee44c1f..c95214ffe3 100644 --- a/tests/test_tutorial/test_testing/test_tutorial004.py +++ b/tests/test_tutorial/test_testing/test_tutorial004.py @@ -1,4 +1,4 @@ -from docs_src.app_testing.tutorial004 import test_read_items +from docs_src.app_testing.tutorial004_py39 import test_read_items def test_main(): diff --git a/tests/test_tutorial/test_testing_dependencies/test_tutorial001.py b/tests/test_tutorial/test_testing_dependencies/test_tutorial001.py index 00ee6ab1ea..6e9656bf55 100644 --- a/tests/test_tutorial/test_testing_dependencies/test_tutorial001.py +++ b/tests/test_tutorial/test_testing_dependencies/test_tutorial001.py @@ -3,16 +3,15 @@ from types import ModuleType import pytest -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="test_module", params=[ - "tutorial001", + pytest.param("tutorial001_py39"), pytest.param("tutorial001_py310", marks=needs_py310), - "tutorial001_an", - pytest.param("tutorial001_an_py39", marks=needs_py39), + pytest.param("tutorial001_an_py39"), pytest.param("tutorial001_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_using_request_directly/test_tutorial001.py b/tests/test_tutorial/test_using_request_directly/test_tutorial001.py index 54c53ae1e3..33e661b164 100644 --- a/tests/test_tutorial/test_using_request_directly/test_tutorial001.py +++ b/tests/test_tutorial/test_using_request_directly/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.using_request_directly.tutorial001 import app +from docs_src.using_request_directly.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_websockets/test_tutorial001.py b/tests/test_tutorial/test_websockets/test_tutorial001.py index 7dbecb2650..4f8368db28 100644 --- a/tests/test_tutorial/test_websockets/test_tutorial001.py +++ b/tests/test_tutorial/test_websockets/test_tutorial001.py @@ -2,7 +2,7 @@ import pytest from fastapi.testclient import TestClient from fastapi.websockets import WebSocketDisconnect -from docs_src.websockets.tutorial001 import app +from docs_src.websockets.tutorial001_py39 import app client = TestClient(app) diff --git a/tests/test_tutorial/test_websockets/test_tutorial002.py b/tests/test_tutorial/test_websockets/test_tutorial002.py index 51aa5752a6..ebf1fc8e81 100644 --- a/tests/test_tutorial/test_websockets/test_tutorial002.py +++ b/tests/test_tutorial/test_websockets/test_tutorial002.py @@ -5,16 +5,15 @@ from fastapi import FastAPI from fastapi.testclient import TestClient from fastapi.websockets import WebSocketDisconnect -from ...utils import needs_py39, needs_py310 +from ...utils import needs_py310 @pytest.fixture( name="app", params=[ - "tutorial002", + pytest.param("tutorial002_py39"), pytest.param("tutorial002_py310", marks=needs_py310), - "tutorial002_an", - pytest.param("tutorial002_an_py39", marks=needs_py39), + pytest.param("tutorial002_an_py39"), pytest.param("tutorial002_an_py310", marks=needs_py310), ], ) diff --git a/tests/test_tutorial/test_websockets/test_tutorial003.py b/tests/test_tutorial/test_websockets/test_tutorial003.py index 85efc18590..f303990f03 100644 --- a/tests/test_tutorial/test_websockets/test_tutorial003.py +++ b/tests/test_tutorial/test_websockets/test_tutorial003.py @@ -4,14 +4,11 @@ from types import ModuleType import pytest from fastapi.testclient import TestClient -from ...utils import needs_py39 - @pytest.fixture( name="mod", params=[ - pytest.param("tutorial003"), - pytest.param("tutorial003_py39", marks=needs_py39), + pytest.param("tutorial003_py39"), ], ) def get_mod(request: pytest.FixtureRequest): @@ -32,13 +29,11 @@ def get_client(mod: ModuleType): return client -@needs_py39 def test_get(client: TestClient, html: str): response = client.get("/") assert response.text == html -@needs_py39 def test_websocket_handle_disconnection(client: TestClient): with client.websocket_connect("/ws/1234") as connection, client.websocket_connect( "/ws/5678" diff --git a/tests/test_tutorial/test_wsgi/test_tutorial001.py b/tests/test_tutorial/test_wsgi/test_tutorial001.py index 4f82252739..9fe8c2a4b8 100644 --- a/tests/test_tutorial/test_wsgi/test_tutorial001.py +++ b/tests/test_tutorial/test_wsgi/test_tutorial001.py @@ -1,6 +1,6 @@ from fastapi.testclient import TestClient -from docs_src.wsgi.tutorial001 import app +from docs_src.wsgi.tutorial001_py39 import app client = TestClient(app)