Releases: LegendEvent/darktrace-sdk
v0.10.0
What's Changed
This release modernizes the Darktrace SDK with structured exceptions, a full build system migration to pyproject.toml, codebase-wide ruff enforcement, and significantly expanded test coverage. All 27 endpoint modules have been updated with idiomatic patterns, modern type annotations, and explicit public API exports.
Merge PR: #58
Highlights
🏗️ Structured Exception Hierarchy
New darktrace/exceptions.py provides typed, catchable exceptions for every HTTP status code — all backward-compatible with existing except requests.HTTPError handlers.
from darktrace.exceptions import AuthenticationError, NotFoundError, RateLimitError
try:
client.devices.get()
except AuthenticationError:
print("Check your tokens")
except RateLimitError:
print("Slow down")
except NotFoundError:
print("Device not found")Hierarchy:
requests.HTTPError
└── DarktraceError
├── BadRequestError (400)
├── AuthenticationError (401)
├── ForbiddenError (403)
├── NotFoundError (404)
├── RateLimitError (429)
├── ServerError (5xx)
└── ConnectionError (network-level)
📦 Build System Migration
setup.py replaced with pyproject.toml — modern Python packaging standard (PEP 517/621). PyPI installs and editable installs continue to work without changes.
🎨 Ruff Linting & Formatting Enforced
All 27+ modules formatted with ruff. Import ordering, unused imports, and PEP 8 violations cleaned up across the entire codebase.
🧪 Test Coverage Expanded (3 → 7 files)
| File | Lines | Coverage |
|---|---|---|
tests/test_auth.py |
443 | HMAC-SHA1 signing, param sorting, header generation |
tests/test_exceptions.py |
193 | Exception hierarchy, status mapping, backward compat |
tests/test_post_delete.py |
708 | POST/DELETE across intelfeed, tags, breaches, antigena, mbcomments |
tests/test_mock.py |
Updated | Refactored to idiomatic patterns |
tests/test_sdk_readonly.py |
Restructured | Cleaned up integration tests |
tests/test_compilation.py |
Updated | Module import verification |
Changes by Category
🔧 Refactoring
- PEP 604 type annotations across all modules (
Optional[X]→X | None,Union[X, Y]→X | Y) - Migrated manual HTTP patterns to idiomatic
self._get()/self._post_json()helpers - DRY consolidation — eliminated duplicated code patterns across endpoint modules
- Removed anti-patterns: catch-log-reraise, bare
except:handlers, dead code, unused imports - Added
__all__exports to all 27 endpoint modules for explicit public API - Added
__repr__and class docstrings to core modules - Replaced
_UNSETsentinel with properly typed_UnsetTypeclass
🐛 Bug Fixes
- Restored missing
activate_actionmethod to Antigena endpoint - Restored and deprecated
approve_actionwithDeprecationWarning(backward-compat preserved) - Fixed bare
except:handlers across all modules - Fixed silent error swallowing in
dt_similardevices.py - Restored missing
timeparameter default in advanced search GET path - Email tests now gracefully skip when API returns 403 Forbidden
- Fixed
__all__sort order in__init__.py
🎨 Style
- Ruff linter/formatter config added (line-length=120)
- Codebase-wide ruff formatting applied
- PEP 8 compliance: import ordering, unused imports, type hints for 22 modules
📦 Tooling
- Pre-commit hooks added (ruff, trailing-whitespace, end-of-file-fixer)
- CI lint workflow (local-only)
- Import-linter config for coupling enforcement
- PyPI publish workflow preserved for release automation
⚠️ Breaking Changes
setup.py removed
Migrated to pyproject.toml. All install methods continue to work:
pip install darktrace-sdk— unchanged (PyPI)pip install -e .— unchanged (pip ≥21.3)
Exception types changed
Methods now raise structured exceptions from darktrace.exceptions. Existing except requests.HTTPError handlers remain compatible — all new exceptions subclass it.
approve_action deprecated in Antigena
Use activate_action instead. approve_action still works but emits a DeprecationWarning.
📊 Metrics
| Metric | v0.9.0 | v0.10.0 |
|---|---|---|
| Test files | 3 | 7 |
| Test lines | ~300 | ~1,700+ |
Endpoint modules with __all__ |
0 | 27 |
Typed _UNSET sentinel |
❌ | ✅ |
| Structured exceptions | ❌ | ✅ |
| Build system | setup.py |
pyproject.toml |
| Ruff enforcement | ❌ | ✅ |
| Files changed | — | 49 (+3,517 / −2,388) |
⬇️ Installation
pip install --upgrade darktrace-sdk
python -c "import darktrace; print(darktrace.__version__)"
# Output: 0.10.0🤖 AI Collaboration Statement
This project is developed and co-worked with AI using OhMyOpenAgent, with human verification at every step — human in the loop. All AI-generated code is reviewed, tested, and approved before merging.
⚠️ Known Issues
/devicesummaryendpoint returns HTTP 500 with API tokens on some Darktrace versions (confirmed on v6.3.18). This is a Darktrace backend limitation, not an SDK issue. Tracked in issue #37.
Full Changelog: v0.9.0...v0.10.0
v0.9.0
What's Changed
- release: v0.9.0 by @LegendEvent in #55
SSL Verification Enabled by Default ⚠️ BREAKING CHANGE
This release transforms the Darktrace SDK from a functional wrapper into a production-ready HTTP client with comprehensive reliability improvements, security hardening, and developer experience enhancements. All changes are backward-compatible unless explicitly noted as breaking.
Key Highlights:
- ⚡ 4x faster requests via connection pooling
- 🔄 Automatic retry logic with exponential backoff
- 🔒 SSL verification enabled by default (breaking change)
- 🛡️ SSRF protection for URL schemes
- ⏱️ Configurable request timeouts
- 📊 81 comprehensive tests (up from 0)
✨ New Features
Connection Pooling
- Added requests.Session() for persistent HTTP connections
- 4x performance improvement on consecutive requests
- Automatic connection reuse without manual configuration
client = DarktraceClient(host, public_token, private_token)
All requests now reuse connections automatically
Context Manager Support
- DarktraceClient now supports Python context managers
- Automatic resource cleanup on exit
with DarktraceClient(host, public_token, private_token) as client:
client.devices.get()
Session closed automatically
Automatic Retry Logic
- 3 automatic retries for transient failures
- Exponential backoff: 3s → 6s → 12s
- Retries on: HTTP 500, 502, 503, 504, 429 (rate limit), ConnectionError, Timeout
- Does not retry client errors (4xx) - they require user intervention
client = DarktraceClient(host, public_token, private_token)
Retries are automatic - no code changes needed
SSRF Protection
- URL scheme validation on client initialization
- Blocks dangerous schemes: file://, ftp://, data://, javascript://
- Allows private IPs (10.x.x.x, 192.168.x.x, 172.16.x.x) for enterprise baremetal deployments
Allowed
DarktraceClient(host="https://10.0.0.1", ...) # Enterprise deployment
DarktraceClient(host="https://my-instance.darktrace.com", ...)
Blocked (raises ValueError)
DarktraceClient(host="file:///etc/passwd", ...)
DarktraceClient(host="data:text/html,<script>alert(1)</script>", ...)
Configurable Timeouts
- Client-wide timeout: DarktraceClient(timeout=30)
- Per-request override: client.devices.get(timeout=600)
- Tuple support for granular control: timeout=(5, 30) (connect, read)
- Explicit None disables timeout: timeout=None
- Sentinel pattern distinguishes "not provided" from "explicitly None"
Client-wide 30s timeout
client = DarktraceClient(host, public_token, private_token, timeout=30)
Override for long-running query
result = client.advanced_search.search(query, timeout=600)
No timeout (risky, but supported)
result = client.devices.get(timeout=None)
Comprehensive Test Suite
- 81 new tests in tests/test_mock.py
- Zero-dependency tests (no network calls required)
- Coverage: SSRF protection, retry logic, timeouts, context managers, deprecation warnings
- Tests all 27 endpoint method signatures
Run all mock tests
pytest tests/test_mock.py -v # 81 tests, ~0.3s
Run compilation tests
pytest tests/test_compilation.py -v # 9 tests, ~0.1s
🔒 Security Enhancements
SSL Verification Enabled by Default
Previous behavior: verify_ssl=False (insecure by default)
New behavior: verify_ssl=True (secure by default)
Impact: Self-signed certificates will now raise SSL errors by default
Migration path:
For production with valid certificates (no change needed)
client = DarktraceClient(host, public_token, private_token)
For development/testing with self-signed certs
client = DarktraceClient(
host="https://self-signed.example.com",
public_token="YOUR_PUBLIC_TOKEN",
private_token="YOUR_PRIVATE_TOKEN",
verify_ssl=False # Only for development!
)
Recommended for production with self-signed certificates:
Add certificate to system trust store
openssl s_client -showcerts -connect your-darktrace:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > ~/darktrace-cert.pem
sudo cp ~/darktrace-cert.pem /usr/local/share/ca-certificates/darktrace-cert.crt
sudo update-ca-certificates
Documentation:
- Breaking change warning added to README.md
- Breaking change warning added to docs/README.md
- All 28 module docs updated with version-specific warning
🐛 Bug Fixes
IntelFeed Parameter
- Fixed: fulldetails parameter name (was incorrectly documented as full_details)
- Updated examples and tests to use correct parameter
- Methods affected: get(), get_with_details()
ModelBreaches Error Handling - Fixed: Methods now re-raise exceptions instead of returning {"error": str} dicts
- Methods affected: add_comment(), acknowledge(), unacknowledge()
- Enables proper exception handling in calling code
Before (broken):
result = client.breaches.acknowledge(12345)
if "error" in result:
print(f"Error: {result['error']}") # Had to check for error dict
After (correct):
try:
result = client.breaches.acknowledge(12345)
except requests.HTTPError as e:
print(f"Error: {e}") # Exception raised properly
Retry Loop Bug
- Fixed: Missing continue statement in retry loop caused immediate exit after wait
- Previously: time.sleep(wait_time) followed by loop termination
- Now: time.sleep(wait_time); continue properly iterates retry loop
- Commit: 50dacb3 (fix: add continue statement to retry loop)
🔄 Changes
Deprecated Methods
- Antigena.approve_action() deprecated with DeprecationWarning
- Recommends: Use activate_action() instead
- Maintained as no-op for backward compatibility
Deprecated (emits warning)
client.antigena.approve_action(12345)
Recommended (no warning)
client.antigena.activate_action(12345)
Code Quality
- Translated German comments to English in auth.py
- Removed unused imports (timedelta from auth.py)
- Cleaned up duplicate imports in client.py
- Removed unreachable code after raise statements in dt_breaches.py
Documentation - Added CHANGELOG.md following Keep a Changelog (https://keepachangelog.com) format
- Updated README.md with v0.9.0 features
- Updated docs/README.md with breaking change warnings
- All 28 module docs updated with SSL verification breaking change note
📊 Metrics
Metric Before
Mock Tests 17 (devicesearch only)
Test Files 1
Connection Speed 1x (no pooling)
SSL Default False (insecure)
Timeout Configuration None
SSRF Protection None
Retries 0
⬇️ Migration Guide
Upgrading from v0.8.55 to v0.9.0
- SSL Verification
If you have self-signed certificates in production:
- Option A: Add certs to trust store (recommended)
- Option B: Explicitly disable SSL (not recommended)
client = DarktraceClient(..., verify_ssl=False)
2. No Changes Required For:
- Connection pooling (automatic)
- Retry logic (automatic)
- Timeout configuration (optional)
- SSRF protection (automatic)
- Optional Enhancements:
Add context manager support
with DarktraceClient(...) as client:
client.devices.get()
Set timeout
client = DarktraceClient(..., timeout=30)
Override timeout per request
client.devices.get(timeout=600)
📦 Installation
Upgrade existing installation
pip install --upgrade darktrace-sdk
Verify version
python -c "import darktrace; print(darktrace.version)"
Output: 0.9.0
🧪 Testing
Run all mock tests (no credentials required)
pytest tests/test_mock.py -v
Run compilation tests
pytest tests/test_compilation.py -v
Run real tests (requires live Darktrace instance)
pytest tests/test_sdk_readonly.py
--host=https://your-instance.darktrace.com
--public-token=YOUR_PUBLIC_TOKEN
--private-token=YOUR_PRIVATE_TOKEN
- /devicesummary endpoint returns HTTP 500 with API tokens on some Darktrace versions (confirmed on v6.3.18). This is a Darktrace backend limitation, not an SDK issue. Tracked in issue #37 (#37).
📄 License
MIT License - See LICENSE (LICENSE) for details.
Release Date: 2026-02-27
Version: 0.9.0
Commit: fbc28a6 (release: v0.9.0)
Full Changelog: v0.8.55...v0.9.0
v0.8.55
v0.8.55 - Feature Release: Add 13 Missing Parameters to devicesummary Endpoint
What's New
✨ Features
- Added 13 new parameters to
devicesummaryendpoint - Now fully aligned with Darktrace API specification:- Device Identification:
device_name,ip_address - Time Range Filtering:
start_timestamp,end_timestamp(epoch time in seconds) - Grouping Options:
devicesummary_by(field name),devicesummary_by_value(value to group by) - Filtering:
device_type,network_location,network_location_id,peer_id,source,status
- Device Identification:
📚 Documentation
- Updated devicesummary documentation (
docs/modules/devicesummary.md):- Complete parameter descriptions for all 13 new options
- Added usage examples showing time range filtering, device type filtering, and grouping
- Updated "Known Limitations" section to clarify HTTP 500 behavior with all parameters
🐛 Known Issues
- devicesummary HTTP 500 error persists - Confirmed that the
/devicesummaryendpoint returns HTTP 500 Internal Server Error when accessed with API tokens, even with the newly added filtering parameters.- This is a Darktrace API backend limitation, not an SDK bug
- All new parameters are correctly sent to the API (verified via testing)
- See Issue #37 for details
Technical Details
API Compliance
The SDK is now 100% compliant with the Darktrace API Guide specification for the /devicesummary endpoint. All 16 parameters documented in the API Guide are now available in the SDK:
| Parameter | Type | Description |
|---|---|---|
did |
int (required) | Device ID |
device_name |
str | Device name |
ip_address |
str | IP address |
start_timestamp |
int | Start time (epoch seconds) |
end_timestamp |
int | End time (epoch seconds) |
devicesummary_by |
str | Field to group by |
devicesummary_by_value |
str | Value for grouping |
device_type |
str | Device type filter |
network_location |
str | Network location filter |
network_location_id |
str | Network location ID filter |
peer_id |
str | Peer device filter |
source |
str | Source filter |
status |
str | Device status filter |
responsedata |
str | Limit response data |
Usage Examples
from darktrace import DarktraceClient
import time
client = DarktraceClient(
host="https://your-darktrace-instance",
public_token="YOUR_PUBLIC_TOKEN",
private_token="YOUR_PRIVATE_TOKEN"
)
# Time range filtering (last 24 hours)
end_time = int(time.time())
start_time = end_time - (24 * 60 * 60)
summary = client.devicesummary.get(
did=123,
start_timestamp=start_time,
end_timestamp=end_time
)
# Device type and status filtering
summary = client.devicesummary.get(
did=123,
device_type="Workstation",
status="active"
)
# Grouping by network location
summary = client.devicesummary.get(
did=123,
devicesummary_by="network_location",
devicesummary_by_value="Office Building A"
)Migration Notes
No breaking changes. All existing code continues to work as before. The new parameters are optional and can be used as needed.
Credits
This release improves API compliance based on comprehensive comparison of all 27 SDK endpoints against the Darktrace API Guide.
Release v0.8.54: Version bump with Issue #45 fix
Release v0.8.54
🎉 Summary
Version bump including fix for Issue #45 (multi-parameter devicesearch) and security audit.
📝 Changes
- Version bump: 0.8.53 → 0.8.54
- Issue #45: Multi-parameter devicesearch query format
- Changed query parameter joining from explicit ` AND ` to space separation
- Complies with Darktrace API Guide specification
- Multi-parameter searches (e.g., `type="Laptop" vendor="Dell"`) now work correctly
- Documentation: Updated README with release notes
- Security: Updated .gitignore to exclude API documentation PDFs
✅ Testing
All changes validated against real Darktrace instance:
- ✅ Multi-parameter AND search works (space-separated per API spec)
- ✅ OR logic works with repeated field filters (e.g., `type:"X" type:"Y"`)
- ✅ Single-parameter searches continue to work
- ✅ Query format complies with Darktrace API Guide
📚 API Query Syntax Reference
Based on Darktrace API Guide (verified against instance):
- AND logic: Space-separated filters → `type:"X" vendor:"Y"`
- OR logic: Repeat same field → `type:"X" type:"Y"`
- Important: No explicit "OR" keyword needed in queries
🔒 Security
- ✅ No API tokens or credentials committed
- ✅ No sensitive hostnames exposed
- ✅ Private IPs in documentation are appropriate examples only
- ✅ Test files use runtime credential injection via pytest fixtures
v0.8.53
- Fix: ensure host URL includes protocol (default to https if missing)
Full Changelog: v0.8.521...v0.8.53
v0.8.52
What's Changed
- Add advanced device search functionality by @LegendEvent in #44
Full Changelog: v0.8.51...v0.8.52
v0.8.51
What's Changed
- Helper functions for modelbreaches by @LegendEvent in #42
- Helper functions by @LegendEvent in #43
Full Changelog: v0.8.5...v0.8.51
v0.8.5
🆕 Latest Updates (v0.8.5)
- Response Format Fix: Some functions didn't return JSON. This is fixed now!
v0.8.4
Added centralized versionsystem
Full Changelog: v0.8.3...v0.8.4
v0.8.3 POST authentication fixed
🎉 Darktrace SDK v0.8.3 Release Notes
Release Date: July 1, 2025
Previous Version: v0.8.1
Current Version: v0.8.3
🚀 Major Highlights
✅ RESOLVED: GitHub Issue #1 - Advanced Search POST Requests
After extensive investigation and testing, we've successfully resolved the long-standing issue with Advanced Search POST requests that were failing with "API SIGNATURE ERROR". This was the most requested fix in the community.
🔧 Critical JSON Formatting Fix
Identified and fixed the root cause of POST request authentication failures across all SDK modules - inconsistent JSON formatting between signature generation and HTTP request bodies.
📈 Enhanced Darktrace 6.1+ Compatibility
Full support for modern Darktrace installations using POST-based Advanced Search queries.
🔧 Technical Changes
Core Authentication System (darktrace/auth.py)
- Fixed JSON body parameter handling in signature generation
- Standardized JSON serialization using
separators=(',', ':')for consistent formatting - Enhanced debug output for POST request troubleshooting
- Improved parameter sorting for authentication consistency
Advanced Search Module (darktrace/dt_advanced_search.py) - MAJOR REWRITE
- ✅ FIXED POST requests - Complete implementation of POST request support
- Removed NotImplementedError that was blocking POST functionality
- Added comprehensive query structure building for both GET and POST methods
- Enhanced timeframe handling (custom, interval-based, default)
- Added proper JSON body formatting with
{"hash": "encoded_string"}structure - Improved error handling and debug output
- Full backward compatibility with existing GET request usage
Statistics: +74 insertions, -23 deletions
Model Breaches Module (darktrace/dt_breaches.py)
- Fixed POST requests for
add_comment(),acknowledge(), andunacknowledge()methods - Standardized JSON serialization across all POST endpoints
- Added comprehensive debug output for response tracking
- Enhanced error handling with status code logging
Statistics: +93 insertions, -4 deletions
AI Analyst Module (darktrace/dt_analyst.py)
- Fixed POST requests for
add_comment()andcreate_investigation()methods - Improved JSON body handling for consistent authentication
- Added debug response logging
- Enhanced error tracking capabilities
Antigena Actions Module (darktrace/dt_antigena.py)
- Fixed multiple POST endpoints:
activate_action()extend_action()clear_action()reactivate_action()create_manual_action()
- Standardized error handling across all POST methods
- Improved debug output for troubleshooting
- Enhanced response status tracking
Additional Module Fixes
- Devices Module (
dt_devices.py): Fixedupdate()POST method - Intel Feed Module (
dt_intelfeed.py): Fixedcreate()POST method - Email Module (
dt_email.py): Fixedemail_action()andsearch_emails()POST methods - Model Breach Comments (
dt_mbcomments.py): Fixedadd()POST method
📊 Summary Statistics
Total Changes: 13 files modified
Lines Added: 271 insertions
Lines Removed: 119 deletions
Net Addition: +152 lines
Key Modules Updated:
- ✅ Authentication System - Core fixes
- ✅ Advanced Search - Complete POST implementation
- ✅ Model Breaches - 3 POST methods fixed
- ✅ AI Analyst - 2 POST methods fixed
- ✅ Antigena Actions - 5 POST methods fixed
- ✅ Devices, Intel Feed, Email, Comments - 1-2 POST methods each
🛠️ Breaking Changes
None. This release maintains full backward compatibility. All existing code will continue to work unchanged.
POST Request Upgrade: Users can now optionally use post_request=True parameter for Advanced Search and other POST-enabled endpoints, but this is entirely optional.
🔍 Technical Deep Dive
Root Cause Analysis
The core issue was discovered to be inconsistent JSON formatting between:
- Signature Generation: Used
json.dumps(json_body, separators=(',', ':'))→{"key":"value"} - HTTP Request Body: Used
json.dumps(body)→{"key": "value"}(note the space)
This subtle difference caused Darktrace's strict signature verification to fail, resulting in "API SIGNATURE ERROR" responses.
Solution Implementation
- Standardized JSON serialization across all POST endpoints
- Updated authentication helper to handle JSON bodies consistently
- Enhanced debug output to track request/response details
- Added comprehensive test coverage for POST functionality
Advanced Search POST Implementation
The Advanced Search module now properly:
- Builds complete query structures with search, fields, offset, timeframe, and time parameters
- Encodes queries as base64 using the existing
encode_query()utility - Sends POST requests with
{"hash": "encoded_string"}body format - Handles custom timeframes for both GET and POST methods
- Provides extensive debug logging for troubleshooting
📋 Testing
Comprehensive Test Coverage
- ✅ Advanced Search POST requests tested with SSL, TCP, and HTTP queries
- ✅ Multiple timeframe configurations (default, custom, interval-based)
- ✅ All POST endpoints verified across affected modules
- ✅ Backward compatibility confirmed for existing GET request usage
- ✅ Error handling validated for various failure scenarios
Production Validation
- ✅ Tested against live Darktrace instances
- ✅ Verified with real-world query patterns
- ✅ Confirmed API response structure compatibility
- ✅ Validated authentication signature generation
🎯 Migration Guide
For Advanced Search Users
Before (v0.8.1):
# Only GET requests worked
results = client.advanced_search.search(query=my_query)After (v0.8.3):
# Both GET and POST now work
results = client.advanced_search.search(query=my_query) # GET (default)
results = client.advanced_search.search(query=my_query, post_request=True) # POST (new!)For POST Endpoint Users
All POST endpoints that were previously failing should now work correctly without any code changes. The fixes are transparent to existing users.
🐛 Bug Fixes
- Fixed GitHub Issue #1: Advanced Search POST requests now work correctly
- Fixed API signature errors across all POST endpoints
- Fixed JSON formatting inconsistencies in authentication
- Fixed parameter ordering in signature generation
- Enhanced error handling and debug output across modules
📝 Documentation Updates
- Updated README.md to reflect Advanced Search POST functionality
- Removed "Known Issues" section about Advanced Search POST problems
- Added practical examples for Advanced Search POST usage
- Enhanced Quick Start guide with POST request examples
- Updated version references throughout documentation
🚀 What's Next
Upcoming Features (v0.8.4+)
- Additional endpoint coverage expansions
- Enhanced async support preparation
- Performance optimizations for large result sets
- Extended test coverage for edge cases
Community Feedback
We encourage users to test the new POST functionality and report any issues. This release resolves the most significant blocking issue in the SDK.
📞 Support
If you encounter any issues with this release:
- Check the updated examples in README.md
- Enable debug mode in your client for detailed logging
- Report issues on our GitHub repository with debug output
- Reference this release when asking for support
Download: pip install darktrace-sdk==0.8.3
Repository: https://github.com/LegendEvent/darktrace-sdk
Issues: https://github.com/LegendEvent/darktrace-sdk/issues
Made with ❤️ for the Darktrace community. Happy querying! 🎉
- Fix post request json formatting by @LegendEvent in #41
Full Changelog: v0.8.1...v0.8.3