Python client library for the Treetop policy server
Project description
TreeTop Client
Dataclass-based HTTPX client for the Treetop REST API. Python ≥ 3.12, zero runtime deps beyond HTTPX.
Features
- Unified Batch Authorization Endpoint: Process multiple authorization requests in a single API call
- Detail Levels: Control response verbosity (brief vs. detailed with policy information)
- Backward Compatible: Existing code using
check()andcheck_detailed()continues to work seamlessly - Full Async Support: Async/await support for all API methods
- Type Safe: Fully type-hinted dataclasses for requests and responses
- Version Tracking: Access policy version information (hash and loaded_at timestamp)
Basic Usage (Single Request)
from treetop_client.client import TreeTopClient
from treetop_client.models import (
Action,
Decision,
Request,
Resource,
User,
ResourceAttribute,
ResourceAttributeType,
)
client = TreeTopClient(base_url=f"http://localhost:{PORT}")
attrs = {}
attrs["ip"] = ResourceAttribute.new("10.0.0.1", ResourceAttributeType.IP)
attrs["name"] = ResourceAttribute.new("myhost.example.com", ResourceAttributeType.STRING)
req = Request(
principal=User.new("myuser", "mynamespace", ["mygroup"]),
action=Action.new("myaction", ["mynamespace"]),
resource=Resource.new("Host", id="myhost", attrs=attrs)
)
# Use the check method (wraps batch API internally)
resp = client.check(req)
# Use is_allowed() / is_denied() methods
assert resp.is_allowed()
# Or compare with the Decision enum
assert resp.decision == Decision.ALLOW
Batch Authorization
Send multiple authorization requests in a single API call for better performance:
from treetop_client.client import TreeTopClient
from treetop_client.models import (
Action,
Request,
Resource,
User,
ResourceAttribute,
ResourceAttributeType,
)
client = TreeTopClient(base_url=f"http://localhost:{PORT}")
# Create multiple requests
requests = []
for i in range(3):
attrs = {"ip": ResourceAttribute.new(f"10.0.0.{i}", ResourceAttributeType.IP)}
req = Request(
id=f"request-{i}", # Optional client-provided correlation ID
principal=User.new(f"user{i}", "mynamespace"),
action=Action.new("view", ["mynamespace"]),
resource=Resource.new("Host", id=f"host{i}", attrs=attrs)
)
requests.append(req)
# Process all requests in one call (brief detail level)
response = client.authorize(requests)
# Access results
print(f"Successful: {response.successful}, Failed: {response.failed}")
for result in response:
print(f"Request {result.id}: {result.get_decision()}")
# Look up specific result by ID
result = response.get_by_id("request-0")
if result and result.is_allowed():
print("Request 0 was allowed!")
Detailed Responses (With Policy Information)
Retrieve matching policy information in your responses:
from treetop_client.client import TreeTopClient
from treetop_client.models import (
Action,
Decision,
Request,
Resource,
User,
ResourceAttribute,
ResourceAttributeType,
)
client = TreeTopClient(base_url=f"http://localhost:{PORT}")
attrs = {}
attrs["ip"] = ResourceAttribute.new("10.0.0.1", ResourceAttributeType.IP)
attrs["name"] = ResourceAttribute.new("myhost.example.com", ResourceAttributeType.STRING)
req = Request(
principal=User.new("myuser", "mynamespace", ["mygroup"]),
action=Action.new("myaction", ["mynamespace"]),
resource=Resource.new("Host", id="myhost", attrs=attrs)
)
# Get detailed response with policy information
resp = client.check_detailed(req)
assert resp.is_allowed()
assert resp.decision == Decision.ALLOW
# Access policy information (if allowed)
# The server returns all matching policies as PermitPolicy objects
policies = list(resp) # or resp.policies
if policies:
print(f"First matching policy: {policies[0].literal}")
print(f"Total matching policies: {len(policies)}")
print(f"Annotation IDs: {[p.annotation_id for p in policies if p.annotation_id]}")
print(f"Cedar IDs: {[p.cedar_id for p in policies if p.cedar_id]}")
# Access version information
hash = resp.version_hash() # SHA-256 hash or None
loaded_at = resp.version_loaded_at() # datetime or None
Batch Detailed Responses
Combine batch processing with detailed responses:
# Create multiple requests
requests = [req1, req2, req3]
# Get batch response with detailed policy information
response = client.authorize_detailed(requests)
for result in response:
if result.is_success() and result.is_allowed():
print(f"Decision: {result.get_decision()}")
# Access all matching policies for this result
policies = result.policies
if policies:
print(f"First matching policy: {policies[0].literal}")
print(f"Total matching policies: {len(policies)}")
print(f"Version hash: {result.version_hash()}")
Async API
All methods have async versions:
# Single request (async)
resp = await client.acheck(req)
# Batch requests (async)
response = await client.aauthorize(requests)
# Detailed batch requests (async)
response = await client.aauthorize_detailed(requests)
Correlation ID
Track requests across services using correlation IDs:
from treetop_client.client import TreeTopClient
from treetop_client.models import (
Action,
Request,
Resource,
User,
ResourceAttribute,
ResourceAttributeType,
)
client = TreeTopClient(base_url=f"http://localhost:{PORT}")
attrs = {}
attrs["ip"] = ResourceAttribute.new("10.0.0.1", ResourceAttributeType.IP)
attrs["name"] = ResourceAttribute.new("myhost.example.com", ResourceAttributeType.STRING)
req = Request(
principal=User.new("myuser", "mynamespace", ["mygroup"]),
action=Action.new("myaction", ["mynamespace"]),
resource=Resource.new("Host", id="myhost", attrs=attrs)
)
# Pass correlation ID for tracing
resp = client.check(req, correlation_id="my-correlation-id")
response = client.authorize([req1, req2], correlation_id="batch-trace-id")
Notes
Usernamespace and groups are optional; they default to the root namespace if not providedActionnamespace is optional; it defaults to the root namespace if not provided- Each
Requestcan optionally have anidfield for client-provided correlation IDs in batch operations
Development
This project uses uv for dependency management.
# Install dependencies (including dev dependencies)
uv sync --extra dev
# Run tests
uv run pytest
# Run integration tests (requires Docker & Docker Compose)
uv run pytest -m integration
# Add a new dependency
uv add package-name
# Add a dev dependency
uv add --dev package-name
Project details
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 treetop_client-0.0.7.tar.gz.
File metadata
- Download URL: treetop_client-0.0.7.tar.gz
- Upload date:
- Size: 28.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01b0d8dde4f2830ec9556d3373b01a4c09f1048145deb9781c00d8d3515df38f
|
|
| MD5 |
758971436fc0f76e54abf4ef6e081c61
|
|
| BLAKE2b-256 |
0b0044a4a3f8957c9a490fc4033226f49ae8c6cf0e072d43a53985683b335eb5
|
File details
Details for the file treetop_client-0.0.7-py3-none-any.whl.
File metadata
- Download URL: treetop_client-0.0.7-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c158a8563a8438e4dc2a5e79965be572aa4c350b8a12e513691b94bae017ada
|
|
| MD5 |
2a55de7e6c14cb139590ec40624aaa6f
|
|
| BLAKE2b-256 |
600cea9f569072ff9fcad1025fffa4876b6cc2c8eecacec838e7d7acce724ed3
|