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 correlationpayload(dict, optional): Additional context data
Returns: dict with:
decision: "allow" | "deny" | "escalate"reason: Human-readable explanationpolicy_id: ID of matched policy (if any)latency_ms: Evaluation latencydecision_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 nameaction_types(list): Action types this policy applies toconditions(list): Condition expressionsdecision(str): "allow", "deny", or "escalate"priority(int): Evaluation priority (lower = higher priority)enabled(bool): Whether policy is activedescription(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 key402 Payment Required: Plan limit exceeded429 Too Many Requests: Rate limit exceeded500 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
- Documentation: https://deerdawn.com/docs
- API Reference: https://deerdawn.com/docs/api-reference
- Issues: https://github.com/deerdawn/deerdawn-sdk-python/issues
- Email: support@deerdawn.com
License
MIT
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37e805b1095eca47420964c340092df6ae1f239ef15daf92867f552d516ad133
|
|
| MD5 |
578dad29f38e70a6535b4a1e33f167af
|
|
| BLAKE2b-256 |
bf237e4245cb06a0fc8feb181fcd3e4f576b4ebdafcdeb3ebd576e1b50c562a1
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
964ede0142980b622acd8f2a062d361d29b56a501a5983d6b6d5504a5335c655
|
|
| MD5 |
18aa323f180455ce28179915e671422a
|
|
| BLAKE2b-256 |
1b9dcbfaaccff438f9e5deeef5a9eeb177d8586501b0610bb5c95352903cfcda
|