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. Useresume(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
- Sandbox guide
- Files and commands
- Lifecycle and recovery
- Persistent state and extensions
- API reference
License
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)
| File | Size | Uploaded | |
|---|---|---|---|
| tinkerfin_sandbox-0.1.1.tar.gz | 215.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|