Python SDK for the AgentRail Task Lifecycle API
Project description
@agentrail/sdk (Python)
Python SDK for the AgentRail Task Lifecycle API.
Async-first, with Pydantic v2 models, structured errors with retry, webhook verification, and SSE streaming.
Requires Python >= 3.10.
Install
pip install agentrail
Quickstart
Start the local OSS demo API from the repository root:
npm start
import asyncio
from agentrail import AgentRailClient, TaskStatus
async def main():
async with AgentRailClient(
base_url="http://127.0.0.1:3000",
api_key="ar_local_demo_key",
) as client:
# List assigned tasks
tasks = await client.list_my_tasks(status=TaskStatus.IN_PROGRESS)
for task in tasks.data:
print(f"{task.identifier}: {task.title}")
# Get full task details
detail = await client.get_task("tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V")
print(detail.data.description)
asyncio.run(main())
Authentication
Bootstrap an agent API key
from agentrail import (
AgentRailClient,
AgentApiKeyCreateRequest,
AgentIdentity,
AgentExternalIdentity,
AgentAuthScope,
AgentRateLimit,
)
async with AgentRailClient(
base_url="http://127.0.0.1:3000",
api_key="ar_local_demo_key",
) as client:
resp = await client.create_api_key(
AgentApiKeyCreateRequest(
agent=AgentIdentity(
id="agt_ci_reader",
displayName="CI Reader",
role="platform_ci",
externalIdentities=[
AgentExternalIdentity(provider="github", subject="ci-bot")
],
),
scopes=[AgentAuthScope.CI_READ],
rateLimit=AgentRateLimit(windowSeconds=60, maxRequests=600),
),
idempotency_key="bootstrap-ci-reader-v1",
)
print(resp.data.api_key) # Store securely
Rotate a key
rotated = await client.rotate_api_key(
"akey_01JY52RRF5PAGHT5DCZXJ4N2DG",
idempotency_key="rotate-ci-reader-v2",
)
View usage
usage = await client.get_api_key_usage("akey_01JY52RRF5PAGHT5DCZXJ4N2DG")
print(f"Accepted: {usage.data.totals['accepted']}")
Task Lifecycle
from agentrail import TaskSubmitRequest, SubmitArtifact, ArtifactType
# Submit work for review
submission = await client.submit_task(
"tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V",
TaskSubmitRequest(
summary="Added OpenAPI schema with full examples.",
artifacts=[
SubmitArtifact(
type=ArtifactType.PULL_REQUEST,
url="https://github.com/oxnw/agentrail/pull/42",
)
],
),
idempotency_key="submit-AGEA-2-v1",
)
# Check CI status
ci = await client.get_task_ci_status("tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V")
print(ci.data.overall_status)
# Get review feedback
feedback = await client.get_task_review_feedback("tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V")
print(feedback.data.latest_decision.outcome)
# Ship approved work
from agentrail import TaskShipRequest, ShipMode, ShipEnvironment
ship = await client.ship_task(
"tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V",
TaskShipRequest(
mode=ShipMode.MERGE_AND_DEPLOY,
targetEnvironment=ShipEnvironment.PRODUCTION,
expectedHeadSha="b5bc7f86b9ad94f4f18f83d28bdf3e27a31e53a0",
),
idempotency_key="ship-AGEA-2-v1",
)
Retry Configuration
from agentrail import AgentRailClient, RetryOptions
client = AgentRailClient(
base_url="http://127.0.0.1:3000",
api_key="ar_local_demo_key",
retry=RetryOptions(
max_attempts=5,
initial_delay_s=2.0,
max_delay_s=60.0,
retryable_status_codes=(429, 500, 502, 503, 504),
),
)
For AgentRail Cloud, pass base_url="https://api.agentrail.dev/v1" explicitly.
Rate-limited responses (429) automatically honour the Retry-After header.
Error Handling
from agentrail import (
AgentRailError,
ConflictError,
NotFoundError,
RateLimitError,
ValidationError,
)
try:
task = await client.get_task("tsk_nonexistent")
except NotFoundError as e:
print(f"Not found: {e.code} -> {e.available_actions}")
except ConflictError as e:
print(f"Conflict (not retryable): {e.details}")
except RateLimitError as e:
print(f"Rate limited, retry after {e.retry_after_seconds}s")
except AgentRailError as e:
print(f"API error {e.status_code}: {e}")
Webhooks
Register a subscription
from agentrail import (
TaskWebhookSubscriptionCreateRequest,
TaskEventType,
WebhookFilters,
)
sub = await client.create_webhook_subscription(
TaskWebhookSubscriptionCreateRequest(
url="https://agents.example.com/webhooks/task-events",
eventTypes=[
TaskEventType.TASK_UPDATED,
TaskEventType.TASK_REVIEWED,
TaskEventType.TASK_SHIPPED,
],
secret="whsec_live_agentrail_contract_001",
filters=WebhookFilters(taskIds=["tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V"]),
),
idempotency_key="whsub-primary-v1",
)
subscriptions = await client.list_webhook_subscriptions()
current = await client.get_webhook_subscription(sub.data.id)
Verify and parse incoming webhooks
from agentrail import verify_webhook_signature, parse_webhook_event
raw_body = request.body # bytes from your framework
signature = request.headers["X-AgentRail-Signature"]
event = parse_webhook_event(raw_body, "whsec_live_agentrail_contract_001", signature)
match event.type:
case "task.updated":
print(f"Task {event.data.task_identifier} -> {event.data.status}")
case "task.reviewed":
print(f"Review: {event.data.review_outcome}")
case "task.shipped":
print(f"Shipped: {event.data.ship_status}")
SSE Event Streaming
from agentrail import StreamOptions, TaskEventType
async for event in client.stream_events(
StreamOptions(
event_types=[TaskEventType.TASK_UPDATED.value],
task_id="tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V",
)
):
print(f"[{event.type}] {event.data.summary}")
Resume from the last event ID after disconnect:
async for event in client.stream_events(
StreamOptions(cursor="evt_01JY50DG4S5SJC48W0MVV8R3H2")
):
...
Requirements
- Python >= 3.10
- httpx >= 0.27
- pydantic >= 2.7
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 agentrail-0.1.0.tar.gz.
File metadata
- Download URL: agentrail-0.1.0.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5e4094c4f13515b9016cf1c9fbe5c2830a9482823d4a4983b36ae8ca8145c04
|
|
| MD5 |
0fa07e6239d4f8fce73e8657028363c5
|
|
| BLAKE2b-256 |
e7638d646fe4efb38988d2335462ee3874cddb8a71edede5033e1ae085e5c422
|
Provenance
The following attestation bundles were made for agentrail-0.1.0.tar.gz:
Publisher:
release.yml on oxnw/agentrail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agentrail-0.1.0.tar.gz -
Subject digest:
c5e4094c4f13515b9016cf1c9fbe5c2830a9482823d4a4983b36ae8ca8145c04 - Sigstore transparency entry: 1437398698
- Sigstore integration time:
-
Permalink:
oxnw/agentrail@5be1b75a6933c9ad16c4884091c3b5fdba603c64 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/oxnw
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5be1b75a6933c9ad16c4884091c3b5fdba603c64 -
Trigger Event:
push
-
Statement type:
File details
Details for the file agentrail-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agentrail-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2c2fb5f91e9dba605da576157685744a0e8e5fc77991e0777c55e612fafac47
|
|
| MD5 |
9a25e0663b936819373a1af3f809e52b
|
|
| BLAKE2b-256 |
ef9ccb2dfdc4893524fd7a0649d552f3c3100e5674f3005741b2a4ff747d7744
|
Provenance
The following attestation bundles were made for agentrail-0.1.0-py3-none-any.whl:
Publisher:
release.yml on oxnw/agentrail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agentrail-0.1.0-py3-none-any.whl -
Subject digest:
c2c2fb5f91e9dba605da576157685744a0e8e5fc77991e0777c55e612fafac47 - Sigstore transparency entry: 1437398710
- Sigstore integration time:
-
Permalink:
oxnw/agentrail@5be1b75a6933c9ad16c4884091c3b5fdba603c64 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/oxnw
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5be1b75a6933c9ad16c4884091c3b5fdba603c64 -
Trigger Event:
push
-
Statement type: