app = mk_app('solveit-sandbox'); app<modal.app.App>
flowchart TD
A[Create the app] --> B[Define the image]
B --> C[Launch the sandbox]
C --> D[Set up SSH]
Modal is a library that allows you to straightfowardly use cloud GPU compute programmatically in Python. No extra scripts, YAML files or whatnot needed.
Modal allows you to run your code on a GPU in multiple ways.
@app.function(gpu=...) for stateless tasks. When you run a function wrapped like this, Modal spins up a container, runs your function, and then recycles it. Good for one-off compute like inference or batch processing.@app.cls(gpu=...) for stateful classes. Akin to loading a model once at startup and repeatedly calling its methods. Containers stay alive between calls, and hooks like @modal.enter() let you set things up when the container starts.modal.Sandbox. This gives you a full Linux environment that runs continuously. You can SSH in, install packages, and run code interactively.The third option is what solveit-modal will be using.
Look up a Modal App by name, creating it if missing.
An app is like a folder for our projects, or sandboxes in this case. When we create a sandbox, we’ll register it under this app. An app can contain multiple sandboxes.
Create a Modal Image with system + Python packages.
The image describes our Linux environment setup. By default, a build of Debian is used, and we can choose which apt packages, pip packages, or other packages we can have pre-installed.
Image(<function _Image.pip_install.<locals>.build_dockerfile>)
Look up a Modal Volume by name, creating it if missing.
We can also create a volume in which we can persistently store data every time the sandbox is loaded.
def mk_sandbox(
app:App, # Modal App to register the Sandbox with
img:Image, # Image for the Sandbox environment
vol:dict, # Volume for the Sandbox environment
timeout:int, # auto-terminate after this many seconds
gpu:str, # GPU type (e.g. "T4", "A100") or None
secrets:dict, # Sandbox secrets
)->Sandbox:
Create a Modal Sandbox with optional GPU, SSH, and Volumes.
sleep infinity keeps the sandbox alive until it times out or is stopped.It’s now time to construct our sandbox with our defined app, image, and volume on Modal.
INFO - ∞ creating sandbox; this may take 5-10 minutes if you are creating this sandbox for the first time... | 2026-06-17 06:19:52,242
INFO - ✔ sandbox ready | 2026-06-17 06:19:58,555
Sandbox()
Our sandbox is now running. To connect, we need to fetch the tunnel opened on port 22.
Get unencrypted host and port for a Sandbox’s TCP tunnel.
INFO - ✔ gotten tunnel: r438.modal.host:42091 | 2026-06-17 06:20:22,784
('r438.modal.host', 42091)
SSH public key from environment.
We fetch SolveIt’s public key from our environment and inject it into the sandbox’s authorized keys to grant SSH access.
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID5fw9cXzFDJDm8mCuWUOesThxZZfdlPEsKmMSYrDmmH solveit@8321abd9ea3b'
Inject an SSH public key into the Sandbox’s authorized_keys.
We can now start our SSH service.
Start SSH service in the Sandbox, waiting up to ~6 seconds for it to come online.
Pass `cmd` (splitting with `shlex` if string) to `subprocess.run`; return `stdout`; raise `IOError` if fails
File: /usr/local/lib/python3.12/site-packages/fastcore/xtras.py
Type: function
Crafting a function to allow us to easily run bash commands in the sandbox.
Return an SSH function for the given Modal tunnel.
Verify SSH connection to Sandbox and print system info.
System: Linux
Hostname: modal
User: root
Kernel: 4.4.0
Architecture: x86_64
OS Type: GNU/Linux
GPU: Tesla T4
And SolveIt has a connection to Modal! But we’re not quite done yet. What’s left is spinning up an IPython kernel on Modal, and then swapping out SolveIt’s IPython kernel with the one started on Modal. See the ipyfernel module for that.
Additional functions to help you customize your Modal sandbox instance.
List installed system package names.
['adduser',
'alsa-topology-conf',
'alsa-ucm-conf',
'apt',
'aria2',
'autoconf',
'automake',
'autotools-dev',
'base-files',
'base-passwd']
List installed Python packages (name==version).
['accelerate==1.13.0',
'anki==25.9.2',
'beartype==0.22.5',
'blis==1.3.0',
'catalogue==2.0.10',
'cbor2==5.8.0',
'cloudpathlib==0.23.0',
'cloudpickle==3.1.2',
'confection==0.1.5',
'coolname==2.2.0']
Checks whether current environment is Modal or not.
Checks whether current environment is SolveIt or not.