Rat docs

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 invokes the named handler. Bytes ship as base64 so the same payload can cross 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. Files carry 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 — image processing, OCR, 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)

Next section: Realtime — broadcasting from the server, subscribing from the browser.