Skip to main content

Official Python SDK for DeerDawn - AI governance and decision control platform

Project description

DeerDawn Python SDK

Official Python client library for DeerDawn - AI governance and decision control platform.

Installation

pip install deerdawn

Quick Start

from deerdawn import Deerdawn

# Initialize client
client = Deerdawn(api_key='dd_prod_xxxxx')  # Get from https://app.deerdawn.com/api-keys

# Evaluate a decision
result = client.evaluate_decision(
    action_type='send_email',
    trace_id='user-123-action-456',
    payload={
        'recipient': 'user@example.com',
        'subject': 'Hello World'
    }
)

if result['decision'] == 'allow':
    print('Action allowed')
    # Proceed with sending email
else:
    print(f"Action blocked: {result['reason']}")

Type Hints

The SDK includes full type hints for Python 3.7+:

from deerdawn import Deerdawn, EvaluateDecisionResponse, Policy
from typing import List

client = Deerdawn(api_key='dd_prod_xxxxx')

# Type-checked decision evaluation
result: EvaluateDecisionResponse = client.evaluate_decision(
    action_type='database_write',
    trace_id='req-789',
    payload={'table': 'users', 'operation': 'delete'}
)

# Type-checked policy list
policies: List[Policy] = client.list_policies()

Configuration

client = Deerdawn(
    api_key='dd_prod_xxxxx',           # Required: Your API key
    base_url='https://api.deerdawn.com',  # Optional: API base URL (default shown)
    timeout=5,                         # Optional: Request timeout in seconds (default: 5)
    max_retries=3,                     # Optional: Max retry attempts (default: 3)
    debug=False                        # Optional: Enable debug logging (default: False)
)

API Reference

evaluate_decision(action_type, trace_id, payload=None)

Evaluate an action against your policies.

Parameters:

  • action_type (str, required): Type of action (e.g., "send_email", "database_write")
  • trace_id (str, required): Unique trace identifier for correlation
  • payload (dict, optional): Additional context data

Returns: dict with:

  • decision: "allow" | "deny" | "escalate"
  • reason: Human-readable explanation
  • policy_id: ID of matched policy (if any)
  • latency_ms: Evaluation latency
  • decision_id: Decision log ID

Example:

result = client.evaluate_decision(
    action_type='refund_payment',
    trace_id='order-12345',
    payload={
        'amount': 99.99,
        'currency': 'USD',
        'reason': 'customer_request'
    }
)

print(f"Decision: {result['decision']}")
print(f"Reason: {result['reason']}")
print(f"Latency: {result['latency_ms']}ms")

list_policies()

Get all policies for your organization.

Returns: List[dict] - List of policy objects

Example:

policies = client.list_policies()

for policy in policies:
    print(f"{policy['name']}: {policy['decision']} (priority: {policy['priority']})")

create_policy(...)

Create a new policy.

Parameters:

  • name (str): Policy name
  • action_types (list): Action types this policy applies to
  • conditions (list): Condition expressions
  • decision (str): "allow", "deny", or "escalate"
  • priority (int): Evaluation priority (lower = higher priority)
  • enabled (bool): Whether policy is active
  • description (str, optional): Policy description

Returns: dict - Created policy

Example:

policy = client.create_policy(
    name='Auto-approve refunds under $100',
    action_types=['refund_payment'],
    conditions=[
        {
            'field': 'payload.amount',
            'operator': 'lt',
            'value': 100
        }
    ],
    decision='allow',
    priority=10,
    enabled=True,
    description='Automatically approve small refunds'
)

delete_policy(policy_id)

Delete a policy.

Parameters:

  • policy_id (str): Policy ID to delete

Example:

client.delete_policy('pol_abc123')

list_decisions(decision=None, trace_id=None)

Get decision logs with optional filters.

Parameters:

  • decision (str, optional): Filter by decision type ("allow", "deny", "escalate")
  • trace_id (str, optional): Filter by trace ID

Returns: List[dict] - List of decision objects

Example:

# Get all denied decisions
denied_decisions = client.list_decisions(decision='deny')

# Get decisions for a specific trace
trace_decisions = client.list_decisions(trace_id='user-123')

get_decision(decision_id)

Get a specific decision by ID.

Parameters:

  • decision_id (str): Decision ID

Returns: dict - Decision object

Example:

decision = client.get_decision('dec_xyz789')
print(decision['payload'])

Error Handling

The SDK raises DeerDawnAPIError for API errors:

from deerdawn import Deerdawn, DeerDawnAPIError

client = Deerdawn(api_key='dd_prod_xxxxx')

try:
    result = client.evaluate_decision(
        action_type='send_email',
        trace_id='test-123'
    )
except DeerDawnAPIError as error:
    print(f"API Error ({error.status}): {error}")
    print(f"Error code: {error.code}")
except Exception as error:
    print(f"Unexpected error: {error}")

Common Error Codes

  • 401 Unauthorized: Invalid API key
  • 402 Payment Required: Plan limit exceeded
  • 429 Too Many Requests: Rate limit exceeded
  • 500 Internal Server Error: Server error (automatically retried)

Retry Logic

The SDK automatically retries failed requests with exponential backoff:

  • Retries on 5xx errors
  • Default: 3 retry attempts
  • Backoff: 1s, 2s, 4s

Configure retry behavior:

client = Deerdawn(
    api_key='dd_prod_xxxxx',
    max_retries=5  # More aggressive retries
)

Debug Mode

Enable debug logging to troubleshoot issues:

client = Deerdawn(
    api_key='dd_prod_xxxxx',
    debug=True
)

# Outputs:
# [DeerDawn] POST https://api.deerdawn.com/api/v1/decisions:evaluate
# [DeerDawn] Request body: {'action_type': 'send_email', ...}
# [DeerDawn] Response status: 200
# [DeerDawn] Response body: {'decision': 'allow', ...}

Context Manager Support

The SDK supports context managers for automatic cleanup:

with Deerdawn(api_key='dd_prod_xxxxx') as client:
    result = client.evaluate_decision(
        action_type='send_email',
        trace_id='test-123'
    )
# Session automatically closed

Examples

AI Agent with DeerDawn Guardrails

from deerdawn import Deerdawn, DeerDawnAPIError
import os

client = Deerdawn(api_key=os.environ['DEERDAWN_API_KEY'])

def execute_agent_action(action_type, params):
    """Execute AI agent action with DeerDawn guardrails"""
    try:
        # Check permission before executing
        decision = client.evaluate_decision(
            action_type=action_type,
            trace_id=f"agent-{int(time.time())}",
            payload=params
        )

        if decision['decision'] == 'deny':
            raise PermissionError(f"Action blocked: {decision['reason']}")

        if decision['decision'] == 'escalate':
            print('Action requires human approval')
            # Queue for manual review
            return {'status': 'pending', 'reason': decision['reason']}

        # Proceed with action
        return perform_action(action_type, params)

    except DeerDawnAPIError as e:
        print(f"Decision check failed: {e}")
        raise

# Use in your agent
execute_agent_action('send_email', {
    'recipient': 'user@example.com',
    'subject': 'AI-generated report'
})

Flask Decorator

from functools import wraps
from flask import request, jsonify
from deerdawn import Deerdawn

client = Deerdawn(api_key=os.environ['DEERDAWN_API_KEY'])

def require_permission(action_type):
    """Decorator to check permissions via DeerDawn"""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            try:
                decision = client.evaluate_decision(
                    action_type=action_type,
                    trace_id=request.headers.get('X-Trace-ID', f"req-{int(time.time())}"),
                    payload={
                        'user': getattr(request, 'user', None),
                        **request.get_json(silent=True) or {}
                    }
                )

                if decision['decision'] != 'allow':
                    return jsonify({
                        'error': 'forbidden',
                        'reason': decision['reason']
                    }), 403

                return f(*args, **kwargs)

            except Exception as e:
                return jsonify({'error': 'decision_check_failed'}), 500

        return decorated_function
    return decorator

# Use on routes
@app.route('/api/refunds', methods=['POST'])
@require_permission('refund_payment')
def process_refund():
    # Process refund
    pass

Django Middleware

from deerdawn import Deerdawn
from django.http import JsonResponse
import os

class DeerDawnMiddleware:
    """Django middleware for DeerDawn decision control"""

    def __init__(self, get_response):
        self.get_response = get_response
        self.client = Deerdawn(api_key=os.environ['DEERDAWN_API_KEY'])

    def __call__(self, request):
        # Check permissions for protected endpoints
        if request.path.startswith('/api/protected/'):
            action_type = f"{request.method.lower()}_{request.path.split('/')[-1]}"

            try:
                decision = self.client.evaluate_decision(
                    action_type=action_type,
                    trace_id=request.META.get('HTTP_X_TRACE_ID', f"req-{int(time.time())}"),
                    payload={
                        'user': getattr(request, 'user', None),
                        'method': request.method,
                        'path': request.path
                    }
                )

                if decision['decision'] != 'allow':
                    return JsonResponse({
                        'error': 'forbidden',
                        'reason': decision['reason']
                    }, status=403)

            except Exception as e:
                return JsonResponse({'error': 'decision_check_failed'}, status=500)

        return self.get_response(request)

Support

License

MIT

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

deerdawn-1.0.1.tar.gz (12.3 kB view details)

Uploaded Source

Built Distribution

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

deerdawn-1.0.1-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file deerdawn-1.0.1.tar.gz.

File metadata

  • Download URL: deerdawn-1.0.1.tar.gz
  • Upload date:
  • Size: 12.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for deerdawn-1.0.1.tar.gz
Algorithm Hash digest
SHA256 37e805b1095eca47420964c340092df6ae1f239ef15daf92867f552d516ad133
MD5 578dad29f38e70a6535b4a1e33f167af
BLAKE2b-256 bf237e4245cb06a0fc8feb181fcd3e4f576b4ebdafcdeb3ebd576e1b50c562a1

See more details on using hashes here.

File details

Details for the file deerdawn-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: deerdawn-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for deerdawn-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 964ede0142980b622acd8f2a062d361d29b56a501a5983d6b6d5504a5335c655
MD5 18aa323f180455ce28179915e671422a
BLAKE2b-256 1b9dcbfaaccff438f9e5deeef5a9eeb177d8586501b0610bb5c95352903cfcda

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