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.0.tar.gz (11.4 kB view details)

Uploaded Source

File details

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

File metadata

  • Download URL: deerdawn-1.0.0.tar.gz
  • Upload date:
  • Size: 11.4 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.0.tar.gz
Algorithm Hash digest
SHA256 9f7a55bcf469bfbaaeb4d934cb306f569ede800a89635b86c2a7c87ee39deff4
MD5 d0e4aa2f852b84dbc727c0bf43914993
BLAKE2b-256 8e600a86104b20307aec8fdb95f32b7c508d67a8575516c1dab307fe704b914f

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