Upload Files in Esmerald: Advanced Guide¶
Uploading files is a common functionality in web applications, and Esmerald makes this process simple using the UploadFile
class. This guide will walk you through how to upload files, both single and multiple, and leverage Esmerald’s powerful features.
📂 Accessing UploadFile
¶
To use the UploadFile
class, you can import it as follows:
from esmerald.core.datastructures import UploadFile
Alternatively:
from esmerald import UploadFile
This class provides an interface for handling file uploads in Esmerald.
🌐 Supported Content Types for File Uploads¶
Esmerald supports different content types for file uploads, which can be specified via the media_type
parameter in the Body
decorator.
Available content types are:
application/x-www-form-urlencoded
multipart/form-data
application/json
You can access the EncodingType
enum to use these content types:
from esmerald.utils.enums import EncodingType
From Esmerald version 0.8+
, you can handle file uploads using Body
with media_type
, or use File
and Form
directly for form and file uploads.
🗂 Single File Upload¶
To upload a single file, use the UploadFile
class. Here's an example of how to handle a single file upload:
Example: Single File Upload¶
from esmerald import Esmerald, Gateway, JSONResponse, UploadFile, Body, post
from esmerald.utils.enums import EncodingType
@post("/upload")
async def upload_file(data: UploadFile = Body(media_type=EncodingType.MULTI_PART)) -> JSONResponse:
"""
Uploads a single file to the server.
"""
content = await data.read()
filename = data.filename
return JSONResponse({"filename": filename, "content": content.decode()})
app = Esmerald(routes=[Gateway(handler=upload_file, name="upload-file")])
Explanation:¶
- The
data
parameter is typed asUploadFile
to accept the file. - The
media_type=EncodingType.MULTI_PART
ensures the body is processed as multipart form data. - The file’s content is read asynchronously, and the filename and content are returned.
🗃 Multiple File Uploads¶
Esmerald allows you to upload multiple files in one request by accepting a list of UploadFile
objects.
Example: Multiple File Upload¶
from typing import List
from esmerald import Esmerald, Gateway, JSONResponse, UploadFile, File, post
@post("/upload")
async def upload_files(data: List[UploadFile] = File()) -> JSONResponse:
"""
Uploads multiple files to the server.
"""
file_details = []
for file in data:
content = await file.read()
file_details.append({"filename": file.filename, "content": content.decode()})
return JSONResponse({"files": file_details})
app = Esmerald(routes=[Gateway(handler=upload_files, name="upload-files")])
Explanation:¶
- The
data
parameter is typed asList[UploadFile]
, allowing multiple files. - The
File()
decorator simplifies handling multiple file uploads by automatically setting the content type to multipart form data. - Each file’s content is read asynchronously, and the details are returned as a JSON array.
📝 Using the File
Parameter¶
You can also use File
directly, which inherits from Body
, to handle file uploads. This makes your code cleaner, as you don't need to specify the media_type=EncodingType.MULTI_PART
—it’s set automatically.
Example: Single File Upload with File
¶
from esmerald import Esmerald, Gateway, JSONResponse, UploadFile, File, post
@post("/upload")
async def upload_file(data: UploadFile = File()) -> JSONResponse:
"""
Uploads a single file to the server.
"""
content = await data.read()
filename = data.filename
return JSONResponse({"filename": filename, "content": content.decode()})
app = Esmerald(routes=[Gateway(handler=upload_file, name="upload-file")])
Example: Multiple File Upload with File
¶
from typing import List
from esmerald import Esmerald, Gateway, JSONResponse, UploadFile, File, post
@post("/upload")
async def upload_files(data: List[UploadFile] = File()) -> JSONResponse:
"""
Uploads multiple files to the server.
"""
file_details = []
for file in data:
content = await file.read()
file_details.append({"filename": file.filename, "content": content.decode()})
return JSONResponse({"files": file_details})
app = Esmerald(routes=[Gateway(handler=upload_files, name="upload-files")])
Explanation:¶
- The
File()
decorator automatically handles multipart form data and simplifies file handling. - Both single and multiple file uploads can be managed easily using
File()
.
⚠️ File Upload Limits¶
You can limit the number of files uploaded or the file size using max_length
and other parameters.
Example: Limit Uploads to Three Files¶
from esmerald import Esmerald, Gateway, JSONResponse, UploadFile, File, post
@post("/upload")
async def upload_files(data: List[UploadFile] = File(..., max_length=3)) -> JSONResponse:
"""
Uploads a maximum of three files to the server.
"""
file_details = []
for file in data:
content = await file.read()
file_details.append({"filename": file.filename, "content": content.decode()})
return JSONResponse({"files": file_details})
app = Esmerald(routes=[Gateway(handler=upload_files, name="upload-files")])
In this case, attempting to upload more than three files will raise a ValidationErrorException
.
🧳 File Handling from Parameters¶
You can also use the File
parameter from the params
module. This differs from UploadFile
, which is used in the data structure.
from esmerald.core.datastructures import File # data structure
or
from esmerald.params import File # parameter
This distinction allows you to handle files with different configurations based on your needs.
📄 API Reference¶
For more detailed information on UploadFile
and its methods, check the Esmerald API Reference.
📌 Conclusion¶
Esmerald makes handling file uploads seamless and flexible, whether you need to upload single or multiple files,
apply limits, or use different encoders. By using the UploadFile
and File
parameters, you can efficiently
manage file uploads in your applications while leveraging Esmerald’s validation and features.