File es una clase que hereda directamente de Form.
Pero recuerda que cuando importas Query, Path, File y otros de fastapi, esos son en realidad funciones que devuelven clases especiales.
Consejo
Para declarar cuerpos de File, necesitas usar File, porque de lo contrario los parámetros serían interpretados como parámetros de query o de cuerpo (JSON).
Los archivos se subirán como "form data".
Si declaras el tipo del parámetro de tu función de path operation como bytes, FastAPI leerá el archivo por ti y recibirás el contenido como bytes.
Ten en cuenta que esto significa que todo el contenido se almacenará en memoria. Esto funcionará bien para archivos pequeños.
Pero hay varios casos en los que podrías beneficiarte de usar UploadFile.
filename: Un str con el nombre original del archivo subido (ej. myimage.jpg).
content_type: Un str con el tipo de contenido (tipo MIME / media type) (ej. image/jpeg).
file: Un SpooledTemporaryFile (un objeto tipo archivo). Este es el objeto archivo real de Python que puedes pasar directamente a otras funciones o librerías que esperan un objeto "tipo archivo".
UploadFile tiene los siguientes métodos async. Todos llaman a los métodos de archivo correspondientes por debajo (usando el SpooledTemporaryFile interno).
write(data): Escribe data (str o bytes) en el archivo.
read(size): Lee size (int) bytes/caracteres del archivo.
seek(offset): Goes to the byte position offset (int) in the file.
Ej., await myfile.seek(0) iría al inicio del archivo.
Esto es especialmente útil si ejecutas await myfile.read() una vez y luego necesitas leer el contenido de nuevo.
close(): Cierra el archivo.
Como todos estos métodos son métodos async, necesitas "await"earlos.
Por ejemplo, dentro de una función de path operationasync puedes obtener el contenido con:
contents=awaitmyfile.read()
Si estás dentro de una función de path operationdef normal, puedes acceder a UploadFile.file directamente, por ejemplo:
contents=myfile.file.read()
Detalles Técnicos de async
Cuando usas los métodos async, FastAPI ejecuta los métodos de archivo en un threadpool y los espera.
Detalles Técnicos de Starlette
El UploadFile de FastAPI hereda directamente del UploadFile de Starlette, pero añade algunas partes necesarias para hacerlo compatible con Pydantic y las otras partes de FastAPI.
La forma en que los formularios HTML (<form></form>) envían los datos al servidor normalmente usa una codificación "especial" para esos datos, es diferente de JSON.
FastAPI se asegurará de leer esos datos del lugar correcto en lugar de JSON.
Detalles Técnicos
Los datos de los formularios se codifican normalmente usando el "media type" application/x-www-form-urlencoded cuando no incluyen archivos.
Pero cuando el formulario incluye archivos, se codifica como multipart/form-data. Si usas File, FastAPI sabrá que tiene que obtener los archivos de la parte correcta del cuerpo.
Puedes declarar múltiples parámetros File y Form en una path operation, pero no puedes también declarar campos Body que esperas recibir como JSON, ya que la request tendrá el cuerpo codificado usando multipart/form-data en lugar de application/json.
Esto no es una limitación de FastAPI, es parte del protocolo HTTP.
También puedes usar File() con UploadFile, por ejemplo, para configurar metadatos adicionales:
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}
🤓 Otras versiones y variantes
Consejo
Preferible usar la versión con Annotated si es posible.
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}
Recibirás, como se declaró, una list de bytes o UploadFiles.
Detalles Técnicos
También podrías usar from starlette.responses import HTMLResponse.
FastAPI proporciona las mismas starlette.responses que fastapi.responses solo como una conveniencia para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette.
Subida de Múltiples Archivos con Metadatos Adicionales¶
Y de la misma manera que antes, puedes usar File() para configurar parámetros adicionales, incluso para UploadFile: