diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 1279ac3f1..c29c2bebf 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -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). diff --git a/docs/pt/docs/advanced/dataclasses.md b/docs/pt/docs/advanced/dataclasses.md new file mode 100644 index 000000000..af603ada7 --- /dev/null +++ b/docs/pt/docs/advanced/dataclasses.md @@ -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 `dataclasses` 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 suporte interno para `dataclasses`. + +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: + + + +## 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 serializar 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 documentação do Pydantic sobre dataclasses. + +## Versão + +Isso está disponível desde a versão `0.67.0` do FastAPI. 🔖 diff --git a/docs/pt/docs/how-to/custom-request-and-route.md b/docs/pt/docs/how-to/custom-request-and-route.md new file mode 100644 index 000000000..64325eed9 --- /dev/null +++ b/docs/pt/docs/how-to/custom-request-and-route.md @@ -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, `msgpack`). +* 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 documentação do Starlette sobre Requests. + +/// + +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!} +``` diff --git a/fastapi/__init__.py b/fastapi/__init__.py index 77b52f35b..64d5dd39b 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.115.2" +__version__ = "0.115.3" from starlette import status as status diff --git a/pyproject.toml b/pyproject.toml index c934356d8..edfa81522 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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", ]