Skip to content

File Upload

SØAD makes file uploads easy and straightforward using standard HTML form input and built-in request handling. Uploaded files are automatically processed by the framework and made available through named request parameters.


1. HTML Form Setup

To enable file upload in a form, two requirements must be met:

  • The <form> element must have the enctype attribute set to multipart/form-data
  • An <input> element of type="file" must be included with a name attribute

Example HTML:

<form action="/t/upload/image" method="post" enctype="multipart/form-data">
    <input type="file" name="photo" required>
    <button type="submit">Upload</button>
</form>

In this example:

  • The input field is named photo
  • SØAD will handle this input and extract the following parameters:

    • photo → the file content as bytes
    • photo_ft → the MIME type (e.g., image/png)
    • photo_fn → the original filename (e.g., myphoto.jpg)

2. Handling the Upload in Transaction

The uploaded file content and its metadata can be retrieved from ctx.getRequest().

Example Transaction:

from utils import render

from java.io import File
from com.google.common.io import Files

class Image(object):
    def upload(self, ctx):
        request = ctx.getRequest()
        file_content = request.getParameter("photo") # byte[] content
        file_type = request.getParameter("photo_ft") # MIME type
        file_name = request.getParameter("photo_fn") # Original filename

        # Check if file has been uploaded
        if file_content:

            # Validate file type
            if file_type not in ["image/png", "image/jpeg"]:
                ctx.output["message"] = "Invalid file type. Only PNG and JPEG are allowed."
                ctx.go_to = render.as_view(ctx, "upload_status")
                return

            # Save file to a directory
            path = "/tmp/uploads/" + file_name
            file = File(path)

            Files.write(file_content, file)

            ctx.output["message"] = "File uploaded successfully: " + file_name
            ctx.go_to = render.as_view(ctx, "upload_status")