Python SDK
Complete guide to the fcloud Python SDK.
Everything the CLI does is available programmatically. The SDK is the right tool when GPU work is embedded in a larger program — a training harness, an agent loop, a pipeline.
Installation
pip install fcloud-sdkAuthentication
Authenticate once via the CLI (fcloud setup or fcloud set_token), or pass a
token explicitly:
import fcloud
client = fcloud.Client() # uses the saved token / env var
client = fcloud.Client(token="fcloud_sk_...") # explicitToken resolution order: Client(token=...) → FCLOUD_API_KEY env var → saved
token in ~/.fcloud/token → FCLOUD_API_KEY from the nearest .env.
Session-based workflow
Sessions persist state across commands. Use the context manager so the session closes (and stops spending) even on exceptions:
import fcloud
client = fcloud.Client()
project = client.project("my-experiment")
with project.session(sku="gpu_1x_a10g") as s:
s.run(["pip", "install", "transformers"])
s.upload("./data", "data/")
result = s.run(["python", "train.py"])
print(result.stdout)
weights = s.download("model.pt") # bytes
open("model.pt", "wb").write(weights)Commands run from /workspace — the same place upload puts files — so
uploaded scripts run by relative path.
Custom images
Declare the environment once; layers are content-addressed, so the same spec is a cache hit and starts instantly:
from fcloud import Image
image = (
Image.from_registry("nvidia/cuda:12.8.1-devel-ubuntu24.04")
.apt_install(["git", "build-essential"])
.pip_install(["torch", "transformers"])
.env({"PYTHONUNBUFFERED": "1"})
)
project = client.project("my-experiment", image=image)Image.debian_slim() is the lightweight default; named images like
Image.from_name("agent-gpu") ship a pinned GPU training stack (torch,
transformers, flash-attn, vLLM).
Background processes
Start long-running work without blocking:
with project.session(sku="gpu_1x_a10g") as s:
proc = s.spawn(["python", "train.py", "--epochs=100"])
proc.poll() # refresh status
print(proc.output) # read output so far
proc.wait() # block until done
print(proc.exit_code)Stream output live with s.watch(proc) — see
Logs & streaming.
Session lifecycle
Sessions are cold ($0, no host) until first used, then hot while running.
A cold session comes back online automatically the next time you target it —
there is no explicit resume step. s.close() (or fcloud stop from the CLI)
returns it to cold and halts spend; /workspace is preserved either way.
with project.session(sku="gpu_1x_l4") as s:
s.run(["python", "train.py"])
sid = s.session_id
# Later — even days later, on a fresh host, files restored:
s2 = client.attach_session(sid)
s2.run(["ls", "/workspace/"]) # original files are here
s2.close()When a spot host is reclaimed, a session is by default checkpointed and
restored on a fresh host in the same region. Pass checkpoint=False to
project.session(...) / project.cold_session(...) to opt out: the session
is instead rebuilt cold on any available host (/workspace kept, processes
lost, SessionInfo.checkpoint == False). None (the default) defers to
FCLOUD_CHECKPOINT, fcloud.json "checkpoint", then
fcloud config set checkpoint.
with project.session(sku="gpu_1x_h100", checkpoint=False) as s:
s.run(["python", "train.py", "--resume-from", "/workspace/ckpt"])Jobs and sweeps
For run-to-completion batch work, project.job(...) runs a command on an
ephemeral session (no saved filesystem; outputs go to volumes), and
client.map(...) fans a command out over argument bindings as a durable
sweep. See Batch: jobs & sweeps for both.
Volumes
client.list_volume_files("results") # [{path, size, ...}]
data = client.read_volume_file("results", "model.pt") # bytes, no session
client.download_volume_file("results", "model.pt", "./model.pt")
client.delete_volume("results")Mount into a session at creation with volume_mounts=[{"name": ..., "mount_path": ...}] — semantics match the CLI's --volume
(Volumes).
Mixing CLI and SDK
Both talk to the same sessions. A common pattern: provision and iterate from
the CLI, then follow the work programmatically (or vice versa) — any session id
printed by fcloud create works with client.attach_session(sid), and any SDK
session shows up in fcloud sessions.