From 8fa18e5e6ff5ae6bb620bf4a7bd0d1964f10f2de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro?= Date: Wed, 22 Jan 2025 10:41:56 -0300 Subject: [PATCH 01/14] =?UTF-8?q?=F0=9F=8C=90=20Update=20Portuguese=20Tran?= =?UTF-8?q?slation=20for=20`docs/pt/docs/tutorial/request-forms.md`=20(#13?= =?UTF-8?q?216)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pt/docs/tutorial/request-forms.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/pt/docs/tutorial/request-forms.md b/docs/pt/docs/tutorial/request-forms.md index 756ceb581..572ddf003 100644 --- a/docs/pt/docs/tutorial/request-forms.md +++ b/docs/pt/docs/tutorial/request-forms.md @@ -6,7 +6,11 @@ Quando você precisar receber campos de formulário ao invés de JSON, você pod Para usar formulários, primeiro instale `python-multipart`. -Ex: `pip install python-multipart`. +Lembre-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e então instalar a dependência, por exemplo: + +```console +$ pip install python-multipart +``` /// From a215687c987ea882ef6c4f0788b6c5a8b71f75ff Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 22 Jan 2025 13:42:19 +0000 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index a242407ea..5f527d37b 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -49,6 +49,7 @@ hide: ### Translations +* 🌐 Update Portuguese Translation for `docs/pt/docs/tutorial/request-forms.md`. PR [#13216](https://github.com/fastapi/fastapi/pull/13216) by [@Joao-Pedro-P-Holanda](https://github.com/Joao-Pedro-P-Holanda). * 🌐 Update Portuguese translation for `docs/pt/docs/advanced/settings.md`. PR [#13209](https://github.com/fastapi/fastapi/pull/13209) by [@ceb10n](https://github.com/ceb10n). * 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/security/oauth2-jwt.md`. PR [#13205](https://github.com/fastapi/fastapi/pull/13205) by [@ceb10n](https://github.com/ceb10n). * 🌐 Add Indonesian translation for `docs/id/docs/index.md`. PR [#13191](https://github.com/fastapi/fastapi/pull/13191) by [@gerry-sabar](https://github.com/gerry-sabar). From 548f67d465afff233fa1856b2d337d13595e3308 Mon Sep 17 00:00:00 2001 From: Daniel Kusy <36250676+DanielKusyDev@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:02:36 +0100 Subject: [PATCH 03/14] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20`jinja2`?= =?UTF-8?q?=20to=20>=3D3.1.5=20(#13194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index edfa81522..ae56ebb7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,7 +60,7 @@ standard = [ # For the test client "httpx >=0.23.0", # For templates - "jinja2 >=2.11.2", + "jinja2 >=3.1.5", # For forms and file uploads "python-multipart >=0.0.7", # To validate email fields @@ -79,7 +79,7 @@ all = [ # # For the test client "httpx >=0.23.0", # For templates - "jinja2 >=2.11.2", + "jinja2 >=3.1.5", # For forms and file uploads "python-multipart >=0.0.7", # For Starlette's SessionMiddleware, not commonly used with FastAPI From 1a38cc506e5732a8a0e2d4cfec3059f670a5ef90 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 22 Jan 2025 18:03:00 +0000 Subject: [PATCH 04/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 5f527d37b..d982a15f2 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -33,6 +33,10 @@ hide: * ✅ Simplify tests for background_tasks. PR [#13166](https://github.com/fastapi/fastapi/pull/13166) by [@alejsdev](https://github.com/alejsdev). * ✅ Simplify tests for additional_status_codes. PR [#13149](https://github.com/fastapi/fastapi/pull/13149) by [@tiangolo](https://github.com/tiangolo). +### Upgrades + +* ⬆️ Upgrade `jinja2` to >=3.1.5. PR [#13194](https://github.com/fastapi/fastapi/pull/13194) by [@DanielKusyDev](https://github.com/DanielKusyDev). + ### Docs * ✏️ Update Strawberry integration docs. PR [#13155](https://github.com/fastapi/fastapi/pull/13155) by [@kinuax](https://github.com/kinuax). From 82c74789e8c2ba68f4c88b6e8c80928881578272 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Wed, 22 Jan 2025 19:21:40 +0100 Subject: [PATCH 05/14] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20Starlette=20t?= =?UTF-8?q?o=20allow=20up=20to=200.45.0:=20`>=3D0.40.0,<0.46.0`=20(#13117)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ae56ebb7e..9510d36c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", ] dependencies = [ - "starlette>=0.40.0,<0.42.0", + "starlette>=0.40.0,<0.46.0", "pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0", "typing-extensions>=4.8.0", ] From 91c05b9245269502ea3d28569b3cbe2fa556e465 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 22 Jan 2025 18:22:02 +0000 Subject: [PATCH 06/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index d982a15f2..1951d6559 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -35,6 +35,7 @@ hide: ### Upgrades +* ⬆️ Bump Starlette to allow up to 0.45.0: `>=0.40.0,<0.46.0`. PR [#13117](https://github.com/fastapi/fastapi/pull/13117) by [@Kludex](https://github.com/Kludex). * ⬆️ Upgrade `jinja2` to >=3.1.5. PR [#13194](https://github.com/fastapi/fastapi/pull/13194) by [@DanielKusyDev](https://github.com/DanielKusyDev). ### Docs From 49e82ed2ac63c2aad957d01c857ee1fe597dc4ca Mon Sep 17 00:00:00 2001 From: Daniel Kusy <36250676+DanielKusyDev@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:23:13 +0100 Subject: [PATCH 07/14] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20`python-mu?= =?UTF-8?q?ltipart`=20to=20>=3D0.0.18=20(#13219)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9510d36c3..6fa0f080f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ standard = [ # For templates "jinja2 >=3.1.5", # For forms and file uploads - "python-multipart >=0.0.7", + "python-multipart >=0.0.18", # To validate email fields "email-validator >=2.0.0", # Uvicorn with uvloop @@ -81,7 +81,7 @@ all = [ # For templates "jinja2 >=3.1.5", # For forms and file uploads - "python-multipart >=0.0.7", + "python-multipart >=0.0.18", # For Starlette's SessionMiddleware, not commonly used with FastAPI "itsdangerous >=1.1.0", # For Starlette's schema generation, would not be used with FastAPI From e39143d56de41f8d72a3be8847030346cb1d8adc Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 22 Jan 2025 18:24:12 +0000 Subject: [PATCH 08/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 1951d6559..a806930f5 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -35,6 +35,7 @@ hide: ### Upgrades +* ⬆️ Upgrade `python-multipart` to >=0.0.18. PR [#13219](https://github.com/fastapi/fastapi/pull/13219) by [@DanielKusyDev](https://github.com/DanielKusyDev). * ⬆️ Bump Starlette to allow up to 0.45.0: `>=0.40.0,<0.46.0`. PR [#13117](https://github.com/fastapi/fastapi/pull/13117) by [@Kludex](https://github.com/Kludex). * ⬆️ Upgrade `jinja2` to >=3.1.5. PR [#13194](https://github.com/fastapi/fastapi/pull/13194) by [@DanielKusyDev](https://github.com/DanielKusyDev). From abd05a6d30e6e4c9b1496e0b94d362a9979c9f37 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 22 Jan 2025 13:24:58 -0500 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=94=A7=20Add=20Pydantic=202=20trove?= =?UTF-8?q?=20classifier=20(#13199)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 6fa0f080f..381eb50bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ classifiers = [ "Framework :: FastAPI", "Framework :: Pydantic", "Framework :: Pydantic :: 1", + "Framework :: Pydantic :: 2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3 :: Only", From 2b6f63df712f0ab98f071f64b3f8ac215ddf43be Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 22 Jan 2025 18:25:24 +0000 Subject: [PATCH 10/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index a806930f5..13976b788 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -110,6 +110,7 @@ hide: ### Internal +* 🔧 Add Pydantic 2 trove classifier. PR [#13199](https://github.com/fastapi/fastapi/pull/13199) by [@johnthagen](https://github.com/johnthagen). * 👥 Update FastAPI People - Sponsors. PR [#13231](https://github.com/fastapi/fastapi/pull/13231) by [@tiangolo](https://github.com/tiangolo). * 👷 Refactor FastAPI People Sponsors to use 2 tokens. PR [#13228](https://github.com/fastapi/fastapi/pull/13228) by [@tiangolo](https://github.com/tiangolo). * 👷 Update token for FastAPI People - Sponsors. PR [#13225](https://github.com/fastapi/fastapi/pull/13225) by [@tiangolo](https://github.com/tiangolo). From 7183f0d683558390b973af8ad708e82567d4dc7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 22 Jan 2025 22:48:57 +0000 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 13976b788..c7f01b82f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,12 @@ hide: ## Latest Changes +### Upgrades + +* ⬆️ Upgrade `python-multipart` to >=0.0.18. PR [#13219](https://github.com/fastapi/fastapi/pull/13219) by [@DanielKusyDev](https://github.com/DanielKusyDev). +* ⬆️ Bump Starlette to allow up to 0.45.0: `>=0.40.0,<0.46.0`. PR [#13117](https://github.com/fastapi/fastapi/pull/13117) by [@Kludex](https://github.com/Kludex). +* ⬆️ Upgrade `jinja2` to >=3.1.5. PR [#13194](https://github.com/fastapi/fastapi/pull/13194) by [@DanielKusyDev](https://github.com/DanielKusyDev). + ### Refactors * ✅ Simplify tests for websockets. PR [#13202](https://github.com/fastapi/fastapi/pull/13202) by [@alejsdev](https://github.com/alejsdev). @@ -33,12 +39,6 @@ hide: * ✅ Simplify tests for background_tasks. PR [#13166](https://github.com/fastapi/fastapi/pull/13166) by [@alejsdev](https://github.com/alejsdev). * ✅ Simplify tests for additional_status_codes. PR [#13149](https://github.com/fastapi/fastapi/pull/13149) by [@tiangolo](https://github.com/tiangolo). -### Upgrades - -* ⬆️ Upgrade `python-multipart` to >=0.0.18. PR [#13219](https://github.com/fastapi/fastapi/pull/13219) by [@DanielKusyDev](https://github.com/DanielKusyDev). -* ⬆️ Bump Starlette to allow up to 0.45.0: `>=0.40.0,<0.46.0`. PR [#13117](https://github.com/fastapi/fastapi/pull/13117) by [@Kludex](https://github.com/Kludex). -* ⬆️ Upgrade `jinja2` to >=3.1.5. PR [#13194](https://github.com/fastapi/fastapi/pull/13194) by [@DanielKusyDev](https://github.com/DanielKusyDev). - ### Docs * ✏️ Update Strawberry integration docs. PR [#13155](https://github.com/fastapi/fastapi/pull/13155) by [@kinuax](https://github.com/kinuax). From fe513719ea98abade167d8a89e92f600d9d8f0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 22 Jan 2025 22:50:29 +0000 Subject: [PATCH 12/14] =?UTF-8?q?=F0=9F=94=96=20Release=20version=200.115.?= =?UTF-8?q?7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 ++ fastapi/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index c7f01b82f..c8a75756b 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,8 @@ hide: ## Latest Changes +## 0.115.7 + ### Upgrades * ⬆️ Upgrade `python-multipart` to >=0.0.18. PR [#13219](https://github.com/fastapi/fastapi/pull/13219) by [@DanielKusyDev](https://github.com/DanielKusyDev). diff --git a/fastapi/__init__.py b/fastapi/__init__.py index 823957822..c92279cfd 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.115.6" +__version__ = "0.115.7" from starlette import status as status From 4d60022c88e6ba92a89df4860ba2df3af7e8c926 Mon Sep 17 00:00:00 2001 From: alv2017 Date: Thu, 23 Jan 2025 11:46:41 +0200 Subject: [PATCH 13/14] =?UTF-8?q?=F0=9F=8C=90=20Add=20Russian=20translatio?= =?UTF-8?q?n=20for=20`docs/ru/docs/tutorial/bigger-applications.md`=20(#13?= =?UTF-8?q?154)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ru/docs/tutorial/bigger-applications.md | 556 +++++++++++++++++++ 1 file changed, 556 insertions(+) create mode 100644 docs/ru/docs/tutorial/bigger-applications.md diff --git a/docs/ru/docs/tutorial/bigger-applications.md b/docs/ru/docs/tutorial/bigger-applications.md new file mode 100644 index 000000000..7c3dc288f --- /dev/null +++ b/docs/ru/docs/tutorial/bigger-applications.md @@ -0,0 +1,556 @@ +# Большие приложения, в которых много файлов + +При построении приложения или веб-API нам редко удается поместить всё в один файл. + +**FastAPI** предоставляет удобный инструментарий, который позволяет нам структурировать приложение, сохраняя при этом всю необходимую гибкость. + +/// info | Примечание + +Если вы раньше использовали Flask, то это аналог шаблонов Flask (Flask's Blueprints). + +/// + +## Пример структуры приложения + +Давайте предположим, что наше приложение имеет следующую структуру: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +│   ├── dependencies.py +│   └── routers +│   │ ├── __init__.py +│   │ ├── items.py +│   │ └── users.py +│   └── internal +│   ├── __init__.py +│   └── admin.py +``` + +/// tip | Подсказка + +Обратите внимание, что в каждом каталоге и подкаталоге имеется файл `__init__.py` + +Это как раз то, что позволяет импортировать код из одного файла в другой. + +Например, в файле `app/main.py` может быть следующая строка: + +``` +from app.routers import items +``` + +/// + +* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией модулей Python). +* Он содержит файл `app/main.py`. Данный файл является частью пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем пакета: `app.main`. +* Он также содержит файл `app/dependencies.py`, который также, как и `app/main.py`, является модулем: `app.dependencies`. +* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`. Он является суб-пакетом: `app.routers`. +* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является суб-модулем: `app.routers.items`. +* Точно также `app/routers/users.py` является ещё одним суб-модулем: `app.routers.users`. +* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним суб-пакетом: `app.internal`. +* А файл `app/internal/admin.py` является ещё одним суб-модулем: `app.internal.admin`. + + + +Та же самая файловая структура приложения, но с комментариями: + +``` +. +├── app # "app" пакет +│   ├── __init__.py # этот файл превращает "app" в "Python-пакет" +│   ├── main.py # модуль "main", напр.: import app.main +│   ├── dependencies.py # модуль "dependencies", напр.: import app.dependencies +│   └── routers # суб-пакет "routers" +│   │ ├── __init__.py # превращает "routers" в суб-пакет +│   │ ├── items.py # суб-модуль "items", напр.: import app.routers.items +│   │ └── users.py # суб-модуль "users", напр.: import app.routers.users +│   └── internal # суб-пакет "internal" +│   ├── __init__.py # превращает "internal" в суб-пакет +│   └── admin.py # суб-модуль "admin", напр.: import app.internal.admin +``` + +## `APIRouter` + +Давайте предположим, что для работы с пользователями используется отдельный файл (суб-модуль) `/app/routers/users.py`. + +Для лучшей организации приложения, вы хотите отделить операции пути, связанные с пользователями, от остального кода. + +Но так, чтобы эти операции по-прежнему оставались частью **FastAPI** приложения/веб-API (частью одного пакета) + +С помощью `APIRouter` вы можете создать *операции пути* (*эндпоинты*) для данного модуля. + + +### Импорт `APIRouter` + +Точно также, как и в случае с классом `FastAPI`, вам нужно импортировать и создать объект класса `APIRouter`. + +```Python hl_lines="1 3" title="app/routers/users.py" +{!../../docs_src/bigger_applications/app/routers/users.py!} +``` + +### Создание *эндпоинтов* с помощью `APIRouter` + +В дальнейшем используйте `APIRouter` для объявления *эндпоинтов*, точно также, как вы используете класс `FastAPI`: + +```Python hl_lines="6 11 16" title="app/routers/users.py" +{!../../docs_src/bigger_applications/app/routers/users.py!} +``` + +Вы можете думать об `APIRouter` как об "уменьшенной версии" класса FastAPI`. + +`APIRouter` поддерживает все те же самые опции. + +`APIRouter` поддерживает все те же самые параметры, такие как `parameters`, `responses`, `dependencies`, `tags`, и т. д. + +/// tip | Подсказка + +В данном примере, в качестве названия переменной используется `router`, но вы можете использовать любое другое имя. + +/// + +Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и создадим ещё один модуль с `APIRouter`. + +## Зависимости + +Нам понадобятся некоторые зависимости, которые мы будем использовать в разных местах нашего приложения. + +Мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`). + +Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомизированный `X-Token` из заголовка: + +//// tab | Python 3.9+ + +```Python hl_lines="3 6-8" title="app/dependencies.py" +{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!} +``` + +//// + +//// tab | Python 3.8+ + +```Python hl_lines="1 5-7" title="app/dependencies.py" +{!> ../../docs_src/bigger_applications/app_an/dependencies.py!} +``` + +//// + +//// tab | Python 3.8+ non-Annotated + +/// tip | Подсказка + +Мы рекомендуем использовать версию `Annotated`, когда это возможно. + +/// + +```Python hl_lines="1 4-6" title="app/dependencies.py" +{!> ../../docs_src/bigger_applications/app/dependencies.py!} +``` + +//// + +/// tip | Подсказка + +Для простоты мы воспользовались неким воображаемым заголовоком. + +В реальных случаях для получения наилучших результатов используйте интегрированные утилиты обеспечения безопасности [Security utilities](security/index.md){.internal-link target=_blank}. + +/// + +## Ещё один модуль с `APIRouter` + +Давайте также предположим, что у вас есть *эндпоинты*, отвечающие за обработку "items", и они находятся в модуле `app/routers/items.py`. + +У вас определены следующие *операции пути* (*эндпоинты*): + +* `/items/` +* `/items/{item_id}` + +Тут всё точно также, как и в ситуации с `app/routers/users.py`. + +Но теперь мы хотим поступить немного умнее и слегка упростить код. + +Мы знаем, что все *эндпоинты* данного модуля имеют некоторые общие свойства: + +* Префикс пути: `/items`. +* Теги: (один единственный тег: `items`). +* Дополнительные ответы (responses) +* Зависимости: использование созданной нами зависимости `X-token` + +Таким образом, вместо того чтобы добавлять все эти свойства в функцию каждого отдельного *эндпоинта*, +мы добавим их в `APIRouter`. + +```Python hl_lines="5-10 16 21" title="app/routers/items.py" +{!../../docs_src/bigger_applications/app/routers/items.py!} +``` + +Так как каждый *эндпоинт* начинается с символа `/`: + +```Python hl_lines="1" +@router.get("/{item_id}") +async def read_item(item_id: str): + ... +``` + +...то префикс не должен заканчиваться символом `/`. + +В нашем случае префиксом является `/items`. + +Мы также можем добавить в наш маршрутизатор (router) список `тегов` (`tags`) и дополнительных `ответов` (`responses`), которые являются общими для каждого *эндпоинта*. + +И ещё мы можем добавить в наш маршрутизатор список `зависимостей`, которые должны вызываться при каждом обращении к *эндпоинтам*. + +/// tip | Подсказка + +Обратите внимание, что также, как и в случае с зависимостями в декораторах *эндпоинтов* ([dependencies in *path operation decorators*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), никакого значения в *функцию эндпоинта* передано не будет. + +/// + +В результате мы получим следующие эндпоинты: + +* `/items/` +* `/items/{item_id}` + +...как мы и планировали. + +* Они будут помечены тегами из заданного списка, в нашем случае это `"items"`. + * Эти теги особенно полезны для системы автоматической интерактивной документации (с использованием OpenAPI). +* Каждый из них будет включать предопределенные ответы `responses`. +* Каждый *эндпоинт* будет иметь список зависимостей (`dependencies`), исполняемых перед вызовом *эндпоинта*. + * Если вы определили зависимости в самой операции пути, **то она также будет выполнена**. + * Сначала выполняются зависимости маршрутизатора, затем вызываются зависимости, определенные в декораторе *эндпоинта* ([`dependencies` in the decorator](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), и, наконец, обычные параметрические зависимости. + * Вы также можете добавить зависимости безопасности с областями видимости (`scopes`) [`Security` dependencies with `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}. + +/// tip | Подсказка + +Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *эндпоинтов*, не указывая зависимости для каждой отдельной функции *эндпоинта*. + +/// + +/// check | Заметка + +Параметры `prefix`, `tags`, `responses` и `dependencies` относятся к функционалу **FastAPI**, помогающему избежать дублирования кода. + +/// + +### Импорт зависимостей + +Наш код находится в модуле `app.routers.items` (файл `app/routers/items.py`). + +И нам нужно вызвать функцию зависимости из модуля `app.dependencies` (файл `app/dependencies.py`). + +Мы используем операцию относительного импорта `..` для импорта зависимости: + +```Python hl_lines="3" title="app/routers/items.py" +{!../../docs_src/bigger_applications/app/routers/items.py!} +``` + +#### Как работает относительный импорт? + +/// tip | Подсказка + +Если вы прекрасно знаете, как работает импорт в Python, то переходите к следующему разделу. + +/// + +Одна точка `.`, как в данном примере: + +```Python +from .dependencies import get_token_header +``` +означает: + +* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` расположен в каталоге `app/routers/`)... +* ... найдите модуль `dependencies` (файл `app/routers/dependencies.py`)... +* ... и импортируйте из него функцию `get_token_header`. + +К сожалению, такого файла не существует, и наши зависимости находятся в файле `app/dependencies.py`. + +Вспомните, как выглядит файловая структура нашего приложения: + + + +--- + +Две точки `..`, как в данном примере: + +```Python +from ..dependencies import get_token_header +``` + +означают: + +* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)... +* ... перейдите в родительский пакет (каталог `app/`)... +* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)... +* ... и импортируйте из него функцию `get_token_header`. + +Это работает верно! 🎉 + +--- + +Аналогично, если бы мы использовали три точки `...`, как здесь: + +```Python +from ...dependencies import get_token_header +``` + +то это бы означало: + +* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)... +* ... перейдите в родительский пакет (каталог `app/`)... +* ... затем перейдите в родительский пакет текущего пакета (такого пакета не существует, `app` находится на самом верхнем уровне 😱)... +* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)... +* ... и импортируйте из него функцию `get_token_header`. + +Это будет относиться к некоторому пакету, находящемуся на один уровень выше чем `app/` и содержащему свой собственный файл `__init__.py`. Но ничего такого у нас нет. Поэтому это приведет к ошибке в нашем примере. 🚨 + +Теперь вы знаете, как работает импорт в Python, и сможете использовать относительное импортирование в своих собственных приложениях любого уровня сложности. 🤓 + +### Добавление пользовательских тегов (`tags`), ответов (`responses`) и зависимостей (`dependencies`) + +Мы не будем добавлять префикс `/items` и список тегов `tags=["items"]` для каждого *эндпоинта*, т.к. мы уже их добавили с помощью `APIRouter`. + +Но помимо этого мы можем добавить новые теги для каждого отдельного *эндпоинта*, а также некоторые дополнительные ответы (`responses`), характерные для данного *эндпоинта*: + +```Python hl_lines="30-31" title="app/routers/items.py" +{!../../docs_src/bigger_applications/app/routers/items.py!} +``` + +/// tip | Подсказка + +Последний *эндпоинт* будет иметь следующую комбинацию тегов: `["items", "custom"]`. + +А также в его документации будут содержаться оба ответа: один для `404` и другой для `403`. + +/// + +## Модуль main в `FastAPI` + +Теперь давайте посмотрим на модуль `app/main.py`. + +Именно сюда вы импортируете и именно здесь вы используете класс `FastAPI`. + +Это основной файл вашего приложения, который объединяет всё в одно целое. + +И теперь, когда большая часть логики приложения разделена на отдельные модули, основной файл `app/main.py` будет достаточно простым. + +### Импорт `FastAPI` + +Вы импортируете и создаете класс `FastAPI` как обычно. + +Мы даже можем объявить глобальные зависимости [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого отдельного маршрутизатора: + +```Python hl_lines="1 3 7" title="app/main.py" +{!../../docs_src/bigger_applications/app/main.py!} +``` + +### Импорт `APIRouter` + +Теперь мы импортируем другие суб-модули, содержащие `APIRouter`: + +```Python hl_lines="4-5" title="app/main.py" +{!../../docs_src/bigger_applications/app/main.py!} +``` + +Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`. + +### Как работает импорт? + +Данная строка кода: + +```Python +from .routers import items, users +``` + +означает: + +* Начните с пакета, в котором содержится данный модуль (файл `app/main.py` содержится в каталоге `app/`)... +* ... найдите суб-пакет `routers` (каталог `app/routers/`)... +* ... и из него импортируйте суб-модули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)... + +В модуле `items` содержится переменная `router` (`items.router`), та самая, которую мы создали в файле `app/routers/items.py`, она является объектом класса `APIRouter`. + +И затем мы сделаем то же самое для модуля `users`. + +Мы также могли бы импортировать и другим методом: + +```Python +from app.routers import items, users +``` + +/// info | Примечание + +Первая версия является примером относительного импорта: + +```Python +from .routers import items, users +``` + +Вторая версия является примером абсолютного импорта: + +```Python +from app.routers import items, users +``` + +Узнать больше о пакетах и модулях в Python вы можете из официальной документации Python о модулях + +/// + +### Избегайте конфликтов имен + +Вместо того чтобы импортировать только переменную `router`, мы импортируем непосредственно суб-модуль `items`. + +Мы делаем это потому, что у нас есть ещё одна переменная `router` в суб-модуле `users`. + +Если бы мы импортировали их одну за другой, как показано в примере: + +```Python +from .routers.items import router +from .routers.users import router +``` + +то переменная `router` из `users` переписал бы переменную `router` из `items`, и у нас не было бы возможности использовать их одновременно. + +Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули: + +```Python hl_lines="5" title="app/main.py" +{!../../docs_src/bigger_applications/app/main.py!} +``` + +### Подключение маршрутизаторов (`APIRouter`) для `users` и для `items` + +Давайте подключим маршрутизаторы (`router`) из суб-модулей `users` и `items`: + +```Python hl_lines="10-11" title="app/main.py" +{!../../docs_src/bigger_applications/app/main.py!} +``` + +/// info | Примечание + +`users.router` содержит `APIRouter` из файла `app/routers/users.py`. + +А `items.router` содержит `APIRouter` из файла `app/routers/items.py`. + +/// + +С помощью `app.include_router()` мы можем добавить каждый из маршрутизаторов (`APIRouter`) в основное приложение `FastAPI`. + +Он подключит все маршруты заданного маршрутизатора к нашему приложению. + +/// note | Технические детали + +Фактически, внутри он создаст все *операции пути* для каждой операции пути объявленной в `APIRouter`. + +И под капотом всё будет работать так, как будто бы мы имеем дело с одним файлом приложения. + +/// + +/// check | Заметка + +При подключении маршрутизаторов не стоит беспокоиться о производительности. + +Операция подключения займёт микросекунды и понадобится только при запуске приложения. + +Таким образом, это не повлияет на производительность. ⚡ + +/// + +### Подключение `APIRouter` с пользовательскими префиксом (`prefix`), тегами (`tags`), ответами (`responses`), и зависимостями (`dependencies`) + +Теперь давайте представим, что ваша организация передала вам файл `app/internal/admin.py`. + +Он содержит `APIRouter` с некоторыми *эндпоитами* администрирования, которые ваша организация использует для нескольких проектов. + +В данном примере это сделать очень просто. Но давайте предположим, что поскольку файл используется для нескольких проектов, +то мы не можем модифицировать его, добавляя префиксы (`prefix`), зависимости (`dependencies`), теги (`tags`), и т.д. непосредственно в `APIRouter`: + +```Python hl_lines="3" title="app/internal/admin.py" +{!../../docs_src/bigger_applications/app/internal/admin.py!} +``` + +Но, несмотря на это, мы хотим использовать кастомный префикс (`prefix`) для подключенного маршрутизатора (`APIRouter`), в результате чего, каждая *операция пути* будет начинаться с `/admin`. Также мы хотим защитить наш маршрутизатор с помощью зависимостей, созданных для нашего проекта. И ещё мы хотим включить теги (`tags`) и ответы (`responses`). + +Мы можем применить все вышеперечисленные настройки, не изменяя начальный `APIRouter`. Нам всего лишь нужно передать нужные параметры в `app.include_router()`. + +```Python hl_lines="14-17" title="app/main.py" +{!../../docs_src/bigger_applications/app/main.py!} +``` + +Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации. + +В результате, в нашем приложении каждый *эндпоинт* модуля `admin` будет иметь: + +* Префикс `/admin`. +* Тег `admin`. +* Зависимость `get_token_header`. +* Ответ `418`. 🍵 + +Это будет иметь место исключительно для `APIRouter` в нашем приложении, и не затронет любой другой код, использующий его. + +Например, другие проекты, могут использовать тот же самый `APIRouter` с другими методами аутентификации. + +### Подключение отдельного *эндпоинта* + +Мы также можем добавить *эндпоинт* непосредственно в основное приложение `FastAPI`. + +Здесь мы это делаем ... просто, чтобы показать, что это возможно 🤷: + +```Python hl_lines="21-23" title="app/main.py" +{!../../docs_src/bigger_applications/app/main.py!} +``` + +и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`. + +/// info | Сложные технические детали + +**Примечание**: это сложная техническая деталь, которую, скорее всего, **вы можете пропустить**. + +--- + +Маршрутизаторы (`APIRouter`) не "монтируются" по-отдельности и не изолируются от остального приложения. + +Это происходит потому, что нужно включить их *эндпоинты* в OpenAPI схему и в интерфейс пользователя. + +В силу того, что мы не можем их изолировать и "примонтировать" независимо от остальных, *эндпоинты* клонируются (пересоздаются) и не подключаются напрямую. + +/// + +## Проверка автоматической документации API + +Теперь запустите приложение: + +
+ +```console +$ fastapi dev app/main.py + +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +
+ +Откройте документацию по адресу http://127.0.0.1:8000/docs. + +Вы увидите автоматическую API документацию. Она включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги: + + + +## Подключение существующего маршрута через новый префикс (`prefix`) + +Вы можете использовать `.include_router()` несколько раз с одним и тем же маршрутом, применив различные префиксы. + +Это может быть полезным, если нужно предоставить доступ к одному и тому же API через различные префиксы, например, `/api/v1` и `/api/latest`. + +Это продвинутый способ, который вам может и не пригодится. Мы приводим его на случай, если вдруг вам это понадобится. + +## Включение одного маршрутизатора (`APIRouter`) в другой + +Точно так же, как вы включаете `APIRouter` в приложение `FastAPI`, вы можете включить `APIRouter` в другой `APIRouter`: + +```Python +router.include_router(other_router) +``` + +Удостоверьтесь, что вы сделали это до того, как подключить маршрутизатор (`router`) к вашему `FastAPI` приложению, и *эндпоинты* маршрутизатора `other_router` были также подключены. From b6f6818d76f312fe30d798e52fff16927649db0a Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 23 Jan 2025 09:47:05 +0000 Subject: [PATCH 14/14] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index c8a75756b..bc725fafe 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Translations + +* 🌐 Add Russian translation for `docs/ru/docs/tutorial/bigger-applications.md`. PR [#13154](https://github.com/fastapi/fastapi/pull/13154) by [@alv2017](https://github.com/alv2017). + ## 0.115.7 ### Upgrades