RatMinimal web framework

File uploads

Binary uploads use the dedicated endpoint /__rat__/upload, separate from the JSON call path. The browser POSTs a standard multipart/form-data body. The server packs every file part into request.files and calls the named handler. Bytes ship as base64, so the same payload crosses Tail into Python without UTF-8 corruption.

Handler shape

main.rat

A top-level function takes one argument: the request Object. It exposes request.files (an array of file Objects), request.form (the non-file fields), request.path, and request.method. Each file carries name, field, size, content_type, and base64 data.

> save_upload[request]
    [file] << request.files[0]
    [bytes] << base64_decode(file.data)
    << {name: file.name, size: file.size, ok: true}

Wire up the form

Plain multipart, no Rat-specific markup

Use a standard HTML form with enctype="multipart/form-data". The endpoint URL carries the handler name and the page path, so middleware can apply route-based gating around the upload.

> page
<form
    method['POST']
    enctype['multipart/form-data']
    action['/__rat__/upload?fn=save_upload&path=/upload-form']
  >
    <input type['file'] name['photo']>
    <button> upload

Pass bytes through Tail

Python receives base64-ready bytes

Because request.files[0].data is base64, you can hand it straight to a Python Tail handler. The Python side decodes with base64.b64decode(data) and works with the raw bytes for image processing, OCR, or audio transcoding.

# lang/python/vision.py
import base64
def describe(b64):
    raw = base64.b64decode(b64)
    # ...run image model on raw bytes...
    return {"caption": "..."}

# main.rat
> save_upload[request]
    [file] << request.files[0]
    << vision.describe(file.data)

See also Forms · Tail (Python) · Middleware