Python SDK for the Plato API
Project description
Plato Python SDK
Python SDK for the Plato platform. Uses Harbor for agent execution.
Installation
pip install plato-sdk-v2
# For agent functionality (requires Python 3.12+)
pip install 'plato-sdk-v2[agents]'
Or with uv:
uv add plato-sdk-v2
uv add 'plato-sdk-v2[agents]' # for agent support
Configuration
Create a .env file in your project root:
PLATO_API_KEY=your-api-key
PLATO_BASE_URL=https://plato.so # optional, defaults to https://plato.so
Or set environment variables directly:
export PLATO_API_KEY=your-api-key
Agents
The SDK uses Harbor's agent framework. All agents are BaseInstalledAgent subclasses that run in containers.
Available Agents
Harbor built-in agents (code agents):
| Agent | Description |
|---|---|
claude-code |
Claude Code CLI |
openhands |
OpenHands/All Hands AI |
codex |
OpenAI Codex CLI |
aider |
Aider pair programming |
gemini-cli |
Google Gemini CLI |
goose |
Block Goose |
swe-agent |
SWE-agent |
mini-swe-agent |
Mini SWE-agent |
cline-cli |
Cline CLI |
cursor-cli |
Cursor CLI |
opencode |
OpenCode |
qwen-coder |
Qwen Coder |
Plato custom agents (browser/automation):
| Agent | Description |
|---|---|
computer-use |
Browser automation (install: pip install plato-agent-computer-use) |
Python Usage
from plato.agents import ClaudeCode, OpenHands, AgentFactory, AgentName
from pathlib import Path
# Option 1: Use AgentFactory
agent = AgentFactory.create_agent_from_name(
AgentName.CLAUDE_CODE,
logs_dir=Path("./logs"),
model_name="anthropic/claude-sonnet-4",
)
# Option 2: Import agent class directly
agent = ClaudeCode(
logs_dir=Path("./logs"),
model_name="anthropic/claude-sonnet-4",
)
# Option 3: Create custom BaseInstalledAgent
from plato.agents import BaseInstalledAgent
CLI Usage
# Run an agent
plato agent run -a claude-code -m anthropic/claude-sonnet-4 -d swe-bench-lite
# List available agents
plato agent list
# Get agent config schema
plato agent schema claude-code
# Publish custom agent to Plato PyPI
plato agent publish ./my-agent
Agent Schemas
Get configuration schemas for any agent:
from plato.agents import get_agent_schema, AGENT_SCHEMAS
# Get schema for specific agent
schema = get_agent_schema("claude-code")
print(schema)
# List all available schemas
print(list(AGENT_SCHEMAS.keys()))
Custom Agents
Create a custom agent by extending BaseInstalledAgent:
from harbor.agents.installed.base import BaseInstalledAgent, ExecInput
from pathlib import Path
class MyAgent(BaseInstalledAgent):
@staticmethod
def name() -> str:
return "my-agent"
@property
def _install_agent_template_path(self) -> Path:
return Path(__file__).parent / "install.sh.j2"
def create_run_agent_commands(self, instruction: str) -> list[ExecInput]:
return [ExecInput(command=f"my-agent --task '{instruction}'")]
Publish to Plato PyPI:
plato agent publish ./my-agent-package
Sessions & Environments
Flow 1: Create Session from Environments
Use this when you want to spin up environments for development, testing, or custom automation.
import asyncio
from plato.v2 import AsyncPlato, Env
async def main():
plato = AsyncPlato()
# Create session with one or more environments
# (heartbeat starts automatically to keep session alive)
session = await plato.sessions.create(
envs=[
Env.simulator("gitea", dataset="blank", alias="gitea"),
Env.simulator("kanboard", alias="kanboard"),
],
timeout=600,
)
# Reset environments to initial state
await session.reset()
# Get public URLs for browser access
public_urls = await session.get_public_url()
for alias, url in public_urls.items():
print(f"{alias}: {url}")
# Get state mutations from all environments
state = await session.get_state()
print(state)
# Cleanup
await session.close()
await plato.close()
asyncio.run(main())
Flow 2: Create Session from Task
Use this when running evaluations against predefined tasks. This flow includes task evaluation at the end.
import asyncio
from plato.v2 import AsyncPlato
async def main():
plato = AsyncPlato()
# Create session from task ID
session = await plato.sessions.create(task=123, timeout=600)
# Reset environments to initial state
await session.reset()
# Get public URLs for browser access
public_urls = await session.get_public_url()
for alias, url in public_urls.items():
print(f"{alias}: {url}")
# Evaluate task completion
evaluation = await session.evaluate()
print(f"Task completed: {evaluation}")
# Cleanup
await session.close()
await plato.close()
asyncio.run(main())
Environment Configuration
Two ways to specify environments:
from plato.v2 import Env
# 1. From simulator (most common)
Env.simulator("gitea") # default tag
Env.simulator("gitea", tag="staging") # specific tag
Env.simulator("gitea", dataset="blank") # specific dataset
Env.simulator("gitea", alias="my-git") # custom alias
# 2. From artifact ID
Env.artifact("artifact-abc123")
Env.artifact("artifact-abc123", alias="my-env")
Per-Environment Operations
Access individual environments within a session:
# Get all environments
for env in session.envs:
print(f"{env.alias}: {env.job_id}")
# Get specific environment by alias
gitea = session.get_env("gitea")
if gitea:
# Execute shell command
result = await gitea.execute("whoami", timeout=30)
print(result)
# Get state for this environment only
state = await gitea.get_state()
# Reset this environment only
await gitea.reset()
Sync Client
A synchronous client is also available:
from plato.v2 import Plato, Env
plato = Plato()
session = plato.sessions.create(
envs=[Env.simulator("gitea", alias="gitea")],
timeout=600,
)
session.reset()
public_urls = session.get_public_url()
state = session.get_state()
session.close()
plato.close()
Architecture
plato/
├── agents/ # Harbor agent re-exports + schemas
├── sims/ # Simulator clients (Spree, Firefly, etc.)
├── world/ # World/environment abstractions
├── v1/ # Legacy SDK + CLI
└── v2/ # New API client
Documentation
- Generating Simulator SDKs - How to create API clients for simulators
- Building Simulators - Internal docs for snapshotting simulators
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file plato_sdk_v2-2.61.5.tar.gz.
File metadata
- Download URL: plato_sdk_v2-2.61.5.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02b02906a87ca27269c5ac0e51b18d361ca5b97d0617b02946fd06eb6c2f9026
|
|
| MD5 |
b64d1d2ef4fb3f7de20fdc9d1450a7a4
|
|
| BLAKE2b-256 |
41f5439a877ce3b0e058562fee49342db3a9ae7b8de120ed054a1e205a6ac27a
|
File details
Details for the file plato_sdk_v2-2.61.5-py3-none-any.whl.
File metadata
- Download URL: plato_sdk_v2-2.61.5-py3-none-any.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb14c67fbc29346e17545e7ecc455ef6fa2eaa925ff7ca745ba054f9f13c4c81
|
|
| MD5 |
d72be16cdb67279d793b2155da5ce0cb
|
|
| BLAKE2b-256 |
eb144f8c6f3f34d4ba46c9bb0566a538a3c3f944aac1c96bac7652debface2f3
|