Apothic Client Classes and Sandboxes Reference
Reference for @app.cls(...), @method(), enter/exit hooks, Cls, BoundCls, Sandbox, SandboxHandle, and SandboxSession.
Last updated: 4/21/2026
API Version: v0.1.0
apothic-clientapireferencestatefulsandbox
Apothic Client Classes and Sandboxes Reference
Apothic supports two main stateful shapes:
- object-style resources through
@app.cls(...) - workspace-style resources through
app.sandbox(...)
Class lifecycle decorators
@method(...)
@method(
*,
tags: Iterable[str] | None = None,
metadata: dict[str, Any] | None = None,
)
@enter() and @exit()
enter = @enter()
exit = @exit()
@app.cls(...)
@app.cls(
*,
name: str | None = None,
gpu: str | list[str] | None = None,
gpu_count: int | None = None,
min_vram_gb: int | None = None,
geolocation: str | list[str] | None = None,
offer_filters: OfferFiltersModel | dict[str, Any] | None = None,
max_cost_per_hour_usd: float | None = None,
max_cost_per_tflop_hour_usd: float | None = None,
min_total_flops: float | None = None,
min_gpu_ram_bandwidth_gbps: float | None = None,
min_cpu_cores: float | None = None,
min_cpu_ram_gb: float | None = None,
min_cpu_ghz: float | None = None,
min_disk_bandwidth_mb_s: float | None = None,
min_internet_upload_mbps: float | None = None,
min_internet_download_mbps: float | None = None,
secure_cloud_only: bool | None = None,
cpu: int = 1,
memory_mb: int = 1024,
disk_gb: float | None = None,
timeout_s: int = 600,
retries: int | Retries | None = None,
max_retries: int = 0,
concurrent_requests: int = 1,
max_pending_tasks: int = 100,
max_containers: int = 1,
tasks_per_container: int = 1,
image: Image | None = None,
secrets: list[Secret] | None = None,
volumes: dict[str, StorageMount] | list[StorageMount] | None = None,
tags: Iterable[str] | None = None,
metadata: dict[str, Any] | None = None,
)
Cls
Lookup helpers
Cls.from_name(
app_name: str,
class_name: str,
*,
client: ControlPlaneClient | None = None,
base_url: str | None = None,
) -> Cls
Cls.from_handle(
handle: ClassInstanceHandle | dict[str, Any] | str,
*,
client: ControlPlaneClient | None = None,
base_url: str | None = None,
) -> ClassInstance
Properties
cls_handle.name -> str
cls_handle.methods -> dict[str, Function[Any] | RemoteFunction]
cls_handle.method_names -> tuple[str, ...]
cls_handle.method_infos -> dict[str, MethodInfo]
cls_handle.close_function -> Function[Any] | RemoteFunction | None
cls_handle.signature -> inspect.Signature | None
cls_handle.parameters -> constructor parameter metadata
cls_handle.parameter_names -> tuple[str, ...]
cls_handle.tags -> tuple[str, ...]
cls_handle.metadata -> dict[str, Any]
cls_handle.enter_hook_names -> tuple[str, ...]
cls_handle.exit_hook_names -> tuple[str, ...]
cls_handle.remote_only -> bool
cls_handle.local_cls -> type[Any] | None
cls_handle.app_name -> str | None
Methods
cls_handle.inspect() -> ClassInfo
cls_handle.has_method(name: str) -> bool
cls_handle.method_info(name: str) -> MethodInfo
cls_handle.bind(*args, **kwargs) -> ClassInstance
cls_handle.remote(*args, **kwargs) -> ClassInstance
cls_handle.partial(*args, **kwargs) -> BoundCls
cls_handle.new(*args, **kwargs) -> ClassInstance
cls_handle.named(instance_id: str, *args, **kwargs) -> ClassInstance
cls_handle.local(*args, **kwargs) -> LocalClassInstance
cls_handle.attach(handle: ClassInstanceHandle | dict[str, Any] | str) -> ClassInstance
cls_handle.close_handle(handle: ClassInstanceHandle | dict[str, Any] | str) -> Any
cls_handle.close_named(instance_id: str, *args, **kwargs) -> Any
BoundCls
bound.cls -> Cls
bound.signature -> inspect.Signature | None
bound.init_args -> tuple[Any, ...]
bound.init_kwargs -> dict[str, Any]
bound.bind(*args, **kwargs) -> ClassInstance
bound.remote(*args, **kwargs) -> ClassInstance
bound.local(*args, **kwargs) -> LocalClassInstance
bound.new(*args, **kwargs) -> ClassInstance
bound.named(instance_id: str, *args, **kwargs) -> ClassInstance
bound.partial(*args, **kwargs) -> BoundCls
bound.close_handle(handle: ClassInstanceHandle | dict[str, Any] | str) -> Any
bound.close_named(instance_id: str, *args, **kwargs) -> Any
Sandbox
Construction and lookup
app.sandbox(
*,
name: str = "default",
gpu: str | list[str] | None = None,
gpu_count: int | None = None,
min_vram_gb: int | None = None,
geolocation: str | list[str] | None = None,
offer_filters: OfferFiltersModel | dict[str, Any] | None = None,
max_cost_per_hour_usd: float | None = None,
max_cost_per_tflop_hour_usd: float | None = None,
min_total_flops: float | None = None,
min_gpu_ram_bandwidth_gbps: float | None = None,
min_cpu_cores: float | None = None,
min_cpu_ram_gb: float | None = None,
min_cpu_ghz: float | None = None,
min_disk_bandwidth_mb_s: float | None = None,
min_internet_upload_mbps: float | None = None,
min_internet_download_mbps: float | None = None,
secure_cloud_only: bool | None = None,
cpu: int = 1,
memory_mb: int = 1024,
disk_gb: float | None = None,
timeout_s: int = 3600,
retries: int | Retries | None = None,
max_retries: int = 0,
concurrent_requests: int = 1,
max_pending_tasks: int = 100,
max_containers: int = 1,
tasks_per_container: int = 1000,
image: Image | None = None,
secrets: list[Secret] | None = None,
volumes: dict[str, StorageMount] | list[StorageMount] | None = None,
) -> Sandbox
Sandbox.from_name(
app_name: str,
sandbox_name: str,
*,
client: ControlPlaneClient | None = None,
base_url: str | None = None,
) -> Sandbox
Properties and methods
sandbox.name -> str
sandbox.app_name -> str | None
sandbox.method_names -> tuple[str, ...]
sandbox.tags -> tuple[str, ...]
sandbox.metadata -> dict[str, Any]
sandbox.signature -> inspect.Signature | None
sandbox.create(*, cwd: str = "/", env: dict[str, Any] | None = None) -> SandboxSession
sandbox.named(sandbox_id: str, *, cwd: str = "/", env: dict[str, Any] | None = None) -> SandboxSession
sandbox.local(*, cwd: str = "/", env: dict[str, Any] | None = None) -> SandboxSession
sandbox.attach(handle: SandboxHandle | dict[str, Any] | str) -> SandboxSession
sandbox.inspect() -> SandboxInfo
sandbox.close_handle(handle: SandboxHandle | dict[str, Any] | str) -> Any
sandbox.close_named(sandbox_id: str, *, cwd: str = "/", env: dict[str, Any] | None = None) -> Any
SandboxSession
session.sandbox -> Sandbox
session.local -> bool
session.closed -> bool
session.id -> str
session.handle -> SandboxHandle
session.handle_json -> str
session.method_names -> tuple[str, ...]
session.has_method(name: str) -> bool
session.inspect() -> SandboxSessionInfo
session.pwd() -> str
session.get_env() -> dict[str, str]
session.chdir(path: str) -> str
session.update_env(values: dict[str, Any] | None = None, /, **kwargs: Any) -> dict[str, str]
session.set_env(**kwargs: Any) -> dict[str, str]
session.unset_env(*names: str) -> dict[str, str]
session.exists(path: str = ".") -> bool
session.listdir(path: str = ".") -> list[str]
session.mkdir(path: str, *, parents: bool = True, exist_ok: bool = True) -> str
session.read_text(path: str, *, encoding: str = "utf-8") -> str
session.write_text(path: str, content: str, *, encoding: str = "utf-8", append: bool = False, make_parents: bool = False) -> str
session.read_bytes(path: str) -> bytes
session.write_bytes(path: str, content: bytes | bytearray | memoryview, *, append: bool = False, make_parents: bool = False) -> str
session.upload_file(local_path: str | Path, remote_path: str, *, make_parents: bool = False) -> str
session.download_file(remote_path: str, local_path: str | Path, *, make_parents: bool = False) -> Path
session.exec(command: str | list[str] | tuple[str, ...], *, shell: bool = False, cwd: str | None = None, env: dict[str, Any] | None = None, timeout_s: float | None = None) -> SandboxExecResult
session.exec_stream(command: str | list[str] | tuple[str, ...], *, shell: bool = False, cwd: str | None = None, env: dict[str, Any] | None = None, timeout_s: float | None = None) -> Iterator[SandboxStreamEvent]
session.close() -> Any
