mirror of https://github.com/tiangolo/fastapi.git
Merge branch 'master' into fix-duplicate-special-dependency-handling
This commit is contained in:
commit
709b892a0e
|
|
@ -7,6 +7,17 @@ hide:
|
|||
|
||||
## Latest Changes
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/dataclasses.md`. PR [#12475](https://github.com/fastapi/fastapi/pull/12475) by [@leoscarlato](https://github.com/leoscarlato).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/custom-request-and-route.md`. PR [#12483](https://github.com/fastapi/fastapi/pull/12483) by [@devfernandoa](https://github.com/devfernandoa).
|
||||
|
||||
## 0.115.3
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆️ Upgrade Starlette to `>=0.40.0,<0.42.0`. PR [#12469](https://github.com/fastapi/fastapi/pull/12469) by [@defnull](https://github.com/defnull).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Fix broken link in docs. PR [#12495](https://github.com/fastapi/fastapi/pull/12495) by [@eltonjncorreia](https://github.com/eltonjncorreia).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
# Usando Dataclasses
|
||||
|
||||
FastAPI é construído em cima do **Pydantic**, e eu tenho mostrado como usar modelos Pydantic para declarar requisições e respostas.
|
||||
|
||||
Mas o FastAPI também suporta o uso de <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> da mesma forma:
|
||||
|
||||
```Python hl_lines="1 7-12 19-20"
|
||||
{!../../docs_src/dataclasses/tutorial001.py!}
|
||||
```
|
||||
|
||||
Isso ainda é suportado graças ao **Pydantic**, pois ele tem <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">suporte interno para `dataclasses`</a>.
|
||||
|
||||
Então, mesmo com o código acima que não usa Pydantic explicitamente, o FastAPI está usando Pydantic para converter essas dataclasses padrão para a versão do Pydantic.
|
||||
|
||||
E claro, ele suporta o mesmo:
|
||||
|
||||
* validação de dados
|
||||
* serialização de dados
|
||||
* documentação de dados, etc.
|
||||
|
||||
Isso funciona da mesma forma que com os modelos Pydantic. E na verdade é alcançado da mesma maneira por baixo dos panos, usando Pydantic.
|
||||
|
||||
/// info | Informação
|
||||
|
||||
Lembre-se de que dataclasses não podem fazer tudo o que os modelos Pydantic podem fazer.
|
||||
|
||||
Então, você ainda pode precisar usar modelos Pydantic.
|
||||
|
||||
Mas se você tem um monte de dataclasses por aí, este é um truque legal para usá-las para alimentar uma API web usando FastAPI. 🤓
|
||||
|
||||
///
|
||||
|
||||
## Dataclasses em `response_model`
|
||||
|
||||
Você também pode usar `dataclasses` no parâmetro `response_model`:
|
||||
|
||||
```Python hl_lines="1 7-13 19"
|
||||
{!../../docs_src/dataclasses/tutorial002.py!}
|
||||
```
|
||||
|
||||
A dataclass será automaticamente convertida para uma dataclass Pydantic.
|
||||
|
||||
Dessa forma, seu esquema aparecerá na interface de documentação da API:
|
||||
|
||||
<img src="/img/tutorial/dataclasses/image01.png">
|
||||
|
||||
## Dataclasses em Estruturas de Dados Aninhadas
|
||||
|
||||
Você também pode combinar `dataclasses` com outras anotações de tipo para criar estruturas de dados aninhadas.
|
||||
|
||||
Em alguns casos, você ainda pode ter que usar a versão do Pydantic das `dataclasses`. Por exemplo, se você tiver erros com a documentação da API gerada automaticamente.
|
||||
|
||||
Nesse caso, você pode simplesmente trocar as `dataclasses` padrão por `pydantic.dataclasses`, que é um substituto direto:
|
||||
|
||||
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
|
||||
{!../../docs_src/dataclasses/tutorial003.py!}
|
||||
```
|
||||
|
||||
1. Ainda importamos `field` das `dataclasses` padrão.
|
||||
|
||||
2. `pydantic.dataclasses` é um substituto direto para `dataclasses`.
|
||||
|
||||
3. A dataclass `Author` inclui uma lista de dataclasses `Item`.
|
||||
|
||||
4. A dataclass `Author` é usada como o parâmetro `response_model`.
|
||||
|
||||
5. Você pode usar outras anotações de tipo padrão com dataclasses como o corpo da requisição.
|
||||
|
||||
Neste caso, é uma lista de dataclasses `Item`.
|
||||
|
||||
6. Aqui estamos retornando um dicionário que contém `items`, que é uma lista de dataclasses.
|
||||
|
||||
O FastAPI ainda é capaz de <abbr title="converter os dados para um formato que pode ser transmitido">serializar</abbr> os dados para JSON.
|
||||
|
||||
7. Aqui o `response_model` está usando uma anotação de tipo de uma lista de dataclasses `Author`.
|
||||
|
||||
Novamente, você pode combinar `dataclasses` com anotações de tipo padrão.
|
||||
|
||||
8. Note que esta *função de operação de rota* usa `def` regular em vez de `async def`.
|
||||
|
||||
Como sempre, no FastAPI você pode combinar `def` e `async def` conforme necessário.
|
||||
|
||||
Se você precisar de uma atualização sobre quando usar qual, confira a seção _"Com pressa?"_ na documentação sobre [`async` e `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
|
||||
|
||||
9. Esta *função de operação de rota* não está retornando dataclasses (embora pudesse), mas uma lista de dicionários com dados internos.
|
||||
|
||||
O FastAPI usará o parâmetro `response_model` (que inclui dataclasses) para converter a resposta.
|
||||
|
||||
Você pode combinar `dataclasses` com outras anotações de tipo em muitas combinações diferentes para formar estruturas de dados complexas.
|
||||
|
||||
Confira as dicas de anotação no código acima para ver mais detalhes específicos.
|
||||
|
||||
## Saiba Mais
|
||||
|
||||
Você também pode combinar `dataclasses` com outros modelos Pydantic, herdar deles, incluí-los em seus próprios modelos, etc.
|
||||
|
||||
Para saber mais, confira a <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">documentação do Pydantic sobre dataclasses</a>.
|
||||
|
||||
## Versão
|
||||
|
||||
Isso está disponível desde a versão `0.67.0` do FastAPI. 🔖
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
# Requisições Personalizadas e Classes da APIRoute
|
||||
|
||||
Em algum casos, você pode querer sobreescrever a lógica usada pelas classes `Request`e `APIRoute`.
|
||||
|
||||
Em particular, isso pode ser uma boa alternativa para uma lógica em um middleware
|
||||
|
||||
Por exemplo, se você quiser ler ou manipular o corpo da requisição antes que ele seja processado pela sua aplicação.
|
||||
|
||||
/// danger | Perigo
|
||||
|
||||
Isso é um recurso "avançado".
|
||||
|
||||
Se você for um iniciante em **FastAPI** você deve considerar pular essa seção.
|
||||
|
||||
///
|
||||
|
||||
## Casos de Uso
|
||||
|
||||
Alguns casos de uso incluem:
|
||||
|
||||
* Converter requisições não-JSON para JSON (por exemplo, <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>).
|
||||
* Descomprimir corpos de requisição comprimidos com gzip.
|
||||
* Registrar automaticamente todos os corpos de requisição.
|
||||
|
||||
## Manipulando codificações de corpo de requisição personalizadas
|
||||
|
||||
Vamos ver como usar uma subclasse personalizada de `Request` para descomprimir requisições gzip.
|
||||
|
||||
E uma subclasse de `APIRoute` para usar essa classe de requisição personalizada.
|
||||
|
||||
### Criar uma classe `GzipRequest` personalizada
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Isso é um exemplo de brincadeira para demonstrar como funciona, se você precisar de suporte para Gzip, você pode usar o [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank} fornecido.
|
||||
|
||||
///
|
||||
|
||||
Primeiro, criamos uma classe `GzipRequest`, que irá sobrescrever o método `Request.body()` para descomprimir o corpo na presença de um cabeçalho apropriado.
|
||||
|
||||
Se não houver `gzip` no cabeçalho, ele não tentará descomprimir o corpo.
|
||||
|
||||
Dessa forma, a mesma classe de rota pode lidar com requisições comprimidas ou não comprimidas.
|
||||
|
||||
```Python hl_lines="8-15"
|
||||
{!../../docs_src/custom_request_and_route/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Criar uma classe `GzipRoute` personalizada
|
||||
|
||||
Em seguida, criamos uma subclasse personalizada de `fastapi.routing.APIRoute` que fará uso do `GzipRequest`.
|
||||
|
||||
Dessa vez, ele irá sobrescrever o método `APIRoute.get_route_handler()`.
|
||||
|
||||
Esse método retorna uma função. E essa função é o que irá receber uma requisição e retornar uma resposta.
|
||||
|
||||
Aqui nós usamos para criar um `GzipRequest` a partir da requisição original.
|
||||
|
||||
```Python hl_lines="18-26"
|
||||
{!../../docs_src/custom_request_and_route/tutorial001.py!}
|
||||
```
|
||||
|
||||
/// note | Detalhes Técnicos
|
||||
|
||||
Um `Request` também tem um `request.receive`, que é uma função para "receber" o corpo da requisição.
|
||||
|
||||
Um `Request` também tem um `request.receive`, que é uma função para "receber" o corpo da requisição.
|
||||
|
||||
O dicionário `scope` e a função `receive` são ambos parte da especificação ASGI.
|
||||
|
||||
E essas duas coisas, `scope` e `receive`, são o que é necessário para criar uma nova instância de `Request`.
|
||||
|
||||
Para aprender mais sobre o `Request` confira a <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">documentação do Starlette sobre Requests</a>.
|
||||
|
||||
///
|
||||
|
||||
A única coisa que a função retornada por `GzipRequest.get_route_handler` faz de diferente é converter o `Request` para um `GzipRequest`.
|
||||
|
||||
Fazendo isso, nosso `GzipRequest` irá cuidar de descomprimir os dados (se necessário) antes de passá-los para nossas *operações de rota*.
|
||||
|
||||
Depois disso, toda a lógica de processamento é a mesma.
|
||||
|
||||
Mas por causa das nossas mudanças em `GzipRequest.body`, o corpo da requisição será automaticamente descomprimido quando for carregado pelo **FastAPI** quando necessário.
|
||||
|
||||
## Acessando o corpo da requisição em um manipulador de exceção
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Para resolver esse mesmo problema, é provavelmente muito mais fácil usar o `body` em um manipulador personalizado para `RequestValidationError` ([Tratando Erros](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
|
||||
|
||||
Mas esse exemplo ainda é valido e mostra como interagir com os componentes internos.
|
||||
|
||||
///
|
||||
|
||||
Também podemos usar essa mesma abordagem para acessar o corpo da requisição em um manipulador de exceção.
|
||||
|
||||
Tudo que precisamos fazer é manipular a requisição dentro de um bloco `try`/`except`:
|
||||
|
||||
```Python hl_lines="13 15"
|
||||
{!../../docs_src/custom_request_and_route/tutorial002.py!}
|
||||
```
|
||||
|
||||
Se uma exceção ocorrer, a instância `Request` ainda estará em escopo, então podemos ler e fazer uso do corpo da requisição ao lidar com o erro:
|
||||
|
||||
```Python hl_lines="16-18"
|
||||
{!../../docs_src/custom_request_and_route/tutorial002.py!}
|
||||
```
|
||||
|
||||
## Classe `APIRoute` personalizada em um router
|
||||
|
||||
você também pode definir o parametro `route_class` de uma `APIRouter`;
|
||||
|
||||
```Python hl_lines="26"
|
||||
{!../../docs_src/custom_request_and_route/tutorial003.py!}
|
||||
```
|
||||
|
||||
Nesse exemplo, as *operações de rota* sob o `router` irão usar a classe `TimedRoute` personalizada, e terão um cabeçalho extra `X-Response-Time` na resposta com o tempo que levou para gerar a resposta:
|
||||
|
||||
```Python hl_lines="13-20"
|
||||
{!../../docs_src/custom_request_and_route/tutorial003.py!}
|
||||
```
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
||||
|
||||
__version__ = "0.115.2"
|
||||
__version__ = "0.115.3"
|
||||
|
||||
from starlette import status as status
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ classifiers = [
|
|||
"Topic :: Internet :: WWW/HTTP",
|
||||
]
|
||||
dependencies = [
|
||||
"starlette>=0.37.2,<0.41.0",
|
||||
"starlette>=0.40.0,<0.42.0",
|
||||
"pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0",
|
||||
"typing-extensions>=4.8.0",
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue