Skip to main content

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() and check_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)
assert resp.policy_literal() is not None  # Cedar format
assert resp.policy_json() is not None     # JSON format

# 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()}")
        print(f"Policy: {result.policy_literal()}")
        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

  • User namespace and groups are optional; they default to the root namespace if not provided
  • Action namespace is optional; it defaults to the root namespace if not provided
  • Each Request can optionally have an id field 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

treetop_client-0.0.6.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

treetop_client-0.0.6-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file treetop_client-0.0.6.tar.gz.

File metadata

  • Download URL: treetop_client-0.0.6.tar.gz
  • Upload date:
  • Size: 22.6 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

Hashes for treetop_client-0.0.6.tar.gz
Algorithm Hash digest
SHA256 23f13790c65f4785d733184085876aefac4168b865553ce2fc88b77f569b7dc6
MD5 aa6caf1d41ca7aa4257857f40ae55962
BLAKE2b-256 edd89c753c0092239225b3ed92031126e738eda8f0197e1203ab56cb8fbc9387

See more details on using hashes here.

File details

Details for the file treetop_client-0.0.6-py3-none-any.whl.

File metadata

  • Download URL: treetop_client-0.0.6-py3-none-any.whl
  • Upload date:
  • Size: 9.5 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

Hashes for treetop_client-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 05a8f6982841c67fe17a7b956db42ac47b1984473aecf4c1905ffba6d2a933df
MD5 1e632e882c59c239932dc88f917159f8
BLAKE2b-256 d5a854557f30484e485df8791bda333a49fd64405971c41a771ab1e5e8b5e693

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page