@ -132,7 +132,7 @@ Se você tiver esse caso específico usando SQLModel (ou SQLAlchemy), você pode
Dessa forma a sessão liberaria a conexão com o banco de dados, para que outras requisições pudessem usá-la.
Dessa forma a sessão liberaria a conexão com o banco de dados, para que outras requisições pudessem usá-la.
Se você tiver um caso diferente que precise sair antecipadamente de uma dependência com `yield`, por favor crie uma <ahref="https://github.com/fastapi/fastapi/discussions/new?category=questions"class="external-link"target="_blank">Pergunta no GitHub Discussions</a> com o seu caso específico e por que você se beneficiaria de ter o fechamento antecipado para dependências com `yield`.
Se você tiver um caso diferente que precise sair antecipadamente de uma dependência com `yield`, por favor crie uma [Pergunta no GitHub Discussions](https://github.com/fastapi/fastapi/discussions/new?category=questions) com o seu caso específico e por que você se beneficiaria de ter o fechamento antecipado para dependências com `yield`.
Se houver casos de uso convincentes para fechamento antecipado em dependências com `yield`, considerarei adicionar uma nova forma de optar por esse fechamento antecipado.
Se houver casos de uso convincentes para fechamento antecipado em dependências com `yield`, considerarei adicionar uma nova forma de optar por esse fechamento antecipado.
@ -144,7 +144,7 @@ Isso foi alterado na versão 0.110.0 para corrigir consumo de memória não trat
### Tarefas em Segundo Plano e Dependências com `yield`, Detalhes Técnicos { #background-tasks-and-dependencies-with-yield-technical-details }
### Tarefas em Segundo Plano e Dependências com `yield`, Detalhes Técnicos { #background-tasks-and-dependencies-with-yield-technical-details }
Antes do FastAPI 0.106.0, lançar exceções após o `yield` não era possível, o código de saída em dependências com `yield` era executado depois que a resposta era enviada, então [Tratadores de Exceções](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} já teriam sido executados.
Antes do FastAPI 0.106.0, lançar exceções após o `yield` não era possível, o código de saída em dependências com `yield` era executado depois que a resposta era enviada, então [Tratadores de Exceções](../tutorial/handling-errors.md#install-custom-exception-handlers) já teriam sido executados.
Isso foi projetado assim principalmente para permitir o uso dos mesmos objetos "yielded" por dependências dentro de tarefas em segundo plano, porque o código de saída seria executado depois que as tarefas em segundo plano fossem concluídas.
Isso foi projetado assim principalmente para permitir o uso dos mesmos objetos "yielded" por dependências dentro de tarefas em segundo plano, porque o código de saída seria executado depois que as tarefas em segundo plano fossem concluídas.
@ -16,11 +16,11 @@ Mesmo que a sua aplicação **FastAPI** utilize funções normais com `def` no l
O `TestClient` faz algumas mágicas para invocar a aplicação FastAPI assíncrona em suas funções `def` normais, utilizando o pytest padrão. Porém a mágica não acontece mais quando nós estamos utilizando dentro de funções assíncronas. Ao executar os nossos testes de forma assíncrona, nós não podemos mais utilizar o `TestClient` dentro das nossas funções de teste.
O `TestClient` faz algumas mágicas para invocar a aplicação FastAPI assíncrona em suas funções `def` normais, utilizando o pytest padrão. Porém a mágica não acontece mais quando nós estamos utilizando dentro de funções assíncronas. Ao executar os nossos testes de forma assíncrona, nós não podemos mais utilizar o `TestClient` dentro das nossas funções de teste.
O `TestClient` é baseado no <ahref="https://www.python-httpx.org"class="external-link"target="_blank">HTTPX</a>, e felizmente nós podemos utilizá-lo diretamente para testar a API.
O `TestClient` é baseado no [HTTPX](https://www.python-httpx.org), e felizmente nós podemos utilizá-lo diretamente para testar a API.
## Exemplo { #example }
## Exemplo { #example }
Para um exemplos simples, vamos considerar uma estrutura de arquivos semelhante ao descrito em [Bigger Applications](../tutorial/bigger-applications.md){.internal-link target=_blank} e [Testing](../tutorial/testing.md){.internal-link target=_blank}:
Para um exemplos simples, vamos considerar uma estrutura de arquivos semelhante ao descrito em [Aplicações Maiores](../tutorial/bigger-applications.md) e [Testes](../tutorial/testing.md):
```
```
.
.
@ -84,7 +84,7 @@ Note que nós estamos utilizando async/await com o novo `AsyncClient` - a requis
/// warning | Atenção
/// warning | Atenção
Se a sua aplicação depende de eventos de lifespan, o `AsyncClient` não acionará estes eventos. Para garantir que eles são acionados, utilize o `LifespanManager` do <ahref="https://github.com/florimondmanca/asgi-lifespan#usage"class="external-link"target="_blank">florimondmanca/asgi-lifespan</a>.
Se a sua aplicação depende de eventos de lifespan, o `AsyncClient` não acionará estes eventos. Para garantir que eles são acionados, utilize o `LifespanManager` do [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage).
///
///
@ -94,6 +94,6 @@ Como a função de teste agora é assíncrona, você pode chamar (e `await`) out
/// tip | Dica
/// tip | Dica
Se você se deparar com um `RuntimeError: Task attached to a different loop` ao integrar funções assíncronas em seus testes (e.g. ao utilizar o <ahref="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop"class="external-link"target="_blank">MotorClient do MongoDB</a>) Lembre-se de instanciar objetos que precisam de um loop de eventos (*event loop*) apenas em funções assíncronas, e.g. um callback `@app.on_event("startup")`.
Se você se deparar com um `RuntimeError: Task attached to a different loop` ao integrar funções assíncronas em seus testes (e.g. ao utilizar o [MotorClient do MongoDB](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)) Lembre-se de instanciar objetos que precisam de um loop de eventos (*event loop*) apenas em funções assíncronas, e.g. um callback `@app.on_event("startup")`.
@ -150,11 +150,11 @@ Por causa disso, agora é recomendado usar o `lifespan`, como explicado acima.
Apenas um detalhe técnico para nerds curiosos. 🤓
Apenas um detalhe técnico para nerds curiosos. 🤓
Por baixo, na especificação técnica do ASGI, isso é parte do <ahref="https://asgi.readthedocs.io/en/latest/specs/lifespan.html"class="external-link"target="_blank">Protocolo Lifespan</a>, e define eventos chamados `startup` e `shutdown`.
Por baixo, na especificação técnica do ASGI, isso é parte do [Protocolo Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), e define eventos chamados `startup` e `shutdown`.
/// info | Informação
/// info | Informação
Você pode ler mais sobre os manipuladores de `lifespan` do Starlette na <ahref="https://www.starlette.dev/lifespan/"class="external-link"target="_blank">Documentação do Lifespan do Starlette</a>.
Você pode ler mais sobre os manipuladores de `lifespan` do Starlette na [Documentação do Lifespan do Starlette](https://www.starlette.dev/lifespan/).
Incluindo como lidar com estado do lifespan que pode ser usado em outras áreas do seu código.
Incluindo como lidar com estado do lifespan que pode ser usado em outras áreas do seu código.
@ -162,4 +162,4 @@ Incluindo como lidar com estado do lifespan que pode ser usado em outras áreas
## Sub Aplicações { #sub-applications }
## Sub Aplicações { #sub-applications }
🚨 Tenha em mente que esses eventos de lifespan (inicialização e encerramento) serão executados apenas para a aplicação principal, não para [Sub Aplicações - Montagem](sub-applications.md){.internal-link target=_blank}.
🚨 Tenha em mente que esses eventos de lifespan (inicialização e encerramento) serão executados apenas para a aplicação principal, não para [Sub Aplicações - Montagem](sub-applications.md).
No tutorial principal você leu como adicionar [Middleware Personalizado](../tutorial/middleware.md){.internal-link target=_blank} à sua aplicação.
No tutorial principal você leu como adicionar [Middleware Personalizado](../tutorial/middleware.md) à sua aplicação.
E então você também leu como lidar com [CORS com o `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
E então você também leu como lidar com [CORS com o `CORSMiddleware`](../tutorial/cors.md).
Nesta seção, veremos como usar outros middlewares.
Nesta seção, veremos como usar outros middlewares.
@ -67,7 +67,7 @@ Garante que todas as requisições recebidas tenham um cabeçalho `Host` correta
Os seguintes argumentos são suportados:
Os seguintes argumentos são suportados:
* `allowed_hosts` - Uma lista de nomes de domínio que são permitidos como nomes de host. Domínios com coringa, como `*.example.com`, são suportados para corresponder a subdomínios. Para permitir qualquer nome de host, use `allowed_hosts=["*"]` ou omita o middleware.
* `allowed_hosts` - Uma lista de nomes de domínio que são permitidos como nomes de host. Domínios com curingas, como `*.example.com`, são suportados para corresponder a subdomínios. Para permitir qualquer nome de host, use `allowed_hosts=["*"]` ou omita o middleware.
* `www_redirect` - Se definido como True, as requisições para versões sem www dos hosts permitidos serão redirecionadas para suas versões com www. O padrão é `True`.
* `www_redirect` - Se definido como True, as requisições para versões sem www dos hosts permitidos serão redirecionadas para suas versões com www. O padrão é `True`.
Se uma requisição recebida não for validada corretamente, uma resposta `400` será enviada.
Se uma requisição recebida não for validada corretamente, uma resposta `400` será enviada.
@ -91,7 +91,7 @@ Há muitos outros middlewares ASGI.
Por exemplo:
Por exemplo:
* <ahref="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py"class="external-link"target="_blank">`ProxyHeadersMiddleware` do Uvicorn</a>
* [`ProxyHeadersMiddleware` do Uvicorn](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
Para checar outros middlewares disponíveis, confira <ahref="https://www.starlette.dev/middleware/"class="external-link"target="_blank">Documentação de Middlewares do Starlette</a> e a <ahref="https://github.com/florimondmanca/awesome-asgi"class="external-link"target="_blank">Lista Incrível do ASGI</a>.
Para checar outros middlewares disponíveis, confira [Documentação de Middlewares do Starlette](https://www.starlette.dev/middleware/) e a [Lista Incrível do ASGI](https://github.com/florimondmanca/awesome-asgi).
@ -16,7 +16,7 @@ E os **seus usuários** definem de alguma forma (em algum painel por exemplo) a
Toda a **lógica** sobre como cadastrar as URLs para os webhooks e o código para enviar de fato as requisições cabe a você definir. Você escreve da maneira que você desejar no **seu próprio código**.
Toda a **lógica** sobre como cadastrar as URLs para os webhooks e o código para enviar de fato as requisições cabe a você definir. Você escreve da maneira que você desejar no **seu próprio código**.
## Documentando webhooks com o FastAPI e OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
## Documentando webhooks com o **FastAPI** e OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
Com o **FastAPI**, utilizando o OpenAPI, você pode definir os nomes destes webhooks, os tipos das operações HTTP que a sua aplicação pode enviar (e.g. `POST`, `PUT`, etc.) e os **corpos** da requisição que a sua aplicação enviaria.
Com o **FastAPI**, utilizando o OpenAPI, você pode definir os nomes destes webhooks, os tipos das operações HTTP que a sua aplicação pode enviar (e.g. `POST`, `PUT`, etc.) e os **corpos** da requisição que a sua aplicação enviaria.
@ -48,7 +48,7 @@ Isto porque espera-se que os **seus usuários** definam o verdadeiro **URL path*
### Confira a documentação { #check-the-docs }
### Confira a documentação { #check-the-docs }
Agora você pode iniciar a sua aplicação e ir até <ahref="http://127.0.0.1:8000/docs"class="external-link"target="_blank">http://127.0.0.1:8000/docs</a>.
Agora você pode iniciar a sua aplicação e ir até [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Você verá que a sua documentação possui as *operações de rota* normais e agora também possui alguns **webhooks**:
Você verá que a sua documentação possui as *operações de rota* normais e agora também possui alguns **webhooks**:
@ -60,7 +60,7 @@ Isso define os metadados sobre a resposta principal da *operação de rota*.
Você também pode declarar respostas adicionais, com seus modelos, códigos de status, etc.
Você também pode declarar respostas adicionais, com seus modelos, códigos de status, etc.
Existe um capítulo inteiro da nossa documentação sobre isso, você pode ler em [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
Existe um capítulo inteiro da nossa documentação sobre isso, você pode ler em [Respostas Adicionais no OpenAPI](additional-responses.md).
## Extras do OpenAPI { #openapi-extra }
## Extras do OpenAPI { #openapi-extra }
@ -68,7 +68,7 @@ Quando você declara uma *operação de rota* na sua aplicação, o **FastAPI**
/// note | Detalhes Técnicos
/// note | Detalhes Técnicos
Na especificação do OpenAPI, isso é chamado de um <ahref="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object"class="external-link"target="_blank">Objeto de Operação</a>.
Na especificação do OpenAPI, isso é chamado de um [Objeto de Operação](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object).
///
///
@ -82,7 +82,7 @@ Esse esquema específico para uma *operação de rota* normalmente é gerado aut
Esse é um ponto de extensão de baixo nível.
Esse é um ponto de extensão de baixo nível.
Caso você só precise declarar respostas adicionais, uma forma conveniente de fazer isso é com [Retornos Adicionais no OpenAPI](additional-responses.md){.internal-link target=_blank}.
Caso você só precise declarar respostas adicionais, uma forma conveniente de fazer isso é com [Respostas Adicionais no OpenAPI](additional-responses.md).
@ -8,7 +8,7 @@ Por esse motivo, é comum fornecê-las em variáveis de ambiente lidas pela apli
/// tip | Dica
/// tip | Dica
Para entender variáveis de ambiente, você pode ler [Variáveis de Ambiente](../environment-variables.md){.internal-link target=_blank}.
Para entender variáveis de ambiente, você pode ler [Variáveis de Ambiente](../environment-variables.md).
///
///
@ -20,11 +20,11 @@ Isso significa que qualquer valor lido em Python a partir de uma variável de am
## Pydantic `Settings` { #pydantic-settings }
## Pydantic `Settings` { #pydantic-settings }
Felizmente, o Pydantic fornece uma ótima utilidade para lidar com essas configurações vindas de variáveis de ambiente com <ahref="https://docs.pydantic.dev/latest/concepts/pydantic_settings/"class="external-link"target="_blank">Pydantic: Settings management</a>.
Felizmente, o Pydantic fornece uma ótima utilidade para lidar com essas configurações vindas de variáveis de ambiente com [Pydantic: Settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
Primeiro, certifique-se de criar seu [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e então instalar o pacote `pydantic-settings`:
Primeiro, certifique-se de criar seu [ambiente virtual](../virtual-environments.md), ativá-lo e então instalar o pacote `pydantic-settings`:
<divclass="termy">
<divclass="termy">
@ -100,7 +100,7 @@ E `items_per_user` manteria seu valor padrão de `50`.
## Configurações em outro módulo { #settings-in-another-module }
## Configurações em outro módulo { #settings-in-another-module }
Você pode colocar essas configurações em outro arquivo de módulo como visto em [Aplicações Maiores - Múltiplos Arquivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
Você pode colocar essas configurações em outro arquivo de módulo como visto em [Aplicações Maiores - Múltiplos Arquivos](../tutorial/bigger-applications.md).
Por exemplo, você poderia ter um arquivo `config.py` com:
Por exemplo, você poderia ter um arquivo `config.py` com:
@ -112,7 +112,7 @@ E então usá-lo em um arquivo `main.py`:
/// tip | Dica
/// tip | Dica
Você também precisaria de um arquivo `__init__.py` como visto em [Aplicações Maiores - Múltiplos Arquivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
Você também precisaria de um arquivo `__init__.py` como visto em [Aplicações Maiores - Múltiplos Arquivos](../tutorial/bigger-applications.md).
///
///
@ -172,7 +172,7 @@ Mas um arquivo dotenv não precisa ter exatamente esse nome de arquivo.
///
///
O Pydantic tem suporte para leitura desses tipos de arquivos usando uma biblioteca externa. Você pode ler mais em <ahref="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support"class="external-link"target="_blank">Pydantic Settings: Dotenv (.env) support</a>.
O Pydantic tem suporte para leitura desses tipos de arquivos usando uma biblioteca externa. Você pode ler mais em [Pydantic Settings: Dotenv (.env) support](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
/// tip | Dica
/// tip | Dica
@ -197,7 +197,7 @@ E então atualizar seu `config.py` com:
/// tip | Dica
/// tip | Dica
O atributo `model_config` é usado apenas para configuração do Pydantic. Você pode ler mais em <ahref="https://docs.pydantic.dev/latest/concepts/config/"class="external-link"target="_blank">Pydantic: Concepts: Configuration</a>.
O atributo `model_config` é usado apenas para configuração do Pydantic. Você pode ler mais em [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/).
///
///
@ -291,7 +291,7 @@ No caso da nossa dependência `get_settings()`, a função nem recebe argumentos
Dessa forma, ela se comporta quase como se fosse apenas uma variável global. Mas como usa uma função de dependência, podemos sobrescrevê-la facilmente para testes.
Dessa forma, ela se comporta quase como se fosse apenas uma variável global. Mas como usa uma função de dependência, podemos sobrescrevê-la facilmente para testes.
`@lru_cache` faz parte de `functools`, que faz parte da biblioteca padrão do Python; você pode ler mais sobre isso na <ahref="https://docs.python.org/3/library/functools.html#functools.lru_cache"class="external-link"target="_blank">documentação do Python para `@lru_cache`</a>.
`@lru_cache` faz parte de `functools`, que faz parte da biblioteca padrão do Python; você pode ler mais sobre isso na [documentação do Python para `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e instalar `jinja2`:
Certifique-se de criar um [ambiente virtual](../virtual-environments.md), ativá-lo e instalar `jinja2`:
<divclass="termy">
<divclass="termy">
@ -123,4 +123,4 @@ E como você está usando `StaticFiles`, este arquivo CSS será automaticamente
## Mais detalhes { #more-details }
## Mais detalhes { #more-details }
Para obter mais detalhes, incluindo como testar templates, consulte a <ahref="https://www.starlette.dev/templates/"class="external-link"target="_blank">documentação da Starlette sobre templates</a>.
Para obter mais detalhes, incluindo como testar templates, consulte a [documentação da Starlette sobre templates](https://www.starlette.dev/templates/).
@ -8,6 +8,6 @@ Para isso, você utiliza o `TestClient` dentro de uma instrução `with`, conect
/// note | Nota
/// note | Nota
Para mais detalhes, confira a documentação do Starlette para <ahref="https://www.starlette.dev/testclient/#testing-websocket-sessions"class="external-link"target="_blank">testar WebSockets</a>.
Para mais detalhes, confira a documentação do Starlette para [testar WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions).
Você pode usar <ahref="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API"class="external-link"target="_blank">WebSockets</a> com **FastAPI**.
Você pode usar [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) com **FastAPI**.
## Instale `websockets` { #install-websockets }
## Instale `websockets` { #install-websockets }
Garanta que você criou um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, o ativou e instalou o `websockets` (uma biblioteca Python que facilita o uso do protocolo "WebSocket"):
Garanta que você criou um [ambiente virtual](../virtual-environments.md), o ativou e instalou o `websockets` (uma biblioteca Python que facilita o uso do protocolo "WebSocket"):
<divclass="termy">
<divclass="termy">
@ -64,19 +64,19 @@ Você pode receber e enviar dados binários, de texto e JSON.
## Tente { #try-it }
## Tente { #try-it }
Se seu arquivo for nomeado `main.py`, execute sua aplicação com:
Coloque seu código em um arquivo `main.py` e então execute sua aplicação:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi dev main.py
$ fastapi dev
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
</div>
</div>
Abra seu navegador em: <ahref="http://127.0.0.1:8000"class="external-link"target="_blank">http://127.0.0.1:8000</a>.
Abra seu navegador em: [http://127.0.0.1:8000](http://127.0.0.1:8000).
Você verá uma página simples como:
Você verá uma página simples como:
@ -115,25 +115,25 @@ Eles funcionam da mesma forma que para outros endpoints FastAPI/*operações de
Como isso é um WebSocket, não faz muito sentido levantar uma `HTTPException`, em vez disso levantamos uma `WebSocketException`.
Como isso é um WebSocket, não faz muito sentido levantar uma `HTTPException`, em vez disso levantamos uma `WebSocketException`.
Você pode usar um código de fechamento dos <ahref="https://tools.ietf.org/html/rfc6455#section-7.4.1"class="external-link"target="_blank">códigos válidos definidos na especificação</a>.
Você pode usar um código de fechamento dos [códigos válidos definidos na especificação](https://tools.ietf.org/html/rfc6455#section-7.4.1).
///
///
### Tente os WebSockets com dependências { #try-the-websockets-with-dependencies }
### Tente os WebSockets com dependências { #try-the-websockets-with-dependencies }
Se seu arquivo for nomeado `main.py`, execute sua aplicação com:
Execute sua aplicação:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi dev main.py
$ fastapi dev
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
</div>
</div>
Abra seu navegador em: <ahref="http://127.0.0.1:8000"class="external-link"target="_blank">http://127.0.0.1:8000</a>.
Abra seu navegador em: [http://127.0.0.1:8000](http://127.0.0.1:8000).
Lá você pode definir:
Lá você pode definir:
@ -174,7 +174,7 @@ O app acima é um exemplo mínimo e simples para demonstrar como lidar e transmi
Mas tenha em mente que, como tudo é manipulado na memória, em uma única list, ele só funcionará enquanto o processo estiver em execução e só funcionará com um único processo.
Mas tenha em mente que, como tudo é manipulado na memória, em uma única list, ele só funcionará enquanto o processo estiver em execução e só funcionará com um único processo.
Se você precisa de algo fácil de integrar com o FastAPI, mas que seja mais robusto, suportado por Redis, PostgreSQL ou outros, verifique o <ahref="https://github.com/encode/broadcaster"class="external-link"target="_blank">encode/broadcaster</a>.
Se você precisa de algo fácil de integrar com o FastAPI, mas que seja mais robusto, suportado por Redis, PostgreSQL ou outros, verifique [encode/broadcaster](https://github.com/encode/broadcaster).
///
///
@ -182,5 +182,5 @@ Se você precisa de algo fácil de integrar com o FastAPI, mas que seja mais rob
Para aprender mais sobre as opções, verifique a documentação do Starlette para:
Para aprender mais sobre as opções, verifique a documentação do Starlette para:
* <ahref="https://www.starlette.dev/websockets/"class="external-link"target="_blank">A classe `WebSocket`</a>.
* [A classe `WebSocket`](https://www.starlette.dev/websockets/).
* <ahref="https://www.starlette.dev/endpoints/#websocketendpoint"class="external-link"target="_blank">Manipulação de WebSockets baseada em classes</a>.
* [Manipulação de WebSockets baseada em classes](https://www.starlette.dev/endpoints/#websocketendpoint).
# Adicionando WSGI - Flask, Django, entre outros { #including-wsgi-flask-django-others }
# Adicionando WSGI - Flask, Django, entre outros { #including-wsgi-flask-django-others }
Como você viu em [Subaplicações - Montagens](sub-applications.md){.internal-link target=_blank} e [Atrás de um Proxy](behind-a-proxy.md){.internal-link target=_blank}, você pode montar aplicações WSGI.
Como você viu em [Subaplicações - Montagens](sub-applications.md) e [Atrás de um Proxy](behind-a-proxy.md), você pode montar aplicações WSGI.
Para isso, você pode utilizar o `WSGIMiddleware` para encapsular a sua aplicação WSGI, como por exemplo Flask, Django, etc.
Para isso, você pode utilizar o `WSGIMiddleware` para encapsular a sua aplicação WSGI, como por exemplo Flask, Django, etc.
@ -36,13 +36,13 @@ Agora, todas as requisições sob o path `/v1/` serão manipuladas pela aplicaç
E o resto será manipulado pelo **FastAPI**.
E o resto será manipulado pelo **FastAPI**.
Se você rodar a aplicação e ir até <ahref="http://localhost:8000/v1/"class="external-link"target="_blank">http://localhost:8000/v1/</a>, você verá o retorno do Flask:
Se você rodar a aplicação e ir até [http://localhost:8000/v1/](http://localhost:8000/v1/), você verá o retorno do Flask:
```txt
```txt
Hello, World from Flask!
Hello, World from Flask!
```
```
E se você for até <ahref="http://localhost:8000/v2"class="external-link"target="_blank">http://localhost:8000/v2</a>, você verá o retorno do FastAPI:
E se você for até [http://localhost:8000/v2](http://localhost:8000/v2), você verá o retorno do FastAPI:
@ -62,7 +62,7 @@ E então outra tarefa em segundo plano gerada na *função de operação de rota
## Detalhes técnicos { #technical-details }
## Detalhes técnicos { #technical-details }
A classe `BackgroundTasks` vem diretamente de <ahref="https://www.starlette.dev/background/"class="external-link"target="_blank">`starlette.background`</a>.
A classe `BackgroundTasks` vem diretamente de [`starlette.background`](https://www.starlette.dev/background/).
Ela é importada/incluída diretamente no FastAPI para que você possa importá-la de `fastapi` e evitar importar acidentalmente a alternativa `BackgroundTask` (sem o `s` no final) de `starlette.background`.
Ela é importada/incluída diretamente no FastAPI para que você possa importá-la de `fastapi` e evitar importar acidentalmente a alternativa `BackgroundTask` (sem o `s` no final) de `starlette.background`.
@ -70,11 +70,11 @@ Usando apenas `BackgroundTasks` (e não `BackgroundTask`), é possível usá-la
Ainda é possível usar `BackgroundTask` sozinho no FastAPI, mas você precisa criar o objeto no seu código e retornar uma `Response` da Starlette incluindo-o.
Ainda é possível usar `BackgroundTask` sozinho no FastAPI, mas você precisa criar o objeto no seu código e retornar uma `Response` da Starlette incluindo-o.
Você pode ver mais detalhes na <ahref="https://www.starlette.dev/background/"class="external-link"target="_blank">documentação oficial da Starlette para tarefas em segundo plano</a>.
Você pode ver mais detalhes na [documentação oficial da Starlette para tarefas em segundo plano](https://www.starlette.dev/background/).
## Ressalva { #caveat }
## Ressalva { #caveat }
Se você precisar realizar computação pesada em segundo plano e não necessariamente precisar que seja executada pelo mesmo processo (por exemplo, você não precisa compartilhar memória, variáveis, etc.), pode se beneficiar do uso de outras ferramentas maiores, como o <ahref="https://docs.celeryq.dev"class="external-link"target="_blank">Celery</a>.
Se você precisar realizar computação pesada em segundo plano e não necessariamente precisar que seja executada pelo mesmo processo (por exemplo, você não precisa compartilhar memória, variáveis, etc.), pode se beneficiar do uso de outras ferramentas maiores, como o [Celery](https://docs.celeryq.dev).
Elas tendem a exigir configurações mais complexas, um gerenciador de fila de mensagens/tarefas, como RabbitMQ ou Redis, mas permitem executar tarefas em segundo plano em vários processos e, especialmente, em vários servidores.
Elas tendem a exigir configurações mais complexas, um gerenciador de fila de mensagens/tarefas, como RabbitMQ ou Redis, mas permitem executar tarefas em segundo plano em vários processos e, especialmente, em vários servidores.
@ -90,15 +90,15 @@ Novamente, apenas fazendo essa declaração, com o **FastAPI**, você ganha:
* Suporte do editor (preenchimento automático, etc.), inclusive para modelos aninhados
* Suporte do editor (preenchimento automático, etc.), inclusive para modelos aninhados
* Conversão de dados
* Conversão de dados
* Validação de dados
* Validação de dados
* Documentação automatica
* Documentação automática
## Tipos especiais e validação { #special-types-and-validation }
## Tipos especiais e validação { #special-types-and-validation }
Além dos tipos singulares normais como `str`, `int`, `float`, etc. Você também pode usar tipos singulares mais complexos que herdam de `str`.
Além dos tipos singulares normais como `str`, `int`, `float`, etc. Você também pode usar tipos singulares mais complexos que herdam de `str`.
Para ver todas as opções possíveis, consulte a <ahref="https://docs.pydantic.dev/latest/concepts/types/"class="external-link"target="_blank">Visão geral dos tipos do Pydantic</a>. Você verá alguns exemplos no próximo capítulo.
Para ver todas as opções possíveis, consulte a [Visão geral dos tipos do Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Você verá alguns exemplos no próximo capítulo.
Por exemplo, no modelo `Image` nós temos um campo `url`, nós podemos declara-lo como um `HttpUrl` do Pydantic invés de como uma `str`:
Por exemplo, no modelo `Image` nós temos um campo `url`, nós podemos declará-lo como um `HttpUrl` do Pydantic invés de como uma `str`:
@ -8,7 +8,7 @@ Mas você ainda precisa que ela seja executada/resolvida.
Para esses casos, em vez de declarar um parâmetro em uma *função de operação de rota* com `Depends`, você pode adicionar um argumento `dependencies` do tipo `list` ao decorador da operação de rota.
Para esses casos, em vez de declarar um parâmetro em uma *função de operação de rota* com `Depends`, você pode adicionar um argumento `dependencies` do tipo `list` ao decorador da operação de rota.
## Adicione `dependencies` ao decorador da operação de rota { #add-dependencies-to-the-path-operation-decorator }
## Adicione `dependencies` ao *decorador da operação de rota* { #add-dependencies-to-the-path-operation-decorator }
O *decorador da operação de rota* recebe um argumento opcional `dependencies`.
O *decorador da operação de rota* recebe um argumento opcional `dependencies`.
@ -32,7 +32,7 @@ Isso também pode ser útil para evitar confundir novos desenvolvedores que ao v
Neste exemplo utilizamos cabeçalhos personalizados inventados `X-Key` e `X-Token`.
Neste exemplo utilizamos cabeçalhos personalizados inventados `X-Key` e `X-Token`.
Mas em situações reais, como implementações de segurança, você pode obter mais vantagens em usar as [Ferramentas de segurança integradas (o próximo capítulo)](../security/index.md){.internal-link target=_blank}.
Mas em situações reais, como implementações de segurança, você pode obter mais vantagens em usar as [Ferramentas de segurança integradas (o próximo capítulo)](../security/index.md).
///
///
@ -62,7 +62,7 @@ Então, você pode reutilizar uma dependência comum (que retorna um valor) que
## Dependências para um grupo de *operações de rota* { #dependencies-for-a-group-of-path-operations }
## Dependências para um grupo de *operações de rota* { #dependencies-for-a-group-of-path-operations }
Mais a frente, quando você ler sobre como estruturar aplicações maiores ([Aplicações maiores - Múltiplos arquivos](../../tutorial/bigger-applications.md){.internal-link target=_blank}), possivelmente com múltiplos arquivos, você aprenderá a declarar um único parâmetro `dependencies` para um grupo de *operações de rota*.
Mais a frente, quando você ler sobre como estruturar aplicações maiores ([Aplicações maiores - Múltiplos arquivos](../../tutorial/bigger-applications.md)), possivelmente com múltiplos arquivos, você aprenderá a declarar um único parâmetro `dependencies` para um grupo de *operações de rota*.
@ -14,8 +14,8 @@ Garanta utilizar `yield` apenas uma vez por dependência.
Qualquer função que possa ser utilizada com:
Qualquer função que possa ser utilizada com:
* <ahref="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager"class="external-link"target="_blank">`@contextlib.contextmanager`</a> ou
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) ou
pode ser utilizada como uma dependência do **FastAPI**.
pode ser utilizada como uma dependência do **FastAPI**.
@ -87,7 +87,7 @@ O **FastAPI** se encarrega de executá-las na ordem certa.
/// note | Detalhes Técnicos
/// note | Detalhes Técnicos
Tudo isso funciona graças aos <ahref="https://docs.python.org/3/library/contextlib.html"class="external-link"target="_blank">gerenciadores de contexto</a> do Python.
Tudo isso funciona graças aos [gerenciadores de contexto](https://docs.python.org/3/library/contextlib.html) do Python.
O **FastAPI** utiliza eles internamente para alcançar isso.
O **FastAPI** utiliza eles internamente para alcançar isso.
@ -111,7 +111,7 @@ Mas ela existe para ser utilizada caso você precise. 🤓
Se você quiser capturar exceções e criar uma resposta personalizada com base nisso, crie um [Manipulador de Exceções Customizado](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
Se você quiser capturar exceções e criar uma resposta personalizada com base nisso, crie um [Manipulador de Exceções Customizado](../handling-errors.md#install-custom-exception-handlers).
## Dependências com `yield` e `except` { #dependencies-with-yield-and-except }
## Dependências com `yield` e `except` { #dependencies-with-yield-and-except }
@ -233,14 +233,14 @@ participant operation as Operação de Rota
Dependências com `yield` evoluíram ao longo do tempo para cobrir diferentes casos de uso e corrigir alguns problemas.
Dependências com `yield` evoluíram ao longo do tempo para cobrir diferentes casos de uso e corrigir alguns problemas.
Se você quiser ver o que mudou em diferentes versões do FastAPI, você pode ler mais sobre isso no guia avançado, em [Dependências Avançadas - Dependências com `yield`, `HTTPException`, `except` e Tarefas de Background](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
Se você quiser ver o que mudou em diferentes versões do FastAPI, você pode ler mais sobre isso no guia avançado, em [Dependências Avançadas - Dependências com `yield`, `HTTPException`, `except` e Tarefas de Background](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
## Gerenciadores de contexto { #context-managers }
## Gerenciadores de contexto { #context-managers }
### O que são "Gerenciadores de Contexto" { #what-are-context-managers }
### O que são "Gerenciadores de Contexto" { #what-are-context-managers }
"Gerenciadores de Contexto" são qualquer um dos objetos Python que podem ser utilizados com a declaração `with`.
"Gerenciadores de Contexto" são qualquer um dos objetos Python que podem ser utilizados com a declaração `with`.
Por exemplo, <ahref="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"class="external-link"target="_blank">você pode utilizar `with` para ler um arquivo</a>:
Por exemplo, [você pode utilizar `with` para ler um arquivo](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files):
```Python
```Python
with open("./somefile.txt") as f:
with open("./somefile.txt") as f:
@ -264,7 +264,7 @@ Se você está apenas iniciando com o **FastAPI** você pode querer pular isso p
///
///
Em Python, você pode criar Gerenciadores de Contexto ao <ahref="https://docs.python.org/3/reference/datamodel.html#context-managers"class="external-link"target="_blank">criar uma classe com dois métodos: `__enter__()` e `__exit__()`</a>.
Em Python, você pode criar Gerenciadores de Contexto ao [criar uma classe com dois métodos: `__enter__()` e `__exit__()`](https://docs.python.org/3/reference/datamodel.html#context-managers).
Você também pode usá-los dentro de dependências com `yield` do **FastAPI** ao utilizar
Você também pode usá-los dentro de dependências com `yield` do **FastAPI** ao utilizar
`with` ou `async with` dentro da função da dependência:
`with` ou `async with` dentro da função da dependência:
@ -275,8 +275,8 @@ Você também pode usá-los dentro de dependências com `yield` do **FastAPI** a
Outra forma de criar um gerenciador de contexto é utilizando:
Outra forma de criar um gerenciador de contexto é utilizando:
* <ahref="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager"class="external-link"target="_blank">`@contextlib.contextmanager`</a> ou
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) ou
Para alguns tipos de aplicação você pode querer adicionar dependências para toda a aplicação.
Para alguns tipos de aplicação você pode querer adicionar dependências para toda a aplicação.
De forma semelhante a [adicionar `dependencies` aos *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, você pode adicioná-las à aplicação `FastAPI`.
De forma semelhante a [adicionar `dependencies` aos *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md), você pode adicioná-las à aplicação `FastAPI`.
Nesse caso, elas serão aplicadas a todas as *operações de rota* da aplicação:
Nesse caso, elas serão aplicadas a todas as *operações de rota* da aplicação:
E todos os conceitos apresentados na seção sobre [adicionar `dependencies` aos *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} ainda se aplicam, mas nesse caso, para todas as *operações de rota* da aplicação.
E todos os conceitos apresentados na seção sobre [adicionar `dependencies` aos *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md) ainda se aplicam, mas nesse caso, para todas as *operações de rota* da aplicação.
## Dependências para conjuntos de *operações de rota* { #dependencies-for-groups-of-path-operations }
## Dependências para conjuntos de *operações de rota* { #dependencies-for-groups-of-path-operations }
Mais para a frente, quando você ler sobre como estruturar aplicações maiores ([Aplicações Maiores - Múltiplos Arquivos](../../tutorial/bigger-applications.md){.internal-link target=_blank}), possivelmente com múltiplos arquivos, você irá aprender a declarar um único parâmetro `dependencies` para um conjunto de *operações de rota*.
Mais para a frente, quando você ler sobre como estruturar aplicações maiores ([Aplicações Maiores - Múltiplos Arquivos](../../tutorial/bigger-applications.md)), possivelmente com múltiplos arquivos, você irá aprender a declarar um único parâmetro `dependencies` para um conjunto de *operações de rota*.
O **FastAPI** possui um poderoso, mas intuitivo sistema de **<dfntitle="também conhecida como: componentes, recursos, provedores, serviços, injetáveis">Injeção de Dependência</dfn>**.
O **FastAPI** possui um poderoso, mas intuitivo sistema de **<dfntitle="também conhecida como componentes, recursos, provedores, serviços, injetáveis">Injeção de Dependência</dfn>**.
Esse sistema foi pensado para ser fácil de usar, e permitir que qualquer desenvolvedor possa integrar facilmente outros componentes ao **FastAPI**.
Esse sistema foi pensado para ser fácil de usar, e permitir que qualquer desenvolvedor possa integrar facilmente outros componentes ao **FastAPI**.
@ -57,7 +57,7 @@ FastAPI passou a suportar a notação `Annotated` (e começou a recomendá-la) n
Se você utiliza uma versão anterior, ocorrerão erros ao tentar utilizar `Annotated`.
Se você utiliza uma versão anterior, ocorrerão erros ao tentar utilizar `Annotated`.
Certifique-se de [Atualizar a versão do FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
Certifique-se de [Atualizar a versão do FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions) para pelo menos 0.95.1 antes de usar `Annotated`.
///
///
@ -152,7 +152,7 @@ Não faz diferença. O **FastAPI** sabe o que fazer.
/// note | Nota
/// note | Nota
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#in-a-hurry){.internal-link target=_blank} a sessão acerca de `async` e `await` na documentação.
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#in-a-hurry) a sessão acerca de `async` e `await` na documentação.
@ -40,7 +40,7 @@ Eles serão adicionados ao esquema OpenAPI e usados pelas interfaces de document
### Tags com Enums { #tags-with-enums }
### Tags com Enums { #tags-with-enums }
Se você tem uma grande aplicação, você pode acabar acumulando **várias tags**, e você gostaria de ter certeza de que você sempre usa a **mesma tag** para *operações de rota* relacionadas.
Se você tem uma grande aplicação, você pode acabar acumulando **várias tags**, e você gostaria de ter certeza de que você sempre usa a ** mesma tag** para *operações de rota* relacionadas.
Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
@ -58,7 +58,7 @@ Você pode adicionar um `summary` e uma `description`:
Como as descrições tendem a ser longas e cobrir várias linhas, você pode declarar a descrição da *operação de rota* na <dfntitle="uma string de várias linhas como a primeira expressão dentro de uma função (não atribuída a nenhuma variável) usada para documentação">docstring</dfn> da função e o **FastAPI** irá lê-la de lá.
Como as descrições tendem a ser longas e cobrir várias linhas, você pode declarar a descrição da *operação de rota* na <dfntitle="uma string de várias linhas como a primeira expressão dentro de uma função (não atribuída a nenhuma variável) usada para documentação">docstring</dfn> da função e o **FastAPI** irá lê-la de lá.
Você pode escrever <ahref="https://en.wikipedia.org/wiki/Markdown"class="external-link"target="_blank">Markdown</a> na docstring, ele será interpretado e exibido corretamente (levando em conta a indentação da docstring).
Você pode escrever [Markdown](https://en.wikipedia.org/wiki/Markdown) na docstring, ele será interpretado e exibido corretamente (levando em conta a indentação da docstring).
@ -14,7 +14,7 @@ O FastAPI adicionou suporte a `Annotated` (e passou a recomendá-lo) na versão
Se você tiver uma versão mais antiga, verá erros ao tentar usar `Annotated`.
Se você tiver uma versão mais antiga, verá erros ao tentar usar `Annotated`.
Certifique-se de [Atualizar a versão do FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
Certifique-se de [Atualizar a versão do FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions) para pelo menos 0.95.1 antes de usar `Annotated`.
///
///
@ -122,7 +122,7 @@ E o mesmo para <abbr title="less than – menor que"><code>lt</code></abbr>.
## Recapitulando { #recap }
## Recapitulando { #recap }
Com `Query`, `Path` (e outras que você ainda não viu) você pode declarar metadados e validações de string do mesmo modo que em [Parâmetros de consulta e validações de string](query-params-str-validations.md){.internal-link target=_blank}.
Com `Query`, `Path` (e outras que você ainda não viu) você pode declarar metadados e validações de string do mesmo modo que em [Parâmetros de consulta e validações de string](query-params-str-validations.md).
@ -4,9 +4,9 @@ Você pode definir arquivos para serem enviados pelo cliente usando `File`.
/// info | Informação
/// info | Informação
Para receber arquivos enviados, primeiro instale o <ahref="https://github.com/Kludex/python-multipart"class="external-link"target="_blank">`python-multipart`</a>.
Para receber arquivos enviados, primeiro instale [`python-multipart`](https://github.com/Kludex/python-multipart).
Garanta que você criou um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, o ativou e então o instalou, por exemplo:
Garanta que você criou um [ambiente virtual](../virtual-environments.md), o ativou e então o instalou, por exemplo:
```console
```console
$ pip install python-multipart
$ pip install python-multipart
@ -63,8 +63,8 @@ Utilizar `UploadFile` tem várias vantagens sobre `bytes`:
* Um arquivo armazenado na memória até um limite máximo de tamanho, e após passar esse limite, ele será armazenado no disco.
* Um arquivo armazenado na memória até um limite máximo de tamanho, e após passar esse limite, ele será armazenado no disco.
* Isso significa que funcionará bem para arquivos grandes como imagens, vídeos, binários grandes, etc., sem consumir toda a memória.
* Isso significa que funcionará bem para arquivos grandes como imagens, vídeos, binários grandes, etc., sem consumir toda a memória.
* Você pode receber metadados do arquivo enviado.
* Você pode receber metadados do arquivo enviado.
* Ele tem uma <ahref="https://docs.python.org/3/glossary.html#term-file-like-object"class="external-link"target="_blank">file-like</a> interface `assíncrona`.
* Ele tem uma [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) interface `assíncrona`.
* Ele expõe um objeto python <ahref="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile"class="external-link"target="_blank">`SpooledTemporaryFile`</a> que você pode passar diretamente para outras bibliotecas que esperam um objeto semelhante a um arquivo("file-like").
* Ele expõe um objeto python [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) que você pode passar diretamente para outras bibliotecas que esperam um objeto semelhante a um arquivo.
### `UploadFile` { #uploadfile }
### `UploadFile` { #uploadfile }
@ -72,7 +72,7 @@ Utilizar `UploadFile` tem várias vantagens sobre `bytes`:
* `filename`: Uma `str` com o nome do arquivo original que foi enviado (por exemplo, `myimage.jpg`).
* `filename`: Uma `str` com o nome do arquivo original que foi enviado (por exemplo, `myimage.jpg`).
* `content_type`: Uma `str` com o tipo de conteúdo (MIME type / media type) (por exemplo, `image/jpeg`).
* `content_type`: Uma `str` com o tipo de conteúdo (MIME type / media type) (por exemplo, `image/jpeg`).
* `file`: Um <ahref="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile"class="external-link"target="_blank">`SpooledTemporaryFile`</a> (um <ahref="https://docs.python.org/3/glossary.html#term-file-like-object"class="external-link"target="_blank">file-like</a> objeto). Este é o objeto de arquivo Python que você pode passar diretamente para outras funções ou bibliotecas que esperam um objeto semelhante a um arquivo("file-like").
* `file`: Um [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) (um [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) objeto). Este é o objeto de arquivo Python que você pode passar diretamente para outras funções ou bibliotecas que esperam um objeto semelhante a um arquivo.
`UploadFile` tem os seguintes métodos `assíncronos`. Todos eles chamam os métodos de arquivo correspondentes por baixo dos panos (usando o `SpooledTemporaryFile` interno).
`UploadFile` tem os seguintes métodos `assíncronos`. Todos eles chamam os métodos de arquivo correspondentes por baixo dos panos (usando o `SpooledTemporaryFile` interno).
@ -121,7 +121,7 @@ Dados de formulários normalmente são codificados usando o "media type" `applic
Mas quando o formulário inclui arquivos, ele é codificado como `multipart/form-data`. Se você usar `File`, o **FastAPI** saberá que tem que pegar os arquivos da parte correta do corpo da requisição.
Mas quando o formulário inclui arquivos, ele é codificado como `multipart/form-data`. Se você usar `File`, o **FastAPI** saberá que tem que pegar os arquivos da parte correta do corpo da requisição.
Se você quiser ler mais sobre essas codificações e campos de formulário, vá para a <ahref="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST"class="external-link"target="_blank"><abbrtitle="Mozilla Developer Network - Rede de Desenvolvedores da Mozilla">MDN</abbr> web docs para <code>POST</code></a>.
Se você quiser ler mais sobre essas codificações e campos de formulário, vá para a [<abbr title="Mozilla Developer Network - Rede de Desenvolvedores da Mozilla">MDN</abbr> web docs para `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
@ -4,9 +4,9 @@ Você pode utilizar **Modelos Pydantic** para declarar **campos de formulários*
/// info | Informação
/// info | Informação
Para utilizar formulários, instale primeiramente o <ahref="https://github.com/Kludex/python-multipart"class="external-link"target="_blank">`python-multipart`</a>.
Para utilizar formulários, instale primeiramente o [`python-multipart`](https://github.com/Kludex/python-multipart).
Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo, e então instalar. Por exemplo:
Certifique-se de criar um [ambiente virtual](../virtual-environments.md), ativá-lo, e então instalar. Por exemplo:
@ -4,9 +4,9 @@ Você pode definir arquivos e campos de formulário ao mesmo tempo usando `File`
/// info | Informação
/// info | Informação
Para receber arquivos carregados e/ou dados de formulário, primeiro instale <ahref="https://github.com/Kludex/python-multipart"class="external-link"target="_blank">`python-multipart`</a>.
Para receber arquivos carregados e/ou dados de formulário, primeiro instale [`python-multipart`](https://github.com/Kludex/python-multipart).
Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e então instalar, por exemplo:
Certifique-se de criar um [ambiente virtual](../virtual-environments.md), ativá-lo e então instalar, por exemplo:
# Declarar dados de exemplo da requisição { #declare-request-example-data }
# Declare dados de exemplo da requisição { #declare-request-example-data }
Você pode declarar exemplos dos dados que sua aplicação pode receber.
Você pode declarar exemplos dos dados que sua aplicação pode receber.
@ -12,7 +12,7 @@ Você pode declarar `examples` para um modelo Pydantic que serão adicionados ao
Essas informações extras serão adicionadas como estão ao **JSON Schema** de saída para esse modelo e serão usadas na documentação da API.
Essas informações extras serão adicionadas como estão ao **JSON Schema** de saída para esse modelo e serão usadas na documentação da API.
Você pode usar o atributo `model_config`, que recebe um `dict`, conforme descrito na <ahref="https://docs.pydantic.dev/latest/api/config/"class="external-link"target="_blank">documentação do Pydantic: Configuration</a>.
Você pode usar o atributo `model_config`, que recebe um `dict`, conforme descrito na [documentação do Pydantic: Configuration](https://docs.pydantic.dev/latest/api/config/).
Você pode definir `"json_schema_extra"` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`.
Você pode definir `"json_schema_extra"` com um `dict` contendo quaisquer dados adicionais que você queira que apareçam no JSON Schema gerado, incluindo `examples`.
@ -145,12 +145,12 @@ O JSON Schema não tinha `examples`, então o OpenAPI adicionou seu próprio cam
O OpenAPI também adicionou os campos `example` e `examples` a outras partes da especificação:
O OpenAPI também adicionou os campos `example` e `examples` a outras partes da especificação:
* <ahref="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object"class="external-link"target="_blank">`Parameter Object` (na especificação)</a>, usado no FastAPI por:
* [`Parameter Object` (na especificação)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object), usado no FastAPI por:
* `Path()`
* `Path()`
* `Query()`
* `Query()`
* `Header()`
* `Header()`
* `Cookie()`
* `Cookie()`
* <ahref="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object"class="external-link"target="_blank">`Request Body Object`, no campo `content`, no `Media Type Object` (na especificação)</a>, usado no FastAPI por:
* [`Request Body Object`, no campo `content`, no `Media Type Object` (na especificação)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object), usado no FastAPI por:
* `Body()`
* `Body()`
* `File()`
* `File()`
* `Form()`
* `Form()`
@ -163,7 +163,7 @@ Esse parâmetro antigo `examples` específico do OpenAPI agora é `openapi_examp
### Campo `examples` do JSON Schema { #json-schemas-examples-field }
### Campo `examples` do JSON Schema { #json-schemas-examples-field }
Depois, o JSON Schema adicionou um campo <ahref="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5"class="external-link"target="_blank">`examples`</a> em uma nova versão da especificação.
Depois, o JSON Schema adicionou um campo [`examples`](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5) em uma nova versão da especificação.
E então o novo OpenAPI 3.1.0 passou a se basear na versão mais recente (JSON Schema 2020-12), que incluiu esse novo campo `examples`.
E então o novo OpenAPI 3.1.0 passou a se basear na versão mais recente (JSON Schema 2020-12), que incluiu esse novo campo `examples`.
@ -26,11 +26,11 @@ Copie o exemplo em um arquivo `main.py`:
/// info | Informação
/// info | Informação
O pacote <ahref="https://github.com/Kludex/python-multipart"class="external-link"target="_blank">`python-multipart`</a> é instalado automaticamente com o **FastAPI** quando você executa o comando `pip install "fastapi[standard]"`.
O pacote [`python-multipart`](https://github.com/Kludex/python-multipart) é instalado automaticamente com o **FastAPI** quando você executa o comando `pip install "fastapi[standard]"`.
Entretanto, se você usar o comando `pip install fastapi`, o pacote `python-multipart` não é incluído por padrão.
Entretanto, se você usar o comando `pip install fastapi`, o pacote `python-multipart` não é incluído por padrão.
Para instalá-lo manualmente, certifique-se de criar um [ambiente virtual](../../virtual-environments.md){.internal-link target=_blank}, ativá-lo e então instalá-lo com:
Para instalá-lo manualmente, certifique-se de criar um [ambiente virtual](../../virtual-environments.md), ativá-lo e então instalá-lo com:
```console
```console
$ pip install python-multipart
$ pip install python-multipart
@ -45,7 +45,7 @@ Execute o exemplo com:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi dev main.py
$ fastapi dev
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
@ -54,7 +54,7 @@ $ fastapi dev main.py
## Verifique-o { #check-it }
## Verifique-o { #check-it }
Vá até a documentação interativa em: <ahref="http://127.0.0.1:8000/docs"class="external-link"target="_blank">http://127.0.0.1:8000/docs</a>.
Vá até a documentação interativa em: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Você verá algo deste tipo:
Você verá algo deste tipo:
@ -140,7 +140,7 @@ Aqui `tokenUrl="token"` refere-se a uma URL relativa `token` que ainda não cria
Como estamos usando uma URL relativa, se sua API estivesse localizada em `https://example.com/`, então se referiria a `https://example.com/token`. Mas se sua API estivesse localizada em `https://example.com/api/v1/`, então se referiria a `https://example.com/api/v1/token`.
Como estamos usando uma URL relativa, se sua API estivesse localizada em `https://example.com/`, então se referiria a `https://example.com/token`. Mas se sua API estivesse localizada em `https://example.com/api/v1/`, então se referiria a `https://example.com/api/v1/token`.
Usar uma URL relativa é importante para garantir que sua aplicação continue funcionando mesmo em um caso de uso avançado como [Atrás de um Proxy](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
Usar uma URL relativa é importante para garantir que sua aplicação continue funcionando mesmo em um caso de uso avançado como [Atrás de um Proxy](../../advanced/behind-a-proxy.md).
@ -24,13 +24,13 @@ Dessa forma, você pode criar um token com um prazo de expiração, digamos, de
Depois de uma semana, o token expirará e o usuário não estará autorizado, precisando fazer login novamente para obter um novo token. E se o usuário (ou uma terceira parte) tentar modificar o token para alterar a expiração, você seria capaz de descobrir isso, pois as assinaturas não iriam corresponder.
Depois de uma semana, o token expirará e o usuário não estará autorizado, precisando fazer login novamente para obter um novo token. E se o usuário (ou uma terceira parte) tentar modificar o token para alterar a expiração, você seria capaz de descobrir isso, pois as assinaturas não iriam corresponder.
Se você quiser brincar com tokens JWT e ver como eles funcionam, visite <ahref="https://jwt.io/"class="external-link"target="_blank">https://jwt.io</a>.
Se você quiser brincar com tokens JWT e ver como eles funcionam, visite [https://jwt.io](https://jwt.io/).
## Instalar `PyJWT` { #install-pyjwt }
## Instalar `PyJWT` { #install-pyjwt }
Nós precisamos instalar o `PyJWT` para criar e verificar os tokens JWT em Python.
Nós precisamos instalar o `PyJWT` para criar e verificar os tokens JWT em Python.
Certifique-se de criar um [ambiente virtual](../../virtual-environments.md){.internal-link target=_blank}, ativá-lo e então instalar o `pyjwt`:
Certifique-se de criar um [ambiente virtual](../../virtual-environments.md), ativá-lo e então instalar o `pyjwt`:
<divclass="termy">
<divclass="termy">
@ -46,7 +46,7 @@ $ pip install pyjwt
Se você pretente utilizar algoritmos de assinatura digital como o RSA ou o ECDSA, você deve instalar a dependência da biblioteca de criptografia `pyjwt[crypto]`.
Se você pretente utilizar algoritmos de assinatura digital como o RSA ou o ECDSA, você deve instalar a dependência da biblioteca de criptografia `pyjwt[crypto]`.
Você pode ler mais sobre isso na <ahref="https://pyjwt.readthedocs.io/en/latest/installation.html"class="external-link"target="_blank">documentação de instalação do PyJWT</a>.
Você pode ler mais sobre isso na [documentação de instalação do PyJWT](https://pyjwt.readthedocs.io/en/latest/installation.html).
///
///
@ -72,7 +72,7 @@ Ele suporta muitos algoritmos de hashing seguros e utilitários para trabalhar c
O algoritmo recomendado é o "Argon2".
O algoritmo recomendado é o "Argon2".
Certifique-se de criar um [ambiente virtual](../../virtual-environments.md){.internal-link target=_blank}, ativá-lo e então instalar o pwdlib com Argon2:
Certifique-se de criar um [ambiente virtual](../../virtual-environments.md), ativá-lo e então instalar o pwdlib com Argon2:
<divclass="termy">
<divclass="termy">
@ -200,7 +200,7 @@ O importante a se lembrar é que a chave `sub` deve ter um identificador único
## Verifique { #check-it }
## Verifique { #check-it }
Execute o servidor e vá para a documentação: <ahref="http://127.0.0.1:8000/docs"class="external-link"target="_blank">http://127.0.0.1:8000/docs</a>.
Execute o servidor e vá para a documentação: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Extra Models**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}.
Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Extra Models**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}.
@ -216,7 +217,7 @@ Esse é o benefício dos padrões...
## Veja em ação { #see-it-in-action }
## Veja em ação { #see-it-in-action }
Abra o docs interativo: <ahref="http://127.0.0.1:8000/docs"class="external-link"target="_blank">http://127.0.0.1:8000/docs</a>.
Abra o docs interativo: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
**FastAPI** não exige que você use um banco de dados SQL (relacional). Mas você pode usar **qualquer banco de dados** que quiser.
**FastAPI** não exige que você use um banco de dados SQL (relacional). Mas você pode usar **qualquer banco de dados** que quiser.
Aqui veremos um exemplo usando <ahref="https://sqlmodel.tiangolo.com/"class="external-link"target="_blank">SQLModel</a>.
Aqui veremos um exemplo usando [SQLModel](https://sqlmodel.tiangolo.com/).
**SQLModel** é construído sobre <ahref="https://www.sqlalchemy.org/"class="external-link"target="_blank">SQLAlchemy</a> e Pydantic. Ele foi criado pelo mesmo autor do **FastAPI** para ser o par perfeito para aplicações **FastAPI** que precisam usar **bancos de dados SQL**.
**SQLModel** é construído sobre [SQLAlchemy](https://www.sqlalchemy.org/) e Pydantic. Ele foi criado pelo mesmo autor do **FastAPI** para ser o par perfeito para aplicações **FastAPI** que precisam usar **bancos de dados SQL**.
/// tip | Dica
/// tip | Dica
Você pode usar qualquer outra biblioteca de banco de dados SQL ou NoSQL que quiser (em alguns casos chamadas de <abbrtitle="Object Relational Mapper – Mapeador Objeto-Relacional: um termo sofisticado para uma biblioteca onde algumas classes representam tabelas SQL e instâncias representam linhas nessas tabelas">"ORMs"</abbr>), o FastAPI não obriga você a usar nada. 😎
Você pode usar qualquer outra biblioteca de banco de dados SQL ou NoSQL que quiser (em alguns casos chamadas de <abbrtitle="Object Relational Mapper - Mapeador Objeto-Relacional: um termo sofisticado para uma biblioteca onde algumas classes representam tabelas SQL e instâncias representam linhas nessas tabelas">"ORMs"</abbr>), o FastAPI não obriga você a usar nada. 😎
///
///
@ -26,15 +26,15 @@ Mais tarde, para sua aplicação em produção, você pode querer usar um servid
/// tip | Dica
/// tip | Dica
Existe um gerador de projetos oficial com **FastAPI** e **PostgreSQL** incluindo um frontend e mais ferramentas: <ahref="https://github.com/fastapi/full-stack-fastapi-template"class="external-link"target="_blank">https://github.com/fastapi/full-stack-fastapi-template</a>
Existe um gerador de projetos oficial com **FastAPI** e **PostgreSQL** incluindo um frontend e mais ferramentas: [https://github.com/fastapi/full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template)
///
///
Este é um tutorial muito simples e curto, se você quiser aprender sobre bancos de dados em geral, sobre SQL ou recursos mais avançados, acesse a <ahref="https://sqlmodel.tiangolo.com/"class="external-link"target="_blank">documentação do SQLModel</a>.
Este é um tutorial muito simples e curto, se você quiser aprender sobre bancos de dados em geral, sobre SQL ou recursos mais avançados, acesse a [documentação do SQLModel](https://sqlmodel.tiangolo.com/).
## Instalar o `SQLModel` { #install-sqlmodel }
## Instalar o `SQLModel` { #install-sqlmodel }
Primeiro, certifique-se de criar seu [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e, em seguida, instalar o `sqlmodel`:
Primeiro, certifique-se de criar seu [ambiente virtual](../virtual-environments.md), ativá-lo e, em seguida, instalar o `sqlmodel`:
<divclass="termy">
<divclass="termy">
@ -45,7 +45,7 @@ $ pip install sqlmodel
</div>
</div>
## Criar o App com um Único Modelo { #create-the-app-with-a-single-model }
## Crear o App com um Único Modelo { #create-the-app-with-a-single-model }
Vamos criar a primeira versão mais simples do app com um único modelo **SQLModel**.
Vamos criar a primeira versão mais simples do app com um único modelo **SQLModel**.
@ -65,7 +65,7 @@ Existem algumas diferenças:
* `Field(primary_key=True)` informa ao SQLModel que o `id` é a **chave primária** no banco de dados SQL (você pode aprender mais sobre chaves primárias SQL na documentação do SQLModel).
* `Field(primary_key=True)` informa ao SQLModel que o `id` é a **chave primária** no banco de dados SQL (você pode aprender mais sobre chaves primárias SQL na documentação do SQLModel).
**Nota:** Usamos `int | None` para o campo de chave primária para que, no código Python, possamos *criar um objeto sem um `id`* (`id=None`), assumindo que o banco de dados irá *gerá-lo ao salvar*. O SQLModel entende que o banco de dados fornecerá o `id` e *define a coluna como um `INTEGER` não nulo* no esquema do banco de dados. Veja a <ahref="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id"class="external-link"target="_blank">documentação do SQLModel sobre chaves primárias</a> para detalhes.
**Nota:** Usamos `int | None` para o campo de chave primária para que, no código Python, possamos *criar um objeto sem um `id`* (`id=None`), assumindo que o banco de dados irá *gerá-lo ao salvar*. O SQLModel entende que o banco de dados fornecerá o `id` e *define a coluna como um `INTEGER` não nulo* no esquema do banco de dados. Veja a [documentação do SQLModel sobre chaves primárias](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id) para detalhes.
* `Field(index=True)` informa ao SQLModel que ele deve criar um **índice SQL** para essa coluna, o que permitirá buscas mais rápidas no banco de dados ao ler dados filtrados por essa coluna.
* `Field(index=True)` informa ao SQLModel que ele deve criar um **índice SQL** para essa coluna, o que permitirá buscas mais rápidas no banco de dados ao ler dados filtrados por essa coluna.
@ -96,7 +96,7 @@ Vamos criar uma **dependência** do FastAPI com `yield` que fornecerá uma nova
Então, criamos uma dependência `Annotated` chamada `SessionDep` para simplificar o restante do código que usará essa dependência.
Então, criamos uma dependência `Annotated` chamada `SessionDep` para simplificar o restante do código que usará essa dependência.
### Criar Tabelas de Banco de Dados na Inicialização { #create-database-tables-on-startup }
### Criar Tabelas de Banco de Dados na Inicialização { #create-database-tables-on-startup }
@ -110,7 +110,7 @@ Para produção, você provavelmente usaria um script de migração que é execu
/// tip | Dica
/// tip | Dica
O SQLModel terá utilitários de migração envolvendo o Alembic, mas por enquanto, você pode usar o <ahref="https://alembic.sqlalchemy.org/en/latest/"class="external-link"target="_blank">Alembic</a> diretamente.
O SQLModel terá utilitários de migração envolvendo o Alembic, mas por enquanto, você pode usar o [Alembic](https://alembic.sqlalchemy.org/en/latest/) diretamente.
///
///
@ -151,7 +151,7 @@ Você pode executar o app:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi dev main.py
$ fastapi dev
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
@ -168,7 +168,7 @@ Então, vá para a interface `/docs`, você verá que o **FastAPI** está usando
Agora vamos **refatorar** este app um pouco para aumentar a **segurança** e **versatilidade**.
Agora vamos **refatorar** este app um pouco para aumentar a **segurança** e **versatilidade**.
Se você verificar o app anterior, na interface você pode ver que, até agora, ele permite que o cliente decida o `id` do `Hero` a ser criado. 😱
Se você verificar o app anterior, na interface você pode ser que, até agora, ele permite que o cliente decida o `id` do `Hero` a ser criado. 😱
Não deveríamos deixar isso acontecer, eles poderiam sobrescrever um `id` que já atribuimos na base de dados. Decidir o `id` deve ser feito pelo **backend** ou pelo **banco de dados**, **não pelo cliente**.
Não deveríamos deixar isso acontecer, eles poderiam sobrescrever um `id` que já atribuimos na base de dados. Decidir o `id` deve ser feito pelo **backend** ou pelo **banco de dados**, **não pelo cliente**.
@ -336,7 +336,7 @@ Você pode executar o app novamente:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi dev main.py
$ fastapi dev
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
@ -351,6 +351,6 @@ Se você for para a interface `/docs` da API, verá que agora ela está atualiza
## Recapitulando { #recap }
## Recapitulando { #recap }
Você pode usar <ahref="https://sqlmodel.tiangolo.com/"class="external-link"target="_blank">**SQLModel**</a> para interagir com um banco de dados SQL e simplificar o código com *modelos de dados* e *modelos de tabela*.
Você pode usar [**SQLModel**](https://sqlmodel.tiangolo.com/) para interagir com um banco de dados SQL e simplificar o código com *modelos de dados* e *modelos de tabela*.
Você pode aprender muito mais na documentação do **SQLModel**, há um mini <ahref="https://sqlmodel.tiangolo.com/tutorial/fastapi/"class="external-link"target="_blank">tutorial sobre como usar SQLModel com **FastAPI**</a> mais longo. 🚀
Você pode aprender muito mais na documentação do **SQLModel**, há um mini [tutorial sobre como usar SQLModel com **FastAPI**](https://sqlmodel.tiangolo.com/tutorial/fastapi/) mais longo. 🚀
@ -23,7 +23,7 @@ O **FastAPI** fornece o mesmo que `starlette.staticfiles` como `fastapi.staticfi
Isso é diferente de usar um `APIRouter`, pois uma aplicação montada é completamente independente. A OpenAPI e a documentação da sua aplicação principal não incluirão nada da aplicação montada, etc.
Isso é diferente de usar um `APIRouter`, pois uma aplicação montada é completamente independente. A OpenAPI e a documentação da sua aplicação principal não incluirão nada da aplicação montada, etc.
Você pode ler mais sobre isso no [Guia Avançado do Usuário](../advanced/index.md){.internal-link target=_blank}.
Você pode ler mais sobre isso no [Guia Avançado do Usuário](../advanced/index.md).
## Detalhes { #details }
## Detalhes { #details }
@ -37,4 +37,4 @@ Todos esses parâmetros podem ser diferentes de "`static`", ajuste-os de acordo
## Mais informações { #more-info }
## Mais informações { #more-info }
Para mais detalhes e opções, consulte <ahref="https://www.starlette.dev/staticfiles/"class="external-link"target="_blank">a documentação da Starlette sobre Arquivos Estáticos</a>.
Para mais detalhes e opções, consulte [a documentação da Starlette sobre Arquivos Estáticos](https://www.starlette.dev/staticfiles/).
Graças ao <ahref="https://www.starlette.dev/testclient/"class="external-link"target="_blank">Starlette</a>, testar aplicações **FastAPI** é fácil e agradável.
Graças ao [Starlette](https://www.starlette.dev/testclient/), testar aplicações **FastAPI** é fácil e agradável.
Ele é baseado no <ahref="https://www.python-httpx.org"class="external-link"target="_blank">HTTPX</a>, que por sua vez é projetado com base em Requests, por isso é muito familiar e intuitivo.
Ele é baseado no [HTTPX](https://www.python-httpx.org), que por sua vez é projetado com base em Requests, por isso é muito familiar e intuitivo.
Com ele, você pode usar o <ahref="https://docs.pytest.org/"class="external-link"target="_blank">pytest</a> diretamente com **FastAPI**.
Com ele, você pode usar o [pytest](https://docs.pytest.org/) diretamente com **FastAPI**.
## Usando `TestClient` { #using-testclient }
## Usando `TestClient` { #using-testclient }
/// info | Informação
/// info | Informação
Para usar o `TestClient`, primeiro instale o <ahref="https://www.python-httpx.org"class="external-link"target="_blank">`httpx`</a>.
Para usar o `TestClient`, primeiro instale [`httpx`](https://www.python-httpx.org).
Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e instalá-lo, por exemplo:
Certifique-se de criar um [ambiente virtual](../virtual-environments.md), ativá-lo e instalá-lo, por exemplo:
```console
```console
$ pip install httpx
$ pip install httpx
@ -52,7 +52,7 @@ Você também pode usar `from starlette.testclient import TestClient`.
/// tip | Dica
/// tip | Dica
Se você quiser chamar funções `async` em seus testes além de enviar solicitações à sua aplicação FastAPI (por exemplo, funções de banco de dados assíncronas), dê uma olhada em [Testes assíncronos](../advanced/async-tests.md){.internal-link target=_blank} no tutorial avançado.
Se você quiser chamar funções `async` em seus testes além de enviar solicitações à sua aplicação FastAPI (por exemplo, funções de banco de dados assíncronas), dê uma olhada em [Testes assíncronos](../advanced/async-tests.md) no tutorial avançado.
///
///
@ -64,7 +64,7 @@ E sua aplicação **FastAPI** também pode ser composta de vários arquivos/mód
### Arquivo da aplicação **FastAPI** { #fastapi-app-file }
### Arquivo da aplicação **FastAPI** { #fastapi-app-file }
Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicações maiores](bigger-applications.md){.internal-link target=_blank}:
Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicações maiores](bigger-applications.md):
```
```
.
.
@ -140,13 +140,13 @@ Por exemplo:
* Para passar *headers*, use um `dict` no parâmetro `headers`.
* Para passar *headers*, use um `dict` no parâmetro `headers`.
* Para *cookies*, um `dict` no parâmetro `cookies`.
* Para *cookies*, um `dict` no parâmetro `cookies`.
Para mais informações sobre como passar dados para o backend (usando `httpx` ou `TestClient`), consulte a <ahref="https://www.python-httpx.org"class="external-link"target="_blank">documentação do HTTPX</a>.
Para mais informações sobre como passar dados para o backend (usando `httpx` ou `TestClient`), consulte a [documentação do HTTPX](https://www.python-httpx.org).
/// info | Informação
/// info | Informação
Observe que o `TestClient` recebe dados que podem ser convertidos para JSON, não para modelos Pydantic.
Observe que o `TestClient` recebe dados que podem ser convertidos para JSON, não para modelos Pydantic.
Se você tiver um modelo Pydantic em seu teste e quiser enviar seus dados para o aplicativo durante o teste, poderá usar o `jsonable_encoder` descrito em [Codificador compatível com JSON](encoder.md){.internal-link target=_blank}.
Se você tiver um modelo Pydantic em seu teste e quiser enviar seus dados para o aplicativo durante o teste, poderá usar o `jsonable_encoder` descrito em [Codificador compatível com JSON](encoder.md).
///
///
@ -154,7 +154,7 @@ Se você tiver um modelo Pydantic em seu teste e quiser enviar seus dados para o
Depois disso, você só precisa instalar o `pytest`.
Depois disso, você só precisa instalar o `pytest`.
Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ativá-lo e instalá-lo, por exemplo:
Certifique-se de criar um [ambiente virtual](../virtual-environments.md), ativá-lo e instalá-lo, por exemplo: