Skip to main content

Plainrouter Python SDK and CLI

Generated from Plainrouter's signed OpenAPI contract. The package is in 0.x and its API may change between minor releases. No support guarantees are made yet.

Official project: plainrouter.com · documentation · source

Report Python SDK issues in the Plainrouter SDK issue tracker.

Install

python -m pip install plainrouter

Python 3.11 or newer is required.

For command-line use, install the same package in an isolated environment:

pipx install plainrouter
plainrouter --help

You can also run the CLI from an active Python environment with python -m plainrouter. The PyPI CLI provides the same command tree, config path, environment variables, JSON output, and safety prompts as @plainrouter/cli.

Use

from plainrouter import create_client, list_events

client = create_client("your-signal-tracker-secret")
response = list_events.sync(client=client)

Async operations are available through each operation module:

from plainrouter import create_client, get_event

client = create_client("your-signal-tracker-secret")
response = await get_event.asyncio(event="event-id", client=client)

The default API base is https://plainrouter.com/api/v1 and the default request timeout is 30 seconds. Pass base_url or an httpx.Timeout to create_client to override either setting. Credentials are supplied by the caller and are never embedded in the SDK.

Copy a failed plan to a fresh draft using a plan-writer bearer token:

import os
from plainrouter import create_client, launch_plans_copy

client = create_client(os.environ["PLAINROUTER_TOKEN"])
response = launch_plans_copy.sync_detailed(1, "failed-plan-id", client=client)

The same operation provides asyncio and asyncio_detailed entry points. The public plainrouter.launch_plans_copy.PlanCopyResponse type alias describes the parsed result union, including ProposalUnavailable and WorkspaceLockTimeout. The detailed entry points return Response[PlanCopyResponse]; sync and asyncio return PlanCopyResponse | None.

Retryable proposal errors

Pass the detailed response or raw HTTPX response to the helper, including for async calls and endpoints with no documented 503. It recognizes only 503 error envelopes with a string message and either workspace_lock_timeout or proposal_not_recorded; other bodies return False.

import json
from plainrouter import is_retryable_proposal_error

retryable = is_retryable_proposal_error(response.status_code, response)
error_code = json.loads(response.content)["error"]["code"] if retryable else None
retry_after = response.headers.get("Retry-After") if retryable else None

This example also distinguishes lock timeout (error_code == "workspace_lock_timeout") without relying on response.parsed. If generated parsing raises before returning a detailed response, capture the raw response with an HTTPX response hook and call response.read() there; in an async hook, await response.aread(). Run the same example on that captured response. Use the public copy facade rather than calling generated copy directly.

No automatic retry is added. Honor Retry-After when present (delta seconds or an HTTP date) when scheduling a retry.

Licensed under Apache-2.0.

Use create_client() or the hand-written plainrouter.AuthenticatedClient / plainrouter.Client for JSON negotiation and redirect protection. Headers default to Accept: application/json; override with client.with_headers({"Accept": "..."}) or constructor headers. A 3xx raises httpx.HTTPStatusError before parsing or following, even with follow_redirects=True; inspect error.response.status_code and error.response.headers["Location"]. The separate generated namespace provides raw clients without this policy.

Header names merge case-insensitively, including repeated with_headers calls and clients derived after first use. In-place updates to a live client also merge names case-insensitively: if a dict names Accept or Authorization in multiple letter cases, the last spelling in caller order wins and sends exactly one line. On a token client, the client with_headers returns always sends the SDK's own token as Authorization; the live client and an injected client send the caller's last spelling.

Injected HTTPX clients receive JSON Accept when it is absent or exactly */* (HTTPX's automatic default is indistinguishable from an explicit wildcard); any other configured value is retained. To request an explicit wildcard after injection, use client.with_headers({"Accept": "*/*"}).

set_httpx_client and set_async_httpx_client set Accept on the HTTPX client object you pass in, so other code sharing that object sees the change.

Metadata

Release files for plainrouter 0.10.0

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

Source distribution (sdist)

Source distribution for plainrouter 0.10.0
File Size Uploaded
plainrouter-0.10.0.tar.gz 227.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plainrouter 0.10.0
File Interpreter ABI Platform
plainrouter-0.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 950.0 kB

Release files / plainrouter-0.10.0.tar.gz

Download URL plainrouter-0.10.0.tar.gz
Size 227.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0c1071826da24aef3b13809bf11a9294853c2870db7e341269dff682b8937790
BLAKE2b-256 checksum
How to use checksums
d6b8b6643aeb0a894eed2a3ebca2993dbcd8d8fb99f7089b4cfa1dd0dbc08db5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / plainrouter-0.10.0-py3-none-any.whl

Download URL plainrouter-0.10.0-py3-none-any.whl
Size 722.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9553fc9c05cfa49e62074a948b2d2919b54a499cdfea12640d1ffce2e2f56313
BLAKE2b-256 checksum
How to use checksums
dea74a8f9f4af4e933ab1e175384761c3b961e8560dbb30ad0a8c7d427dbae52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.10.0 This release

2 release files

0.9.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.3.1

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