Official Python SDK for the Amorce Agent Transaction Protocol (AATP)
Project description
Amorce Python SDK (AATP)
Official Python SDK for the Amorce Agent Transaction Protocol (AATP).
The Amorce SDK allows any Python application, API, or Agent to become a verified node in the Agent Economy. It provides the cryptographic primitives (Ed25519) and the transport layer required to transact securely with AI Agents (OpenAI, Google Gemini, Apple Intelligence).
🚀 Features
-
Zero-Trust Security: Every request is cryptographically signed (Ed25519) locally.
-
Agent Identity: Manage your agent's identity and keys securely without complexity.
-
Priority Lane: Mark critical messages (
high,critical) to bypass network congestion. -
HTTP/2 Support (v0.2.0): Optional
AsyncAmorceClientwith multiplexed connections for high-throughput agents. -
Exponential Backoff (v0.2.0): Advanced retry logic with jitter using tenacity (handles 503, 429, 504).
-
Resilience: Automatic retry logic for unstable networks with exponential backoff.
-
Developer Experience: Simplified
IdentityManagerwith auto-derived Agent IDs. -
Robust Error Handling: Specific exceptions (
AmorceNetworkError,AmorceAPIError) for reliable production code.
📦 Installation
Prerequisites
-
Python 3.10+
-
OS: Linux, macOS, or Windows.
- Linux users: Ensure you have
build-essentialandlibssl-devinstalled for the cryptography dependency.
- Linux users: Ensure you have
Install via PyPI
pip install amorce-sdk
⚡ Quick Start
1. Identity Setup
An Agent is defined by its Private Key. Never share this key.
Option A: Quick Start (Ephemeral / Testing)
Generate a new identity in memory instantly. Perfect for QA scripts or temporary bots.
from amorce import IdentityManager
# Generates a fresh Ed25519 keypair in memory (Ephemeral)
identity = IdentityManager.generate_ephemeral()
# The Agent ID is automatically derived from the Public Key (SHA-256)
print(f"Agent ID: {identity.agent_id}")
print(f"Public Key: {identity.public_key_pem}")
Option B: Production (Secure Storage)
Load your identity from a secure source or environment variable.
import os
from amorce import IdentityManager, LocalFileProvider
# Load from a local PEM file
identity = IdentityManager(LocalFileProvider("agent_key.pem"))
# OR (Recommended) Load private key content from Environment Variable
# identity = IdentityManager.from_env("AMORCE_PRIVATE_KEY")
2. Sending a Transaction (Full Example)
Use the AmorceClient to discover services and execute transactions.
import os
from amorce import AmorceClient, PriorityLevel
# Configuration (Use Env Vars in Prod!)
DIRECTORY_URL = os.getenv("AMORCE_DIRECTORY_URL", "[https://directory.amorce.io](https://directory.amorce.io)")
ORCHESTRATOR_URL = os.getenv("AMORCE_ORCHESTRATOR_URL", "[https://api.amorce.io](https://api.amorce.io)")
# 1. Initialize the client
# Note: 'agent_id' is automatically derived from the identity object.
client = AmorceClient(
identity=identity,
directory_url=DIRECTORY_URL,
orchestrator_url=ORCHESTRATOR_URL
)
# 2. Define the payload (The "Letter" inside the Envelope)
payload = {
"intent": "book_reservation",
"params": {"date": "2025-10-12", "guests": 2}
}
# 3. Execute with PRIORITY
# Options: PriorityLevel.NORMAL, .HIGH, .CRITICAL
print(f"Sending transaction from {identity.agent_id}...")
try:
response = client.transact(
service_contract={"service_id": "srv_restaurant_01"},
payload=payload,
priority=PriorityLevel.HIGH
)
if response.get("status") == "success":
print(f"✅ Success! Tx ID: {response.get('transaction_id')}")
print(f"Data: {response.get('data')}")
else:
print(f"⚠️ Server Error: {response}")
except AmorceNetworkError as e:
print(f"❌ Network Error (Retryable): {e}")
except AmorceAPIError as e:
print(f"❌ API Error {e.status_code}: {e.response_body}")
except Exception as e:
print(f"❌ Unexpected Error: {e}")
⚡ Async Quick Start (High-Throughput Agents)
NEW in v0.2.0: For AI agents handling concurrent transactions, use AsyncAmorceClient with HTTP/2:
import asyncio
from amorce import AsyncAmorceClient, IdentityManager, PriorityLevel
async def main():
identity = IdentityManager.generate_ephemeral()
# Use as AsyncContextManager for proper resource cleanup
async with AsyncAmorceClient(
identity=identity,
directory_url="https://directory.amorce.io",
orchestrator_url="https://api.amorce.io"
) as client:
payload = {
"intent": "book_reservation",
"params": {"date": "2025-12-15", "guests": 2}
}
response = await client.transact(
service_contract={"service_id": "srv_restaurant_01"},
payload=payload,
priority=PriorityLevel.HIGH
)
if response.is_success:
print(f"✅ Transaction: {response.transaction_id}")
print(f"Data: {response.result.data}")
asyncio.run(main())
Why Async?
- HTTP/2 Multiplexing: Handle 100s of concurrent transactions over a single connection
- Exponential Backoff: Advanced retry logic with jitter prevents thundering herd
- Non-Blocking: Perfect for AI agents that need to transact at high throughput
Migrating from Sync to Async
Sync Client (AmorceClient) |
Async Client (AsyncAmorceClient) |
|---|---|
client = AmorceClient(...) |
async with AsyncAmorceClient(...) as client: |
client.transact(...) |
await client.transact(...) |
HTTP/1.1 via requests |
HTTP/2 via httpx |
| Basic retry (urllib3) | Exponential backoff + jitter (tenacity) |
| Blocking I/O | Non-blocking async I/O |
### 3. Error Handling
The SDK provides specific exceptions for robust error handling:
```python
from amorce import AmorceClient, AmorceConfigError, AmorceNetworkError, AmorceAPIError
try:
client.transact(...)
except AmorceConfigError as e:
print(f"Configuration Error: {e}")
except AmorceNetworkError as e:
print(f"Network Error: {e}") # Retry might be possible
except AmorceAPIError as e:
print(f"API Error {e.status_code}: {e.response_body}")
except Exception as e:
print(f"Unexpected Error: {e}")
🛡️ Architecture & Security
The SDK implements the AATP v0.1 standard strictly.
-
Envelope: Data is wrapped in a
AmorceEnvelope. -
Canonicalization: JSON payloads are serialized canonically (RFC 8785) to ensure signature consistency.
-
Signing: The envelope is signed locally using Ed25519.
-
Transport: The envelope is sent via HTTP/2 to the Orchestrator.
-
Verification: The receiver verifies the signature against the Trust Directory before processing.
🔧 Troubleshooting & FAQ
Q: I get a 401 Unauthorized when registering. A: Ensure your signature logic is correct. If you use IdentityManager, the signature is handled automatically. If you are manually constructing payloads, verify you are signing the canonical JSON string encoded in UTF-8.
Q: I get SSL: CERTIFICATE_VERIFY_FAILED. A: This happens if you use a placeholder URL or a self-signed cert in dev. Ensure ORCHESTRATOR_URL points to a valid HTTPS endpoint with a trusted certificate.
Q: How do I get my Agent ID? A: Do not hardcode it. Access it via identity.agent_id. It is the SHA-256 hash of your public key.
🛠️ Development
To contribute to the SDK:
# Clone and install in editable mode
git clone [https://github.com/trebortGolin/amorce_py_sdk.git](https://github.com/trebortGolin/amorce_py_sdk.git)
cd amorce_py_sdk
pip install -e .
# Run Unit Tests
python3 -m unittest discover tests
📄 License
This project is licensed under the MIT License.
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 amorce_sdk-0.2.0.tar.gz.
File metadata
- Download URL: amorce_sdk-0.2.0.tar.gz
- Upload date:
- Size: 23.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e7ecbf7cceec5756dd553e5f8e5b542983756ef08067e583614dde901d0d695
|
|
| MD5 |
4b8854e5cf23ff27793520edd000f0e9
|
|
| BLAKE2b-256 |
f075319a0e0593dec464ece99e8b30a031b6f40325c37138604575c69cfd92c4
|
File details
Details for the file amorce_sdk-0.2.0-py3-none-any.whl.
File metadata
- Download URL: amorce_sdk-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d62051114035681a5639d4a471304ebea37e737aac73cdf4bd27c0a95e8d6fd
|
|
| MD5 |
75d191f96b4ff7ffa50a44294030ca6e
|
|
| BLAKE2b-256 |
9d1318adda4f6c6d351eb7cc7612100f694a473d4ce5aadece6c0fdc7ffaff8e
|