13 KiB
Resposta Personalizada - HTML, Stream, File e outras
Por padrão, o FastAPI irá retornar respostas utilizando JSONResponse
.
Mas você pode sobrescrever esse comportamento utilizando Response
diretamente, como visto em Retornando uma Resposta Diretamente{.internal-link target=_blank}.
Mas se você retornar uma Response
diretamente (ou qualquer subclasse, como JSONResponse
), os dados não serão convertidos automaticamente (mesmo que você declare um response_model
), e a documentação não será gerada automaticamente (por exemplo, incluindo o "media type", no cabeçalho HTTP Content-Type
como parte do esquema OpenAPI gerado).
Mas você também pode declarar a Response
que você deseja utilizar (e.g. qualquer subclasse de Response
), em um decorador de operação de rota utilizando o parâmetro response_class
.
Os conteúdos que você retorna em sua função de operador de rota serão colocados dentro dessa Response
.
E se a Response
tiver um media type JSON (application/json
), como é o caso com JSONResponse
e UJSONResponse
, os dados que você retornar serão automaticamente convertidos (e filtrados) com qualquer response_model
do Pydantic que for declarado em sua função de operador de rota.
/// note | Nota
Se você utilizar uma classe de Resposta sem media type, o FastAPI esperará que sua resposta não tenha conteúdo, então ele não irá documentar o formato da resposta na documentação OpenAPI gerada.
///
Utilizando ORJSONResponse
Por exemplo, se você precisa bastante de performance, você pode instalar e utilizar o orjson
e definir a resposta para ser uma ORJSONResponse
.
Importe a classe, ou subclasse, de Response
que você deseja utilizar e declare ela no decorador de operação de rota.
Para respostas grandes, retornar uma Response
diretamente é muito mais rápido que retornar um dicionário.
Isso ocorre por que, por padrão, o FastAPI irá verificar cada item dentro do dicionário e garantir que ele seja serializável para JSON, utilizando o mesmoCodificador Compatível com JSON{.internal-link target=_blank} explicado no tutorial. Isso permite que você retorne objetos abstratos, como modelos do banco de dados, por exemplo.
Mas se você tem certeza que o conteúdo que você está retornando é serializável com JSON, você pode passá-lo diretamente para a classe de resposta e evitar o trabalho extra que o FastAPI teria ao passar o conteúdo pelo jsonable_encoder
antes de passar para a classe de resposta.
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
/// info | Informação
O parâmetro response_class
também será usado para definir o "media type" da resposta.
Neste caso, o cabeçalho HTTP Content-Type
irá ser definido como application/json
.
E será documentado como tal no OpenAPI.
///
/// tip | Dica
A ORJSONResponse
está disponível apenas no FastAPI, e não no Starlette.
///
Resposta HTML
Para retornar uma resposta com HTML diretamente do FastAPI, utilize HTMLResponse
.
- Importe
HTMLResponse
- Passe
HTMLResponse
como o parâmetro deresponse_class
do seu decorador de operação de rota.
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
/// info | Informação
O parâmetro response_class
também será usado para definir o "media type" da resposta.
Neste caso, o cabeçalho HTTP Content-Type
será definido como text/html
.
E será documentado como tal no OpenAPI.
///
Retornando uma Response
Como visto em Retornando uma Resposta Diretamente{.internal-link target=_blank}, você também pode sobrescrever a resposta diretamente na sua operação de rota, ao retornar ela.
O mesmo exemplo de antes, retornando uma HTMLResponse
, poderia parecer com:
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
/// warning | Aviso
Uma Response
retornada diretamente em sua função de operação de rota não será documentada no OpenAPI (por exemplo, o Content-Type
não será documentado) e não será visível na documentação interativa automática.
///
/// info | Informação
Obviamente, o cabeçalho Content-Type
, o código de status, etc, virão do objeto Response
que você retornou.
///
Documentar no OpenAPI e sobrescrever Response
Se você deseja sobrescrever a resposta dentro de uma função, mas ao mesmo tempo documentar o "media type" no OpenAPI, você pode utilizar o parâmetro response_class
E retornar um objeto Response
.
A response_class
será usada apenas para documentar o OpenAPI da operação de rota, mas sua Response
será usada como foi definida.
Retornando uma HTMLResponse
diretamente
Por exemplo, poderia ser algo como:
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
Neste exemplo, a função generate_html_response()
já cria e retorna uma Response
em vez de retornar o HTML em uma str
.
Ao retornar o resultado chamando generate_html_response()
, você já está retornando uma Response
que irá sobrescrever o comportamento padrão do FastAPI.
Mas se você passasse uma HTMLResponse
em response_class
também, o FastAPI saberia como documentar isso no OpenAPI e na documentação interativa como um HTML com text/html
:

