Python SDK
The official Python SDK for Plasmate, with Pydantic models and SOM query helpers.
Installation
pip install plasmate
Requires Python 3.9+, Pydantic 2.0+, and the plasmate binary on your PATH.
Quick Start
from plasmate import Plasmate
with Plasmate() as client:
som = client.fetch_page("https://example.com")
print(som["title"])
print(som["meta"])
Pydantic Models
All SOM types are fully typed Pydantic models, making them easy to validate and serialize.
`Som`
class Som(BaseModel):
som_version: str
url: str
title: str
lang: str
regions: List[SomRegion]
meta: SomMeta
structured_data: Optional[StructuredData] = None
`SomRegion`
class SomRegion(BaseModel):
id: str
role: RegionRole # navigation, main, aside, header, footer, form, dialog, content
label: Optional[str] = None
action: Optional[str] = None
method: Optional[str] = None
elements: List[SomElement]
`SomElement`
class SomElement(BaseModel):
id: str
role: ElementRole # link, button, text_input, textarea, select, checkbox, radio, heading, image, list, table, paragraph, section, separator
text: Optional[str] = None
label: Optional[str] = None
actions: Optional[List[str]] = None
attrs: Optional[ElementAttrs] = None
children: Optional[List[SomElement]] = None
hints: Optional[List[SemanticHint]] = None
`SomMeta`
class SomMeta(BaseModel):
html_bytes: int
som_bytes: int
element_count: int
interactive_count: int
Query Helpers
`find_by_role(som, role)`
Find all regions matching a given role.
from plasmate.query import find_by_role
nav_regions = find_by_role(som, "navigation")
`find_by_id(som, element_id)`
Find a single element by its stable ID.
from plasmate.query import find_by_id
el = find_by_id(som, "login-btn")
if el:
print(el.text)
`find_by_tag(som, tag)`
Find elements matching a tag/role string.
from plasmate.query import find_by_tag
links = find_by_tag(som, "link")
`find_interactive(som)`
Return all interactive elements.
from plasmate.query import find_interactive
interactive = find_interactive(som)
print(f"{len(interactive)} interactive elements")
`get_action_plan(som)`
Return compact action targets with stable ids, deterministic cache_key values, labels, action lists, and availability state.
from plasmate.query import get_action_plan
for target in get_action_plan(som):
if target["enabled"]:
print(target["id"], target["cache_key"], target["actions"], target.get("label"))
`get_action_plan_cache_key(item)`
Return the same deterministic cache key used by get_action_plan() for a compact target.
from plasmate.query import get_action_plan_cache_key
cache_key = get_action_plan_cache_key(target)
`get_action_plan_index(som, enabled_only=False)`
Return compact action targets indexed by replay ids and grouped by role/action. Use this when an agent needs a small action menu instead of the full SOM.
from plasmate.query import get_action_plan_index
index = get_action_plan_index(som, enabled_only=True)
buttons = index["by_role"].get("button", [])
click_targets = index["by_action"].get("click", [])
`find_action_targets_by_role(som, role, enabled_only=False)`
Return compact action targets for one SOM role without scanning the full plan.
from plasmate.query import find_action_targets_by_role
buttons = find_action_targets_by_role(som, "button", enabled_only=True)
`find_action_targets_by_action(som, action, enabled_only=False)`
Return compact action targets exposing one action.
from plasmate.query import find_action_targets_by_action
clicks = find_action_targets_by_action(som, "click", enabled_only=True)
`find_by_text(som, text)`
Find elements whose text content contains the given string (case-insensitive).
from plasmate.query import find_by_text
matches = find_by_text(som, "Sign in")
`flat_elements(som)`
Flatten all elements across all regions into a single list.
from plasmate.query import flat_elements
all_elements = flat_elements(som)
`get_token_estimate(som)`
Estimate the LLM token count for the SOM (heuristic: ~4 characters per token).
from plasmate.query import get_token_estimate
tokens = get_token_estimate(som)
print(f"~{tokens} tokens")
Client API
Synchronous Client
from plasmate import Plasmate
client = Plasmate(
binary="plasmate", # path to plasmate binary (default: "plasmate")
timeout=30, # timeout in seconds (default: 30)
)
# Fetch a page and return SOM
som = client.fetch_page("https://example.com")
# Extract plain text
text = client.extract_text("https://example.com")
# Stateful sessions
session = client.open_page("https://example.com")
session_id = session["session_id"]
result = client.evaluate(session_id, "document.title")
updated = client.click(session_id, "login-btn")
client.close_page(session_id)
client.close()
Supports context manager:
with Plasmate() as client:
som = client.fetch_page("https://example.com")
Async Support
The AsyncPlasmate client provides the same API with async/await.
from plasmate import AsyncPlasmate
async with AsyncPlasmate() as client:
som = await client.fetch_page("https://example.com")
text = await client.extract_text("https://example.com")
session = await client.open_page("https://example.com")
session_id = session["session_id"]
result = await client.evaluate(session_id, "document.title")
updated = await client.click(session_id, "login-btn")
await client.close_page(session_id)
Both clients communicate with the plasmate mcp subprocess over JSON-RPC 2.0 on stdio.