mirror of https://github.com/tiangolo/fastapi.git
đ Add Portuguese translation for `docs/pt/docs/tutorial/bigger-applications.md` (#11971)
This commit is contained in:
parent
e1b52cf428
commit
646232121b
|
|
@ -0,0 +1,556 @@
|
||||||
|
# AplicaçÔes Maiores - MĂșltiplos Arquivos
|
||||||
|
|
||||||
|
Se vocĂȘ estĂĄ construindo uma aplicação ou uma API web, Ă© raro que vocĂȘ possa colocar tudo em um Ășnico arquivo.
|
||||||
|
|
||||||
|
**FastAPI** oferece uma ferramenta conveniente para estruturar sua aplicação, mantendo toda a flexibilidade.
|
||||||
|
|
||||||
|
/// info | "Informação"
|
||||||
|
|
||||||
|
Se vocĂȘ vem do Flask, isso seria o equivalente aos Blueprints do Flask.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
## Um exemplo de estrutura de arquivos
|
||||||
|
|
||||||
|
Digamos que vocĂȘ tenha uma estrutura de arquivos como esta:
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
âââ app
|
||||||
|
â  âââ __init__.py
|
||||||
|
â  âââ main.py
|
||||||
|
â  âââ dependencies.py
|
||||||
|
â  âââ routers
|
||||||
|
â  â âââ __init__.py
|
||||||
|
â  â âââ items.py
|
||||||
|
â  â âââ users.py
|
||||||
|
â  âââ internal
|
||||||
|
â  âââ __init__.py
|
||||||
|
â  âââ admin.py
|
||||||
|
```
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Existem vĂĄrios arquivos `__init__.py` presentes em cada diretĂłrio ou subdiretĂłrio.
|
||||||
|
|
||||||
|
Isso permite a importação de código de um arquivo para outro.
|
||||||
|
|
||||||
|
Por exemplo, no arquivo `app/main.py`, vocĂȘ poderia ter uma linha como:
|
||||||
|
|
||||||
|
```
|
||||||
|
from app.routers import items
|
||||||
|
```
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
* O diretório `app` contém todo o código da aplicação. Ele possui um arquivo `app/__init__.py` vazio, o que o torna um "pacote Python" (uma coleção de "módulos Python"): `app`.
|
||||||
|
* Dentro dele, o arquivo `app/main.py` estĂĄ localizado em um pacote Python (diretĂłrio com `__init__.py`). Portanto, ele Ă© um "mĂłdulo" desse pacote: `app.main`.
|
||||||
|
* Existem também um arquivo `app/dependencies.py`, assim como o `app/main.py`, ele é um "módulo": `app.dependencies`.
|
||||||
|
* HĂĄ um subdiretĂłrio `app/routers/` com outro arquivo `__init__.py`, entĂŁo ele Ă© um "subpacote Python": `app.routers`.
|
||||||
|
* O arquivo `app/routers/items.py` estĂĄ dentro de um pacote, `app/routers/`, portanto, Ă© um "submĂłdulo": `app.routers.items`.
|
||||||
|
* O mesmo com `app/routers/users.py`, ele Ă© outro submĂłdulo: `app.routers.users`.
|
||||||
|
* Hå também um subdiretório `app/internal/` com outro arquivo `__init__.py`, então ele é outro "subpacote Python":`app.internal`.
|
||||||
|
* E o arquivo `app/internal/admin.py` Ă© outro submĂłdulo: `app.internal.admin`.
|
||||||
|
|
||||||
|
<img src="/img/tutorial/bigger-applications/package.svg">
|
||||||
|
|
||||||
|
A mesma estrutura de arquivos com comentĂĄrios:
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
âââ app # "app" Ă© um pacote Python
|
||||||
|
â  âââ __init__.py # este arquivo torna "app" um "pacote Python"
|
||||||
|
â  âââ main.py # "main" mĂłdulo, e.g. import app.main
|
||||||
|
â  âââ dependencies.py # "dependencies" mĂłdulo, e.g. import app.dependencies
|
||||||
|
â  âââ routers # "routers" Ă© um "subpacote Python"
|
||||||
|
â  â âââ __init__.py # torna "routers" um "subpacote Python"
|
||||||
|
â  â âââ items.py # "items" submĂłdulo, e.g. import app.routers.items
|
||||||
|
â  â âââ users.py # "users" submĂłdulo, e.g. import app.routers.users
|
||||||
|
â  âââ internal # "internal" Ă© um "subpacote Python"
|
||||||
|
â  âââ __init__.py # torna "internal" um "subpacote Python"
|
||||||
|
â  âââ admin.py # "admin" submĂłdulo, e.g. import app.internal.admin
|
||||||
|
```
|
||||||
|
|
||||||
|
## `APIRouter`
|
||||||
|
|
||||||
|
Vamos supor que o arquivo dedicado a lidar apenas com usuĂĄrios seja o submĂłdulo em `/app/routers/users.py`.
|
||||||
|
|
||||||
|
VocĂȘ quer manter as *operaçÔes de rota* relacionadas aos seus usuĂĄrios separadas do restante do cĂłdigo, para mantĂȘ-lo organizado.
|
||||||
|
|
||||||
|
Mas ele ainda faz parte da mesma aplicação/web API **FastAPI** (faz parte do mesmo "pacote Python").
|
||||||
|
|
||||||
|
VocĂȘ pode criar as *operaçÔes de rotas* para esse mĂłdulo usando o `APIRouter`.
|
||||||
|
|
||||||
|
### Importar `APIRouter`
|
||||||
|
|
||||||
|
vocĂȘ o importa e cria uma "instĂąncia" da mesma maneira que faria com a classe `FastAPI`:
|
||||||
|
|
||||||
|
```Python hl_lines="1 3" title="app/routers/users.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/routers/users.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
### *OperaçÔes de Rota* com `APIRouter`
|
||||||
|
|
||||||
|
E entĂŁo vocĂȘ o utiliza para declarar suas *operaçÔes de rota*.
|
||||||
|
|
||||||
|
Utilize-o da mesma maneira que utilizaria a classe `FastAPI`:
|
||||||
|
|
||||||
|
```Python hl_lines="6 11 16" title="app/routers/users.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/routers/users.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
VocĂȘ pode pensar em `APIRouter` como uma classe "mini `FastAPI`".
|
||||||
|
|
||||||
|
Todas as mesmas opçÔes são suportadas.
|
||||||
|
|
||||||
|
Todos os mesmos `parameters`, `responses`, `dependencies`, `tags`, etc.
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Neste exemplo, a variĂĄvel Ă© chamada de `router`, mas vocĂȘ pode nomeĂĄ-la como quiser.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Vamos incluir este `APIRouter` na aplicação principal `FastAPI`, mas primeiro, vamos verificar as dependĂȘncias e outro `APIRouter`.
|
||||||
|
|
||||||
|
## DependĂȘncias
|
||||||
|
|
||||||
|
Vemos que precisaremos de algumas dependĂȘncias usadas em vĂĄrios lugares da aplicação.
|
||||||
|
|
||||||
|
EntĂŁo, as colocamos em seu prĂłprio mĂłdulo de `dependencies` (`app/dependencies.py`).
|
||||||
|
|
||||||
|
Agora usaremos uma dependĂȘncia simples para ler um cabeçalho `X-Token` personalizado:
|
||||||
|
|
||||||
|
//// 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 | "Dica"
|
||||||
|
|
||||||
|
Prefira usar a versĂŁo `Annotated` se possĂvel.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
```Python hl_lines="1 4-6" title="app/dependencies.py"
|
||||||
|
{!> ../../../docs_src/bigger_applications/app/dependencies.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Estamos usando um cabeçalho inventado para simplificar este exemplo.
|
||||||
|
|
||||||
|
Mas em casos reais, vocĂȘ obterĂĄ melhores resultados usando os [UtilitĂĄrios de Segurança](security/index.md){.internal-link target=_blank} integrados.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
## Outro mĂłdulo com `APIRouter`
|
||||||
|
|
||||||
|
Digamos que vocĂȘ tambĂ©m tenha os endpoints dedicados a manipular "itens" do seu aplicativo no mĂłdulo em `app/routers/items.py`.
|
||||||
|
|
||||||
|
VocĂȘ tem *operaçÔes de rota* para:
|
||||||
|
|
||||||
|
* `/items/`
|
||||||
|
* `/items/{item_id}`
|
||||||
|
|
||||||
|
Ă tudo a mesma estrutura de `app/routers/users.py`.
|
||||||
|
|
||||||
|
Mas queremos ser mais inteligentes e simplificar um pouco o cĂłdigo.
|
||||||
|
|
||||||
|
Sabemos que todas as *operaçÔes de rota* neste mĂłdulo tĂȘm o mesmo:
|
||||||
|
|
||||||
|
* Path `prefix`: `/items`.
|
||||||
|
* `tags`: (apenas uma tag: `items`).
|
||||||
|
* Extra `responses`.
|
||||||
|
* `dependĂȘncias`: todas elas precisam da dependĂȘncia `X-Token` que criamos.
|
||||||
|
|
||||||
|
Então, em vez de adicionar tudo isso a cada *operação de rota*, podemos adicionå-lo ao `APIRouter`.
|
||||||
|
|
||||||
|
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/routers/items.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
Como o caminho de cada *operação de rota* deve começar com `/`, como em:
|
||||||
|
|
||||||
|
```Python hl_lines="1"
|
||||||
|
@router.get("/{item_id}")
|
||||||
|
async def read_item(item_id: str):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
...o prefixo nĂŁo deve incluir um `/` final.
|
||||||
|
|
||||||
|
EntĂŁo, o prefixo neste caso Ă© `/items`.
|
||||||
|
|
||||||
|
TambĂ©m podemos adicionar uma lista de `tags` e `responses` extras que serĂŁo aplicadas a todas as *operaçÔes de rota* incluĂdas neste roteador.
|
||||||
|
|
||||||
|
E podemos adicionar uma lista de `dependencies` que serão adicionadas a todas as *operaçÔes de rota* no roteador e serão executadas/resolvidas para cada solicitação feita a elas.
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Observe que, assim como [dependĂȘncias em *decoradores de operação de rota*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, nenhum valor serĂĄ passado para sua *função de operação de rota*.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
O resultado final Ă© que os caminhos dos itens agora sĂŁo:
|
||||||
|
|
||||||
|
* `/items/`
|
||||||
|
* `/items/{item_id}`
|
||||||
|
|
||||||
|
...como pretendĂamos.
|
||||||
|
|
||||||
|
* Elas serĂŁo marcadas com uma lista de tags que contĂȘm uma Ășnica string `"items"`.
|
||||||
|
* Essas "tags" sĂŁo especialmente Ășteis para os sistemas de documentação interativa automĂĄtica (usando OpenAPI).
|
||||||
|
* Todas elas incluirĂŁo as `responses` predefinidas.
|
||||||
|
* Todas essas *operaçÔes de rota* terão a lista de `dependencies` avaliada/executada antes delas.
|
||||||
|
* Se vocĂȘ tambĂ©m declarar dependĂȘncias em uma *operação de rota* especĂfica, **elas tambĂ©m serĂŁo executadas**.
|
||||||
|
* As dependĂȘncias do roteador sĂŁo executadas primeiro, depois as [`dependencies` no decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank} e, em seguida, as dependĂȘncias de parĂąmetros normais.
|
||||||
|
* VocĂȘ tambĂ©m pode adicionar [dependĂȘncias de `Segurança` com `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Ter `dependĂȘncias` no `APIRouter` pode ser usado, por exemplo, para exigir autenticação para um grupo inteiro de *operaçÔes de rota*. Mesmo que as dependĂȘncias nĂŁo sejam adicionadas individualmente a cada uma delas.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/// check
|
||||||
|
|
||||||
|
Os parùmetros `prefix`, `tags`, `responses` e `dependencies` são (como em muitos outros casos) apenas um recurso do **FastAPI** para ajudar a evitar duplicação de código.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
### Importar as dependĂȘncias
|
||||||
|
|
||||||
|
Este cĂłdigo reside no mĂłdulo `app.routers.items`, o arquivo `app/routers/items.py`.
|
||||||
|
|
||||||
|
E precisamos obter a função de dependĂȘncia do mĂłdulo `app.dependencies`, o arquivo `app/dependencies.py`.
|
||||||
|
|
||||||
|
EntĂŁo usamos uma importação relativa com `..` para as dependĂȘncias:
|
||||||
|
|
||||||
|
```Python hl_lines="3" title="app/routers/items.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/routers/items.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Como funcionam as importaçÔes relativas
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Se vocĂȘ sabe perfeitamente como funcionam as importaçÔes, continue para a prĂłxima seção abaixo.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Um Ășnico ponto `.`, como em:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from .dependencies import get_token_header
|
||||||
|
```
|
||||||
|
|
||||||
|
significaria:
|
||||||
|
|
||||||
|
* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) vive (o diretório `app/routers/`)...
|
||||||
|
* encontre o mĂłdulo `dependencies` (um arquivo imaginĂĄrio em `app/routers/dependencies.py`)...
|
||||||
|
* e dele, importe a função `get_token_header`.
|
||||||
|
|
||||||
|
Mas esse arquivo nĂŁo existe, nossas dependĂȘncias estĂŁo em um arquivo em `app/dependencies.py`.
|
||||||
|
|
||||||
|
Lembre-se de como nossa estrutura app/file se parece:
|
||||||
|
|
||||||
|
<img src="/img/tutorial/bigger-applications/package.svg">
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Os dois pontos `..`, como em:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from ..dependencies import get_token_header
|
||||||
|
```
|
||||||
|
|
||||||
|
significa:
|
||||||
|
|
||||||
|
* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) reside (o diretório `app/routers/`)...
|
||||||
|
* vĂĄ para o pacote pai (o diretĂłrio `app/`)...
|
||||||
|
* e lĂĄ, encontre o mĂłdulo `dependencies` (o arquivo em `app/dependencies.py`)...
|
||||||
|
* e dele, importe a função `get_token_header`.
|
||||||
|
|
||||||
|
Isso funciona corretamente! đ
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Da mesma forma, se tivĂ©ssemos usado trĂȘs pontos `...`, como em:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from ...dependencies import get_token_header
|
||||||
|
```
|
||||||
|
|
||||||
|
isso significaria:
|
||||||
|
|
||||||
|
* Começando no mesmo pacote em que este módulo (o arquivo `app/routers/items.py`) vive (o diretório `app/routers/`)...
|
||||||
|
* vĂĄ para o pacote pai (o diretĂłrio `app/`)...
|
||||||
|
* entĂŁo vĂĄ para o pai daquele pacote (nĂŁo hĂĄ pacote pai, `app` Ă© o nĂvel superior đ±)...
|
||||||
|
* e lĂĄ, encontre o mĂłdulo `dependencies` (o arquivo em `app/dependencies.py`)...
|
||||||
|
* e dele, importe a função `get_token_header`.
|
||||||
|
|
||||||
|
Isso se referiria a algum pacote acima de `app/`, com seu prĂłprio arquivo `__init__.py`, etc. Mas nĂŁo temos isso. EntĂŁo, isso geraria um erro em nosso exemplo. đš
|
||||||
|
|
||||||
|
Mas agora vocĂȘ sabe como funciona, entĂŁo vocĂȘ pode usar importaçÔes relativas em seus prĂłprios aplicativos, nĂŁo importa o quĂŁo complexos eles sejam. đ€
|
||||||
|
|
||||||
|
### Adicione algumas `tags`, `respostas` e `dependĂȘncias` personalizadas
|
||||||
|
|
||||||
|
Não estamos adicionando o prefixo `/items` nem `tags=["items"]` a cada *operação de rota* porque os adicionamos ao `APIRouter`.
|
||||||
|
|
||||||
|
Mas ainda podemos adicionar _mais_ `tags` que serĂŁo aplicadas a uma *operação de rota* especĂfica, e tambĂ©m algumas `respostas` extras especĂficas para essa *operação de rota*:
|
||||||
|
|
||||||
|
```Python hl_lines="30-31" title="app/routers/items.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/routers/items.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
/// tip | "Dica"
|
||||||
|
|
||||||
|
Esta Ășltima operação de caminho terĂĄ a combinação de tags: `["items", "custom"]`.
|
||||||
|
|
||||||
|
E também terå ambas as respostas na documentação, uma para `404` e uma para `403`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
## O principal `FastAPI`
|
||||||
|
|
||||||
|
Agora, vamos ver o mĂłdulo em `app/main.py`.
|
||||||
|
|
||||||
|
Aqui Ă© onde vocĂȘ importa e usa a classe `FastAPI`.
|
||||||
|
|
||||||
|
Este serĂĄ o arquivo principal em seu aplicativo que une tudo.
|
||||||
|
|
||||||
|
E como a maior parte de sua lĂłgica agora viverĂĄ em seu prĂłprio mĂłdulo especĂfico, o arquivo principal serĂĄ bem simples.
|
||||||
|
|
||||||
|
### Importar `FastAPI`
|
||||||
|
|
||||||
|
VocĂȘ importa e cria uma classe `FastAPI` normalmente.
|
||||||
|
|
||||||
|
E podemos atĂ© declarar [dependĂȘncias globais](dependencies/global-dependencies.md){.internal-link target=_blank} que serĂŁo combinadas com as dependĂȘncias para cada `APIRouter`:
|
||||||
|
|
||||||
|
```Python hl_lines="1 3 7" title="app/main.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/main.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Importe o `APIRouter`
|
||||||
|
|
||||||
|
Agora importamos os outros submĂłdulos que possuem `APIRouter`s:
|
||||||
|
|
||||||
|
```Python hl_lines="4-5" title="app/main.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/main.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
Como os arquivos `app/routers/users.py` e `app/routers/items.py` sĂŁo submĂłdulos que fazem parte do mesmo pacote Python `app`, podemos usar um Ășnico ponto `.` para importĂĄ-los usando "importaçÔes relativas".
|
||||||
|
|
||||||
|
### Como funciona a importação
|
||||||
|
|
||||||
|
A seção:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from .routers import items, users
|
||||||
|
```
|
||||||
|
|
||||||
|
significa:
|
||||||
|
|
||||||
|
* Começando no mesmo pacote em que este módulo (o arquivo `app/main.py`) reside (o diretório `app/`)...
|
||||||
|
* procure o subpacote `routers` (o diretĂłrio em `app/routers/`)...
|
||||||
|
* e dele, importe o submĂłdulo `items` (o arquivo em `app/routers/items.py`) e `users` (o arquivo em `app/routers/users.py`)...
|
||||||
|
|
||||||
|
O mĂłdulo `items` terĂĄ uma variĂĄvel `router` (`items.router`). Esta Ă© a mesma que criamos no arquivo `app/routers/items.py`, Ă© um objeto `APIRouter`.
|
||||||
|
|
||||||
|
E entĂŁo fazemos o mesmo para o mĂłdulo `users`.
|
||||||
|
|
||||||
|
TambĂ©m poderĂamos importĂĄ-los como:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from app.routers import items, users
|
||||||
|
```
|
||||||
|
|
||||||
|
/// info | "Informação"
|
||||||
|
|
||||||
|
A primeira versão é uma "importação relativa":
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from .routers import items, users
|
||||||
|
```
|
||||||
|
|
||||||
|
A segunda versão é uma "importação absoluta":
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from app.routers import items, users
|
||||||
|
```
|
||||||
|
|
||||||
|
Para saber mais sobre pacotes e módulos Python, leia <a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">a documentação oficial do Python sobre módulos</a>.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
### Evite colisÔes de nomes
|
||||||
|
|
||||||
|
Estamos importando o submĂłdulo `items` diretamente, em vez de importar apenas sua variĂĄvel `router`.
|
||||||
|
|
||||||
|
Isso ocorre porque também temos outra variåvel chamada `router` no submódulo `users`.
|
||||||
|
|
||||||
|
Se tivéssemos importado um após o outro, como:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from .routers.items import router
|
||||||
|
from .routers.users import router
|
||||||
|
```
|
||||||
|
|
||||||
|
o `router` de `users` sobrescreveria o de `items` e nĂŁo poderĂamos usĂĄ-los ao mesmo tempo.
|
||||||
|
|
||||||
|
EntĂŁo, para poder usar ambos no mesmo arquivo, importamos os submĂłdulos diretamente:
|
||||||
|
|
||||||
|
```Python hl_lines="5" title="app/main.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/main.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Incluir o `APIRouter`s para `usuĂĄrios` e `itens`
|
||||||
|
|
||||||
|
Agora, vamos incluir os `roteadores` dos submĂłdulos `usuĂĄrios` e `itens`:
|
||||||
|
|
||||||
|
```Python hl_lines="10-11" title="app/main.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/main.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
/// info | "Informação"
|
||||||
|
|
||||||
|
`users.router` contém o `APIRouter` dentro do arquivo `app/routers/users.py`.
|
||||||
|
|
||||||
|
E `items.router` contém o `APIRouter` dentro do arquivo `app/routers/items.py`.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo principal `FastAPI`.
|
||||||
|
|
||||||
|
Ele incluirĂĄ todas as rotas daquele roteador como parte dele.
|
||||||
|
|
||||||
|
/// note | "Detalhe Técnico"
|
||||||
|
|
||||||
|
Na verdade, ele criarå internamente uma *operação de rota* para cada *operação de rota* que foi declarada no `APIRouter`.
|
||||||
|
|
||||||
|
EntĂŁo, nos bastidores, ele realmente funcionarĂĄ como se tudo fosse o mesmo aplicativo Ășnico.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/// check
|
||||||
|
|
||||||
|
VocĂȘ nĂŁo precisa se preocupar com desempenho ao incluir roteadores.
|
||||||
|
|
||||||
|
Isso levarå microssegundos e só acontecerå na inicialização.
|
||||||
|
|
||||||
|
EntĂŁo nĂŁo afetarĂĄ o desempenho. âĄ
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
### Incluir um `APIRouter` com um `prefix` personalizado, `tags`, `responses` e `dependencies`
|
||||||
|
|
||||||
|
Agora, vamos imaginar que sua organização lhe deu o arquivo `app/internal/admin.py`.
|
||||||
|
|
||||||
|
Ele contém um `APIRouter` com algumas *operaçÔes de rota* de administração que sua organização compartilha entre vårios projetos.
|
||||||
|
|
||||||
|
Para este exemplo, serå super simples. Mas digamos que, como ele é compartilhado com outros projetos na organização, não podemos modificå-lo e adicionar um `prefix`, `dependencies`, `tags`, etc. diretamente ao `APIRouter`:
|
||||||
|
|
||||||
|
```Python hl_lines="3" title="app/internal/admin.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/internal/admin.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
Mas ainda queremos definir um `prefixo` personalizado ao incluir o `APIRouter` para que todas as suas *operaçÔes de rota* comecem com `/admin`, queremos protegĂȘ-lo com as `dependĂȘncias` que jĂĄ temos para este projeto e queremos incluir `tags` e `responses`.
|
||||||
|
|
||||||
|
Podemos declarar tudo isso sem precisar modificar o `APIRouter` original passando esses parĂąmetros para `app.include_router()`:
|
||||||
|
|
||||||
|
```Python hl_lines="14-17" title="app/main.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/main.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
Dessa forma, o `APIRouter` original permanecerå inalterado, para que possamos compartilhar o mesmo arquivo `app/internal/admin.py` com outros projetos na organização.
|
||||||
|
|
||||||
|
O resultado é que em nosso aplicativo, cada uma das *operaçÔes de rota* do módulo `admin` terå:
|
||||||
|
|
||||||
|
* O prefixo `/admin`.
|
||||||
|
* A tag `admin`.
|
||||||
|
* A dependĂȘncia `get_token_header`.
|
||||||
|
* A resposta `418`. đ”
|
||||||
|
|
||||||
|
Mas isso afetarĂĄ apenas o `APIRouter` em nosso aplicativo, e nĂŁo em nenhum outro cĂłdigo que o utilize.
|
||||||
|
|
||||||
|
Assim, por exemplo, outros projetos poderiam usar o mesmo `APIRouter` com um método de autenticação diferente.
|
||||||
|
|
||||||
|
### Incluir uma *operação de rota*
|
||||||
|
|
||||||
|
Também podemos adicionar *operaçÔes de rota* diretamente ao aplicativo `FastAPI`.
|
||||||
|
|
||||||
|
Aqui fazemos isso... sĂł para mostrar que podemos đ€·:
|
||||||
|
|
||||||
|
```Python hl_lines="21-23" title="app/main.py"
|
||||||
|
{!../../../docs_src/bigger_applications/app/main.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
e funcionarå corretamente, junto com todas as outras *operaçÔes de rota* adicionadas com `app.include_router()`.
|
||||||
|
|
||||||
|
/// info | "Detalhes Técnicos"
|
||||||
|
|
||||||
|
**Observação**: este Ă© um detalhe muito tĂ©cnico que vocĂȘ provavelmente pode **simplesmente pular**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Os `APIRouter`s nĂŁo sĂŁo "montados", eles nĂŁo sĂŁo isolados do resto do aplicativo.
|
||||||
|
|
||||||
|
Isso ocorre porque queremos incluir suas *operaçÔes de rota* no esquema OpenAPI e nas interfaces de usuårio.
|
||||||
|
|
||||||
|
Como nĂŁo podemos simplesmente isolĂĄ-los e "montĂĄ-los" independentemente do resto, as *operaçÔes de rota* sĂŁo "clonadas" (recriadas), nĂŁo incluĂdas diretamente.
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
## Verifique a documentação automåtica da API
|
||||||
|
|
||||||
|
Agora, execute `uvicorn`, usando o mĂłdulo `app.main` e a variĂĄvel `app`:
|
||||||
|
|
||||||
|
<div class="termy">
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ uvicorn app.main:app --reload
|
||||||
|
|
||||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
E abra os documentos em <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||||
|
|
||||||
|
VocĂȘ verĂĄ a documentação automĂĄtica da API, incluindo os caminhos de todos os submĂłdulos, usando os caminhos (e prefixos) corretos e as tags corretas:
|
||||||
|
|
||||||
|
<img src="/img/tutorial/bigger-applications/image01.png">
|
||||||
|
|
||||||
|
## Incluir o mesmo roteador vĂĄrias vezes com `prefixos` diferentes
|
||||||
|
|
||||||
|
VocĂȘ tambĂ©m pode usar `.include_router()` vĂĄrias vezes com o *mesmo* roteador usando prefixos diferentes.
|
||||||
|
|
||||||
|
Isso pode ser Ăștil, por exemplo, para expor a mesma API sob prefixos diferentes, por exemplo, `/api/v1` e `/api/latest`.
|
||||||
|
|
||||||
|
Esse Ă© um uso avançado que vocĂȘ pode nĂŁo precisar, mas estĂĄ lĂĄ caso precise.
|
||||||
|
|
||||||
|
## Incluir um `APIRouter` em outro
|
||||||
|
|
||||||
|
Da mesma forma que vocĂȘ pode incluir um `APIRouter` em um aplicativo `FastAPI`, vocĂȘ pode incluir um `APIRouter` em outro `APIRouter` usando:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
router.include_router(other_router)
|
||||||
|
```
|
||||||
|
|
||||||
|
Certifique-se de fazer isso antes de incluir `router` no aplicativo `FastAPI`, para que as *operaçÔes de rota* de `other_router` tambĂ©m sejam incluĂdas.
|
||||||
LoadingâŠ
Reference in New Issue