Mas lembre-se que quando você importa Query, Path, File e outros de fastapi, eles são, na verdade, funções que retornam classes especiais.
Dica
Para declarar corpos de arquivos, você precisa usar File, caso contrário, os parâmetros seriam interpretados como parâmetros de consulta ou parâmetros de corpo (JSON).
Os arquivos serão enviados como "dados de formulário".
Se você declarar o tipo do parâmetro da função da sua operação de rota como bytes, o FastAPI lerá o arquivo para você e você receberá o conteúdo como bytes.
Mantenha em mente que isso significa que todo o conteúdo será armazenado na memória. Isso funcionará bem para arquivos pequenos.
Mas há muitos casos em que você pode se beneficiar do uso de UploadFile.
Ele expõe um objeto python SpooledTemporaryFile que você pode passar diretamente para outras bibliotecas que esperam um objeto semelhante a um arquivo("file-like").
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 (tipo MIME / tipo de mídia) (por exemplo, image/jpeg).
file: Um SpooledTemporaryFile (um file-like 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").
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).
write(data): Escreve data (str ou bytes) no arquivo.
read(size): Lê size (int) bytes/caracteres do arquivo.
seek(offset): Vai para o byte na posição offset (int) no arquivo.
Por exemplo, await myfile.seek(0) irá para o início do arquivo.
Isso é especialmente útil se você executar await myfile.read() uma vez e precisar ler o conteúdo novamente.
close(): Fecha o arquivo.
Como todos esses métodos são métodos assíncronos, você precisa "aguardar" por eles.
Por exemplo, dentro de uma função de operação de rotaassíncrona, você pode obter o conteúdo com:
contents=awaitmyfile.read()
Se você estiver dentro de uma função de operação de rota normal def, você pode acessar o UploadFile.file diretamente, por exemplo:
contents=myfile.file.read()
Detalhes Técnicos do async
Quando você usa os métodos async, o FastAPI executa os métodos de arquivo em um threadpool e aguarda por eles.
Detalhes Técnicos do Starlette
O UploadFile do FastAPI herda diretamente do UploadFile do *Starlette** , mas adiciona algumas partes necessárias para torná-lo compatível com o Pydantic e as outras partes do FastAPI.
O jeito que os formulários HTML (<form></form>) enviam os dados para o servidor normalmente usa uma codificação "especial" para esses dados, a qual é diferente do JSON.
FastAPI se certificará de ler esses dados do lugar certo, ao invés de JSON.
Detalhes Técnicos
Dados de formulários normalmente são codificados usando o "media type" (tipo de mídia) application/x-www-form-urlencoded quando não incluem arquivos.
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 MDN web docs para POST.
Aviso
Você pode declarar múltiplos parâmetros File e Form em uma operação de rota, mas você não pode declarar campos Body que você espera receber como JSON, pois a requisição terá o corpo codificado usando multipart/form-data ao invés de application/json.
Isso não é uma limitação do FastAPI, é parte do protocolo HTTP.
Você também pode usar File() com UploadFile, por exemplo, para definir metadados adicionais:
fromtypingimportAnnotatedfromfastapiimportFastAPI,File,UploadFileapp=FastAPI()@app.post("/files/")asyncdefcreate_file(file:Annotated[bytes,File(description="A file read as bytes")]):return{"file_size":len(file)}@app.post("/uploadfile/")asyncdefcreate_upload_file(file:Annotated[UploadFile,File(description="A file read as UploadFile")],):return{"filename":file.filename}
🤓 Other versions and variants
fromfastapiimportFastAPI,File,UploadFilefromtyping_extensionsimportAnnotatedapp=FastAPI()@app.post("/files/")asyncdefcreate_file(file:Annotated[bytes,File(description="A file read as bytes")]):return{"file_size":len(file)}@app.post("/uploadfile/")asyncdefcreate_upload_file(file:Annotated[UploadFile,File(description="A file read as UploadFile")],):return{"filename":file.filename}
Tip
Prefer to use the Annotated version if possible.
fromfastapiimportFastAPI,File,UploadFileapp=FastAPI()@app.post("/files/")asyncdefcreate_file(file:bytes=File(description="A file read as bytes")):return{"file_size":len(file)}@app.post("/uploadfile/")asyncdefcreate_upload_file(file:UploadFile=File(description="A file read as UploadFile"),):return{"filename":file.filename}
Você receberá, tal como declarado, uma list de bytes ou UploadFile.
Detalhes Técnicos
Você pode também pode usar from starlette.responses import HTMLResponse.
FastAPI providencia o mesmo starlette.responses que fastapi.responses apenas como uma conveniência para você, o desenvolvedor. Mas a maioria das respostas disponíveis vem diretamente do Starlette.
Uploads de Múltiplos Arquivos com Metadados Adicionais¶
Da mesma forma de antes, você pode usar File() para definir parâmetros adicionais, mesmo para UploadFile: