Jul 6, 2026 6.7 KB markdown v1

how to create a programmable folder

a walkthrough for running python functions on modal from sublimated. your code runs on cloud infrastructure with optional GPU access, reads files from your folder, and writes results back.

folder structure

minimum programmable folder:

myfolder/
  _run.py             your python code (required)
  requirements.txt    pip dependencies (optional)
  data.csv            input files (any type)

1. _run.py

the entry point. sublimated detects any folder with a _run.py as a programmable folder. your code runs in the folder's directory — os.listdir(".") returns the folder's files.

simplest example — combine text files:

import os

txt_files = sorted(f for f in os.listdir(".") if f.endswith(".txt"))

lines = []
for fname in txt_files:
    with open(fname) as f:
        lines.append(f"--- {fname} ---")
        lines.append(f.read().strip())

with open("combined.txt", "w") as f:
    f.write("\n".join(lines))

print(f"Done: processed {len(txt_files)} files")

rules for _run.py:

  • reads input files from the current directory (your folder's files)

  • writes output files to the current directory (pushed back to your folder)

  • print() output is captured in execution logs

  • runs as a regular python script — no special imports required

2. requirements.txt

list pip packages your code needs, one per line:

pandas
pillow
matplotlib

sublimated installs these into the modal container image before running your code.

3. multiple functions

for more control, use modal decorators to define multiple functions with different configs:

import modal

app = modal.App("my-analysis")
image = modal.Image.debian_slim().pip_install("pandas", "numpy")

@app.function(image=image)
def analyze():
    import pandas as pd
    df = pd.read_csv("data.csv")
    summary = df.describe()
    summary.to_csv("summary.csv")
    print(f"Analyzed {len(df)} rows")

@app.function(image=image, gpu="T4")
def train():
    import numpy as np
    # GPU-accelerated computation here
    result = np.random.randn(1000, 1000) @ np.random.randn(1000, 1000)
    np.save("result.npy", result)
    print("Training complete")

each @app.function gets its own button in the folder toolbar. click the one you want to run.

GPU options

set the gpu parameter on @app.function:

  • gpu="T4" — budget GPU, good for inference

  • gpu="A10G" — mid-range, good for fine-tuning

  • gpu="A100" — high-end, large models

  • gpu="H100" — top-tier

  • no gpu parameter — CPU only (default)

other function options

@app.function(
    image=image,
    gpu="A10G",
    memory=4096,         # MB of RAM
    cpu=2.0,             # vCPUs
    timeout=600,         # seconds (default 600)
    secrets=[modal.Secret.from_name("my-api-key")],
)
def my_function():
    ...

4. input files

put any files you want to process in the same folder as _run.py. your code reads them with standard python:

import pandas as pd
df = pd.read_csv("sales.csv")

from PIL import Image
img = Image.open("photo.jpg")

import json
with open("config.json") as f:
    config = json.load(f)

all non-python files in the folder are available in the working directory when your function runs.

5. output files

any file your code writes to the current directory gets pushed back to your folder:

# these all create new files in your folder
df.to_csv("report.csv", index=False)
img.save("thumbnail.png")
with open("summary.md", "w") as f:
    f.write("# results\n...")

existing files are updated if your code overwrites them. new files appear in the folder listing.

6. run

from the sublimated web UI:

  1. navigate to your programmable folder

  2. the toolbar shows run buttons for each function (or one "run" button for simple _run.py)

  3. click the button — execution starts on modal

  4. status indicator shows running/success/failed

  5. output files appear in your folder when done

examples

csv analysis

reads all CSV files, produces a summary report with stats and pivot tables:

import os
import pandas as pd

csv_files = sorted(f for f in os.listdir(".") if f.endswith(".csv"))
all_frames = []
for fname in csv_files:
    df = pd.read_csv(fname)
    df["_source"] = fname
    all_frames.append(df)

combined = pd.concat(all_frames, ignore_index=True)

report = ["# csv analysis report\n"]
for fname in csv_files:
    subset = combined[combined["_source"] == fname]
    report.append(f"## {fname}")
    report.append(f"- rows: {len(subset)}")
    for col in subset.select_dtypes(include="number").columns:
        report.append(f"- {col}: sum={subset[col].sum():.2f}, mean={subset[col].mean():.2f}")

with open("report.md", "w") as f:
    f.write("\n".join(report))

source files: csv-analysis/

image processing

creates thumbnails and a contact sheet from images:

import os
from PIL import Image

THUMB_SIZE = (256, 256)
images = sorted(f for f in os.listdir(".") if f.lower().endswith((".png", ".jpg", ".jpeg")))

os.makedirs("thumbs", exist_ok=True)
for fname in images:
    img = Image.open(fname)
    thumb = img.copy()
    thumb.thumbnail(THUMB_SIZE)
    thumb.save(f"thumbs/{os.path.splitext(fname)[0]}_thumb.png", "PNG")

source files: image-resize/

json to chart

generates PNG charts from structured JSON data:

import json
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

with open("data.json") as f:
    doc = json.load(f)

data = doc["data"]
x_vals = [row["month"] for row in data]
y_vals = [row["users"] for row in data]

fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(x_vals, y_vals, color="#4a90d9")
ax.set_title(doc.get("title", "Chart"))
fig.savefig("chart.png", dpi=150, bbox_inches="tight")

source files: json-to-chart/

how it works under the hood

  1. you click run on a function

  2. sublimated generates a scoped access token (10 min, read/write, path-restricted to your folder)

  3. a wrapper function runs on modal that:

    • git clone your folder via the scoped token

    • runs your function with .local()

    • git add . && git commit && git push any changes back

  4. output files appear in your folder

  5. the scoped token expires automatically

what works

  • any python code with pip dependencies

  • GPU acceleration (T4, A10G, A100, H100)

  • reading all file types from your folder

  • writing output files back (text, images, CSVs, binary)

  • multiple functions per file with independent configs

  • real-time status indicators in the UI

  • execution logs

what doesn't work yet

  • streaming output (logs appear after completion)

  • scheduled/cron runs

  • inter-folder dependencies (importing from other folders)

  • custom docker images