Skip to main content

tinkerfin-sandbox

What it is

tinkerfin-sandbox provides isolated project workspaces, asynchronous files and commands, persistent Sandbox bindings, pause/resume, warm capacity, and cleanup. Its OpenSandbox integration uses SDK 0.1.16 and Server 0.2.3.

The Sandbox runtime image includes Playwright and headless Chromium. Isolated workspaces require the matching Server and execd deployment. Select a runtime image with OpenSandboxConfig(image=...).

Installation

Python 3.11 or newer is required.

pip install tinkerfin-sandbox

For persistent state, install the SQL extra and your database's asynchronous driver:

pip install "tinkerfin-sandbox[sqlalchemy]" aiosqlite

Use asyncpg for PostgreSQL or asyncmy for MySQL. Connection settings and Engine ownership remain with your application.

Quick Start

Deploy the Server and runtime, then choose a Sandbox owner and a project:

import asyncio

from opensandbox.config import ConnectionConfig

from tinkerfin_sandbox import OpenSandboxClient, OpenSandboxManager


async def main() -> None:
    client = OpenSandboxClient(
        connection_config=ConnectionConfig(domain="127.0.0.1:8091"),
    )
    async with OpenSandboxManager(client=client) as sandboxes:
        project = sandboxes.workspace("users/7", workspace_key="project-a")
        async with project.open() as files:
            await files.aupload_files([("/hello.txt", b"hello")])
            result = await files.aexecute("cat hello.txt")
            print(result.output)


asyncio.run(main())

A manager owns its client and State and must outlive workspace access. Leaving project.open() stops that access's processes and network activity while retaining project files. With the default in-memory State, closing the manager destroys its remote Sandboxes. A caller-supplied HTTP transport remains caller-owned.

Keys and Runtime workspaces

The first key selects the physical Sandbox owner, such as a user. workspace_key selects a project inside that Sandbox. Projects with the same owner share one physical instance while keeping separate files, HOME, caches, and dependencies. String owner keys work directly; custom objects require key_resolver:

sandboxes = OpenSandboxManager(client=client, key_resolver=lambda user: user.id)

With tinkerfin installed, a Runtime can prepare and release workspace access for each run:

from tinkerfin import TinkerFin

project = sandboxes.workspace("users/7", workspace_key="project-a")
runtime = (
    TinkerFin()
    .with_namespace("projects/project-a")
    .build(
        model=model,
        backend=project,
    )
)

The returned SandboxWorkspace is a lazy declaration. The Runtime prepares and closes isolated access for each run, while the same project retains files across conversations. The Runtime namespace scopes logical persistence; changing it does not select another Sandbox or project. Finishing a run does not destroy the Sandbox or close the manager.

Files and changes

An isolated workspace exposes its project files at file-tool /. Each run has private processes, temporary files, devices, and networking. HOME, caches, and installed dependencies remain available to later runs of that project. Public HTTP and HTTPS use a managed proxy; processes and network activity end with the run.

All remote file and command operations are asynchronous. Use await files.aread_bytes("/report.pdf", max_bytes=10 * 1024 * 1024) for a bounded binary read. Oversized files raise OpenSandboxFileTooLargeError.

For existing files, project.list_directory(), project.get_file_info(path), and project.read_text(path, max_bytes=..., max_lines=...) provide bounded browsing without creating, initializing, or resuming a workspace. Symbolic links are never followed. Missing workspaces raise OpenSandboxWorkspaceNotInitializedError, and binary text reads raise OpenSandboxNotTextError.

Subscribe before reading an existing running project's initial file state:

async with project.watch() as changes:
    print(await project.list_directory("/"))
    async for change in changes:
        print(await project.list_directory("/"))

WorkspaceChange.FILES_CHANGED and ResyncRequired are hints to reread authoritative state; they contain no file contents or operation history and can be combined. Pausing, deleting, or losing the instance ends the watch with a disconnected resync. Enter a new watch after the project becomes available. Watching creates or resumes no resources and requires a compatible runtime collector. See the file guide for transfer limits, permissions, and change coverage.

Cancellation and data lifetime

  • await project.delete() stops that project's runs and deletes its files, HOME, caches, and dependencies while leaving other projects and the Sandbox intact.
  • await sandboxes.pause(key) pauses the owner's entire Sandbox after active work settles. Use resume(key) explicitly; project.open() does not resume it.
  • await sandboxes.destroy(key) destroys the owner's Sandbox and every project in it.

The default remote TTL is two hours. OpenSandboxConfig(ttl=None) keeps newly created instances until explicit destruction. In-memory State destroys remote instances when the manager closes; persistent State retains them. Pause does not stop or extend a finite TTL. Back up files that must survive instance loss.

Recovery preserves existing bindings by default. OpenSandboxRecoveryPolicy(on_failure="recreate") permits loss of all data in the physical Sandbox; files are not copied. Commands, writes, and reset operations are never replayed. Cancellation retains cleanup ownership. If a manager-close waiter is cancelled, call aclose() again to await the continuing close operation before releasing borrowed resources.

Raw command Sandboxes are available through get(key) and related manager methods. They cannot share an owner already used for isolated workspaces. Their workspace_root maps file paths but does not restrict shell commands. See the lifecycle guide for raw commands, recovery, pause/resume, diagnostics, and observers. Applications control access to trusted diagnostic output.

Persistent state

For SQLite, MySQL, or PostgreSQL, create SQLAlchemyOpenSandboxState(engine=engine, namespace="production") and pass it as state to OpenSandboxManager. The manager owns State; the host owns the AsyncEngine and disposes it after the manager closes. State saves bindings and coordination, not project file bytes.

State namespace separates deployments sharing a database. Workers in one deployment must agree on warm capacity. Warm instances serve raw command Sandboxes; isolated workspaces create their own instances. Startup creates or validates the schema and requires DDL permissions when creating it. Configure connection and statement timeouts on the Engine. The persistence guide provides complete SQL setup examples.

Documentation

License

Apache License 2.0

Metadata

Release files for tinkerfin-sandbox 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tinkerfin-sandbox 0.1.1
File Size Uploaded
tinkerfin_sandbox-0.1.1.tar.gz 215.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tinkerfin-sandbox 0.1.1
File Interpreter ABI Platform
tinkerfin_sandbox-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 418.1 kB

Release files / tinkerfin_sandbox-0.1.1.tar.gz

Download URL tinkerfin_sandbox-0.1.1.tar.gz
Size 215.0 kB
Tags Source
SHA-256 checksum
How to use checksums
116db4304458fdc1a757482f655603159d9465092c720f62c9c07cc4e8c3508b
BLAKE2b-256 checksum
How to use checksums
cbd416cc56de4702085448b1f95ac7ace1e84db8266f8c3b5e2153fe919f2bec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / tinkerfin_sandbox-0.1.1-py3-none-any.whl

Download URL tinkerfin_sandbox-0.1.1-py3-none-any.whl
Size 203.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2f122c171102f13ea395cc578b630be780cc8811c8de88ed044352245973eda4
BLAKE2b-256 checksum
How to use checksums
f098567b041146aae049dc0ad30127a4477a078f55aaefb0dc0c4a2bd27ffd99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page