Respostas disponíveis
Aqui estão algumas dos tipos de resposta disponíveis.
Lembre-se que você pode utilizar Response
para retornar qualquer outra coisa, ou até mesmo criar uma subclasse personalizada.
/// note | Detalhes Técnicos
Você também pode utilizar from starlette.responses import HTMLResponse
.
O FastAPI provê a mesma starlette.responses
como fastapi.responses
apenas como uma facilidade para você, desenvolvedor. Mas a maioria das respostas disponíveis vêm diretamente do Starlette.
///
Response
A classe principal de respostas, todas as outras respostas herdam dela.
Você pode retorná-la diretamente.
Ela aceita os seguintes parâmetros:
content
- Uma sequência de caracteres (str
) oubytes
.status_code
- Um código de status HTTP do tipoint
.headers
- Um dicionáriodict
de strings.media_type
- Umastr
informando o media type. E.g."text/html"
.
O FastAPI (Starlette, na verdade) irá incluir o cabeçalho Content-Length automaticamente. Ele também irá incluir o cabeçalho Content-Type, baseado no media_type
e acrescentando uma codificação para tipos textuais.
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
HTMLResponse
Usa algum texto ou sequência de bytes e retorna uma resposta HTML. Como você leu acima.
PlainTextResponse
Usa algum texto ou sequência de bytes para retornar uma resposta de texto não formatado.
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
JSONResponse
Pega alguns dados e retorna uma resposta com codificação application/json
.
É a resposta padrão utilizada no FastAPI, como você leu acima.
ORJSONResponse
Uma alternativa mais rápida de resposta JSON utilizando o orjson
, como você leu acima.
/// info | Informação
Essa resposta requer a instalação do pacote orjson
, com o comando pip install orjson
, por exemplo.
///
UJSONResponse
Uma alternativa de resposta JSON utilizando a biblioteca ujson
.
/// info | Informação
Essa resposta requer a instalação do pacote ujson
, com o comando pip install ujson
, por exemplo.
///
/// warning | Aviso
ujson
é menos cauteloso que a implementação nativa do Python na forma que os casos especiais são tratados
///
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
/// tip | Dica
É possível que ORJSONResponse
seja uma alternativa mais rápida.
///
RedirectResponse
Retorna um redirecionamento HTTP. Utiliza o código de status 307 (Redirecionamento Temporário) por padrão.
Você pode retornar uma RedirectResponse
diretamente:
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
Ou você pode utilizá-la no parâmetro response_class
:
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
Se você fizer isso, então você pode retornar a URL diretamente da sua função de operação de rota
Neste caso, o status_code
utilizada será o padrão de RedirectResponse
, que é 307
.
Você também pode utilizar o parâmetro status_code
combinado com o parâmetro response_class
:
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
StreamingResponse
Recebe uma gerador assíncrono ou um gerador/iterador comum e retorna o corpo da requisição continuamente (stream).
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
Utilizando StreamingResponse
com objetos semelhantes a arquivos
Se você tiver um objeto semelhante a um arquivo (e.g. o objeto retornado por open()
), você pode criar uma função geradora para iterar sobre esse objeto.
Dessa forma, você não precisa ler todo o arquivo na memória primeiro, e você pode passar essa função geradora para StreamingResponse
e retorná-la.
Isso inclui muitas bibliotecas que interagem com armazenamento em nuvem, processamento de vídeos, entre outras.
{!../../docs_src/custom_response/tutorial008.py!}
-
Essa é a função geradora. É definida como "função geradora" porque contém declarações
yield
nela. -
Ao utilizar o bloco
with
, nós garantimos que o objeto semelhante a um arquivo é fechado após a função geradora ser finalizada. Isto é, após a resposta terminar de ser enivada. -
Essa declaração
yield from
informa a função para iterar sobre essa coisa nomeada defile_like
. E então, para cada parte iterada, fornece essa parte como se viesse dessa função geradora (iterfile
).Então, é uma função geradora que transfere o trabalho de "geração" para alguma outra coisa interna.
Fazendo dessa forma, podemos colocá-la em um bloco
with
, e assim garantir que o objeto semelhante a um arquivo é fechado quando a função termina.
/// tip | Dica
Perceba que aqui estamos utilizando o open()
da biblioteca padrão que não suporta async
e await
, e declaramos a operação de rota com o def
básico.
///
FileResponse
Envia um arquivo de forma assíncrona e contínua (stream). * Recebe um conjunto de argumentos do construtor diferente dos outros tipos de resposta:
path
- O caminho do arquivo que será transmitidoheaders
- quaisquer cabeçalhos que serão incluídos, como um dicionário.media_type
- Uma string com o media type. Se não for definida, o media type é inferido a partir do nome ou caminho do arquivo.filename
- Se for definido, é incluído no cabeçalhoContent-Disposition
.
Respostas de Arquivos incluem o tamanho do arquivo, data da última modificação e ETags apropriados, nos cabeçalhos Content-Length
, Last-Modified
e ETag
, respectivamente.
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
Você também pode usar o parâmetro response_class
:
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
Nesse caso, você pode retornar o caminho do arquivo diretamente da sua função de operação de rota.
Classe de resposta personalizada
Você pode criar sua própria classe de resposta, herdando de Response
e usando essa nova classe.
Por exemplo, vamos supor que você queira utilizar o orjson
, mas com algumas configurações personalizadas que não estão incluídas na classe ORJSONResponse
.
Vamos supor também que você queira retornar um JSON indentado e formatado, então você quer utilizar a opção orjson.OPT_INDENT_2
do orjson.
Você poderia criar uma classe CustomORJSONResponse
. A principal coisa a ser feita é sobrecarregar o método render da classe Response, Response.render(content)
, que retorna o conteúdo em bytes, para retornar o conteúdo que você deseja:
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
Agora em vez de retornar:
{"message": "Hello World"}
...essa resposta retornará:
{
"message": "Hello World"
}
Obviamente, você provavelmente vai encontrar maneiras muito melhores de se aproveitar disso do que a formatação de JSON. 😉
Classe de resposta padrão
Quando você criar uma instância da classe FastAPI ou um APIRouter
você pode especificar qual classe de resposta utilizar por padrão.
O padrão que define isso é o default_response_class
.
No exemplo abaixo, o FastAPI irá utilizar ORJSONResponse
por padrão, em todas as operações de rota, em vez de JSONResponse
.
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
/// tip | Dica
Você ainda pode substituir response_class
em operações de rota como antes.
///
Documentação adicional
Você também pode declarar o media type e muitos outros detalhes no OpenAPI utilizando responses
: Retornos Adicionais no OpenAPI{.internal-link target=_blank}.