- Run: The complete execution, including the initial function Call and any Calls it launches.
- Call: One function invocation submitted through the Python API with its arguments and execution settings. Every Run starts with a root Call.
- Attempt: One try at executing a Call. Retrying a Call creates another Attempt for that Call within the same Run.
Running a function
To create a Run in OuterProduct, useclient.run() to create its first Call. This Call becomes the root of the new Run. Any Calls created by the function as it executes become child Calls within the same Run. The function must take an OuterProduct client as its first parameter. When calling client.run(), specify the function, its arguments, and its compute requirements.
client argument automatically. The remaining positional arguments can be supplied through the args parameter, and named arguments can be supplied through kwargs.
client.run() returns a handle to the Run after submission, without waiting for execution to complete. Calling .wait() blocks until the Run completes and returns the function’s result.
Run lifecycle
run.status is a run status value stored in the handle. It is normally RUNNING, CANCELLING, COMPLETED, FAILED, or CANCELLED. Call run.refresh() to fetch the latest state. It returns a new handle, so assign the result if you need its updated status.
client.list_runs() lists Runs available to you. Save run.id if you want to retrieve a particular Run later with client.get_run().
run.wait(timeout=30) waits up to 30 seconds for the result. If the Run has not finished by then, wait() raises TimeoutError and stops waiting. The Run keeps running on OuterProduct. Omit timeout to wait indefinitely, or set timeout=0 to check once. If the Run fails or is cancelled, wait() raises op.RunFailed.
run.cancel() requests cancellation and returns an updated handle. The status can be CANCELLING while execution stops. You can also cancel a Run by ID with client.cancel_run(run_id) and through the OuterProduct UI via the cancel button.
Inspecting Calls and Attempts
await run.calls() returns every Call in the Run, including the root Call and nested Calls. await call.children() returns only the Calls directly launched by that Call. Each Call has a status, an error message when available, and an attempt_count.
await call.attempts() returns its Attempts. Each Attempt has a number, status, and error message when available:
await call.latest_attempt() to fetch only the newest Attempt; it returns None if the Call has no Attempts. To retrieve a saved resource by its canonical name, use await client.get_call(name) or await client.get_attempt(name). The client also provides list_calls(run) and list_attempts(call). These inspection methods are async only; see Async usage.
Arguments and results
When creating a Call, passclient.run() the function and its arguments, along with the settings that control its execution.
OuterProduct uploads and mounts the function’s Python file, or its entire top-level package when it belongs to one, then imports the function by name. Submitted functions should be defined at the top level of a Python file. Nested functions and lambdas are not supported. Because each Attempt imports the file, code that submits Calls goes under if __name__ == "__main__": (client.run() raises RuntimeError if the import calls it). Other local files can be included through the Image’s add_local_file() and add_local_dir() methods. Third-party dependencies should be installed in the Image.
Arguments and return values are serialized using cloudpickle and can be any Python objects it supports. Return values are reconstructed as Python objects when .wait() is called. Any libraries needed for this should also be installed in the calling program.
For example, a parent Call receiving a PyTorch object should have PyTorch installed in its Image. A local script receiving that same object should have PyTorch installed locally.
Large arrays, datasets, model weights, and other large inputs or outputs are often better stored in a Volume and managed through volume mounts (or an object store more generally).
client.run() controls one part of the execution:
- Function (
fn): The Python function to execute. It may be synchronous or asynchronous and must accept an OuterProduct client as its first argument. - Arguments (
argsandkwargs): The values passed to the function after its client argument. Arguments must be serializable. - Image (
image): The container environment in which the function runs. The image defines the operating system, Python runtime, and installed dependencies (see Images). - Hardware (
cpu,memory_bytes,gpu, andgpu_type): The compute resources assigned to the function. You can choose the number of CPUs, available memory, GPU count, and GPU type (see Hardware). - Environment variables (
env_vars): Configuration injected into the container. Values can be plain strings or securely stored OuterProduct secrets (see Environment variables). - Volumes (
volumes): Persistent storage mounted inside the container. Each entry maps a container path, such as/data, to an OuterProduct Volume (see Volumes). - Retry strategy (
retry_strategy): Controls how OuterProduct responds when an attempt fails. By default, the Python SDK allows a Call to be attempted up to three times; passRetryStrategy(max_attempts=1)to disable retries (see Retries and durability). - Timeout (
timeout): How many seconds each Attempt may run, up to 24 hours, the default. Calls that mount volumes should set it to an hour or less (see Volumes). - Name (
name): Optional display label for the Run, or for a child Call whenclient.run()is called inside a Run. If omitted, the label defaults to the name of the function you pass toclient.run().
We recommend that you or your agent name Runs with the
name argument to make them easier to identify and track in the OuterProduct UI. The name argument only changes the label shown in the UI and has no impact on the Run’s or child Call’s resource identifier.