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 logsruns as a regular python script — no special imports required
2. requirements.txt
list pip packages your code needs, one per line:
pandas
pillow
matplotlibsublimated 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 inferencegpu="A10G"— mid-range, good for fine-tuninggpu="A100"— high-end, large modelsgpu="H100"— top-tierno
gpuparameter — 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:
navigate to your programmable folder
the toolbar shows run buttons for each function (or one "run" button for simple
_run.py)click the button — execution starts on modal
status indicator shows running/success/failed
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
you click run on a function
sublimated generates a scoped access token (10 min, read/write, path-restricted to your folder)
a wrapper function runs on modal that:
git cloneyour folder via the scoped tokenruns your function with
.local()git add . && git commit && git pushany changes back
output files appear in your folder
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