akhu-observer 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. akhu_observer-0.1.0/.gitignore +98 -0
  2. akhu_observer-0.1.0/.hypothesis/constants/1eaa25215ffd5a47 +4 -0
  3. akhu_observer-0.1.0/.hypothesis/constants/3180ff067efd961f +4 -0
  4. akhu_observer-0.1.0/.hypothesis/constants/3298f97fe5667e36 +4 -0
  5. akhu_observer-0.1.0/.hypothesis/constants/5ceef35acaa3f38d +4 -0
  6. akhu_observer-0.1.0/.hypothesis/constants/65c9dd3e0fd396c9 +4 -0
  7. akhu_observer-0.1.0/.hypothesis/constants/6f36de417c1d15ae +4 -0
  8. akhu_observer-0.1.0/.hypothesis/constants/74606fa13a0baad6 +4 -0
  9. akhu_observer-0.1.0/.hypothesis/constants/779404e97dc6f507 +4 -0
  10. akhu_observer-0.1.0/.hypothesis/constants/7d1ea108c17450c4 +4 -0
  11. akhu_observer-0.1.0/.hypothesis/constants/8fb4954bd92d08d0 +4 -0
  12. akhu_observer-0.1.0/.hypothesis/constants/a5b20ca2f96cc2af +4 -0
  13. akhu_observer-0.1.0/.hypothesis/constants/aa0095004c950f7d +4 -0
  14. akhu_observer-0.1.0/.hypothesis/constants/abc7db14c94f020a +4 -0
  15. akhu_observer-0.1.0/.hypothesis/constants/b4a4c92ebf550533 +4 -0
  16. akhu_observer-0.1.0/.hypothesis/constants/b7aef19042d3ed63 +4 -0
  17. akhu_observer-0.1.0/.hypothesis/constants/f110630c7f10f589 +4 -0
  18. akhu_observer-0.1.0/.hypothesis/constants/f1b7597793417f58 +4 -0
  19. akhu_observer-0.1.0/.hypothesis/constants/f28241e0327f5cf8 +4 -0
  20. akhu_observer-0.1.0/.hypothesis/examples/04e6b3400353b141/0941b7ee9952d2ce +1 -0
  21. akhu_observer-0.1.0/.hypothesis/examples/04e6b3400353b141/f076e9e55aca3476 +1 -0
  22. akhu_observer-0.1.0/.hypothesis/examples/0941b7ee9952d2ce/d1270f110bffbe9b +0 -0
  23. akhu_observer-0.1.0/.hypothesis/examples/f076e9e55aca3476/1a51bc85944f6537 +0 -0
  24. akhu_observer-0.1.0/.hypothesis/examples/f076e9e55aca3476/1a7472336018be35 +0 -0
  25. akhu_observer-0.1.0/.hypothesis/examples/f076e9e55aca3476/241c59df2466bc70 +0 -0
  26. akhu_observer-0.1.0/.hypothesis/tmp/tmp4zwtx5ep +0 -0
  27. akhu_observer-0.1.0/.hypothesis/tmp/tmp8s1fvylp +0 -0
  28. akhu_observer-0.1.0/.hypothesis/tmp/tmpc93zydm_ +0 -0
  29. akhu_observer-0.1.0/.hypothesis/tmp/tmpg3l3_2dr +0 -0
  30. akhu_observer-0.1.0/.hypothesis/tmp/tmpghk1mtmd +0 -0
  31. akhu_observer-0.1.0/.hypothesis/tmp/tmphlepqnpl +0 -0
  32. akhu_observer-0.1.0/.hypothesis/tmp/tmpjzr3r6f7 +0 -0
  33. akhu_observer-0.1.0/.hypothesis/tmp/tmply311jmq +0 -0
  34. akhu_observer-0.1.0/.hypothesis/tmp/tmpyi0fhnnw +0 -0
  35. akhu_observer-0.1.0/.hypothesis/tmp/tmpz0tgvayr +0 -0
  36. akhu_observer-0.1.0/.hypothesis/tmp/tmpzvnj39yt +0 -0
  37. akhu_observer-0.1.0/.hypothesis/unicode_data/15.0.0/charmap.json.gz +0 -0
  38. akhu_observer-0.1.0/.hypothesis/unicode_data/15.0.0/codec-utf-8.json.gz +0 -0
  39. akhu_observer-0.1.0/PKG-INFO +108 -0
  40. akhu_observer-0.1.0/README.md +82 -0
  41. akhu_observer-0.1.0/pyproject.toml +76 -0
  42. akhu_observer-0.1.0/src/akhu_observer/__init__.py +46 -0
  43. akhu_observer-0.1.0/src/akhu_observer/_constants.py +91 -0
  44. akhu_observer-0.1.0/src/akhu_observer/_http.py +166 -0
  45. akhu_observer-0.1.0/src/akhu_observer/_redact.py +350 -0
  46. akhu_observer-0.1.0/src/akhu_observer/_retry.py +174 -0
  47. akhu_observer-0.1.0/src/akhu_observer/_types.py +81 -0
  48. akhu_observer-0.1.0/src/akhu_observer/client.py +621 -0
  49. akhu_observer-0.1.0/src/akhu_observer/py.typed +0 -0
  50. akhu_observer-0.1.0/src/akhu_observer/wrappers/__init__.py +6 -0
  51. akhu_observer-0.1.0/src/akhu_observer/wrappers/anthropic.py +246 -0
  52. akhu_observer-0.1.0/src/akhu_observer/wrappers/openai.py +281 -0
  53. akhu_observer-0.1.0/tests/adversarial/__init__.py +0 -0
  54. akhu_observer-0.1.0/tests/adversarial/test_injection.py +510 -0
  55. akhu_observer-0.1.0/tests/conftest.py +165 -0
  56. akhu_observer-0.1.0/tests/invariants/__init__.py +0 -0
  57. akhu_observer-0.1.0/tests/invariants/test_fail_open.py +205 -0
  58. akhu_observer-0.1.0/tests/invariants/test_redaction.py +265 -0
  59. akhu_observer-0.1.0/tests/test_anthropic.py +235 -0
  60. akhu_observer-0.1.0/tests/test_client.py +487 -0
  61. akhu_observer-0.1.0/tests/test_http.py +171 -0
  62. akhu_observer-0.1.0/tests/test_openai.py +295 -0
  63. akhu_observer-0.1.0/tests/test_redact.py +355 -0
  64. akhu_observer-0.1.0/tests/test_retry.py +327 -0
@@ -0,0 +1,98 @@
1
+ node_modules
2
+ dist
3
+ build
4
+ .turbo
5
+ .env
6
+ .env.local
7
+ .env*.local
8
+ *.log
9
+ coverage
10
+ .vscode
11
+ .idea
12
+ .DS_Store
13
+ *.tsbuildinfo
14
+ cdk.out
15
+
16
+ # Runtime data - NO trackear datos de producción
17
+ akhu-data/
18
+ apps/api/akhu-data/
19
+ apps/api/2026/
20
+ apps/api/manifest.ljson
21
+ monitoring/
22
+ apps/api/monitoring/
23
+ apps/api/logs/
24
+
25
+ # Dashboard build artifacts (source is tracked, builds are not)
26
+ apps/dashboard/dist/
27
+ apps/dashboard/dist-*/
28
+ apps/dashboard/node_modules/
29
+ apps/dashboard/.env.production
30
+ apps/dashboard/.env.staging
31
+ apps/dashboard/.env.development
32
+ apps/dashboard/start-production-sim.*
33
+
34
+ # Generated reports (Stryker mutation testing, etc.)
35
+ reports/
36
+ **/reports/mutation/
37
+
38
+ # CDC contract artifacts (auto-generated)
39
+ pacts/
40
+
41
+ # Backup files
42
+ *.backup
43
+ *.bak
44
+ *.old
45
+ *.tmp
46
+
47
+ # NO DOCUMENTATION IN REPO - SOLO LOCAL
48
+ # All markdown and PDF files are excluded
49
+ *.md
50
+ *.pdf
51
+ docs/
52
+
53
+ # Legacy patterns (kept for reference)
54
+ OPUS_ANALYSIS*.md
55
+ SECURITY_*.md
56
+ MEJORAS_*.md
57
+
58
+ # packages/akhu — local tooling and generated data
59
+ packages/akhu/logs/
60
+ packages/akhu/monitoring/
61
+ packages/akhu/scripts/
62
+ packages/akhu/.stryker-tmp/
63
+ packages/akhu/stryker*.config.mjs
64
+ packages/akhu/stryker*.txt
65
+ packages/akhu/mutation-report-*.json
66
+ packages/akhu/mutant-classification.json
67
+ packages/akhu/vitest-*.config.ts
68
+ packages/akhu/analyze-*.js
69
+ packages/akhu/analyze-*.mjs
70
+ packages/akhu/classify-mutants.mjs
71
+ packages/akhu/show-survivors.js
72
+ packages/akhu/get-survivors-detail.js
73
+ packages/akhu/check-orch.js
74
+ packages/akhu/*.bat
75
+ packages/akhu/*.vbs
76
+ nul
77
+ docs/archive/
78
+
79
+ # Development/testing tools - local only
80
+ observation-harness/
81
+ pricing-foundaments/
82
+ scripts/
83
+
84
+ # Build/packaging scripts - local only
85
+ build-images.*
86
+ create-package.*
87
+ analyze-*.js
88
+ test-conversation.sh
89
+ test-axiom*
90
+ axiom-result.txt
91
+ docker-logs.txt
92
+ stress-test-output.txt
93
+
94
+ # Distribution packages (generated, not source)
95
+ dist/
96
+ *.tar.gz
97
+ bash.exe.stackdump
98
+ channels_dump.json
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_retry.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [429, 500, 600, 'T', 'broken pipe', 'connection refused', 'connection reset', 'host unreachable', 'network unreachable', 'socket', 'timed out']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\client.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [200, 300, 400, 409, 429, 500, 1000, '/', 'GET', 'POST', '_adapter', '_buffer', '_buffer_lock', '_buffer_size', '_channel_id', '_channel_name', '_channel_registered', '_description', '_destroyed', '_flush_interval_s', '_flush_lock', '_flush_timer', '_http', '_max_retries', '_on_error', '_on_flush', '_registering_lock', '_timeout_s', '_url', 'akhu-flush', 'body', 'channelId', 'channelName', 'data', 'description', 'error', 'eventType', 'events', 'formatId', 'headers', 'latencyMs', 'payload', 'reachable', 'results', 'retry-after', 'source', 'status', 'timestamp', 'webhook_json', 'x-channel-id', 'x-harness-adapter']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\client.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [200, 300, 400, 409, 429, 500, 1000, '/', 'GET', 'POST', 'akhu-flush', 'body', 'channelId', 'channelName', 'data', 'description', 'error', 'eventType', 'events', 'formatId', 'headers', 'latencyMs', 'payload', 'reachable', 'results', 'retry-after', 'source', 'status', 'timestamp', 'webhook_json', 'x-channel-id', 'x-harness-adapter']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\wrappers\anthropic.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [1000, 'Anthropic Observer', 'LLM_ERROR', 'LLM_REQUEST', 'LLM_RESPONSE', 'T', 'TOOL_CALL', '[REDACTED]', '_', '__dict__', 'anthropic', 'content', 'correlationId', 'dict', 'durationMs', 'error_message', 'error_type', 'id', 'input', 'model', 'model_dump', 'name', 'provider', 'tool_name', 'tool_use', 'tool_use_id', 'type', 'unknown']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\wrappers\openai.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [1000, 'LLM_ERROR', 'LLM_REQUEST', 'LLM_RESPONSE', 'OpenAI Observer', 'T', 'TOOL_CALL', '[REDACTED]', '_', '_akhu_observer', 'arguments', 'choices', 'correlationId', 'durationMs', 'error_message', 'error_type', 'function', 'id', 'message', 'model', 'name', 'openai', 'provider', 'tool_call_id', 'tool_calls', 'tool_name', 'unknown']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\client.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [200, 300, 400, 409, 429, 500, 1000, '/', 'GET', 'POST', '_adapter', '_buffer', '_buffer_lock', '_buffer_size', '_channel_id', '_channel_name', '_channel_registered', '_description', '_destroyed', '_flush_interval_s', '_flush_lock', '_flush_timer', '_http', '_max_retries', '_on_error', '_on_flush', '_registering_lock', '_timeout_s', '_url', 'akhu-flush', 'body', 'channelId', 'channelName', 'data', 'description', 'error', 'eventType', 'events', 'formatId', 'headers', 'latencyMs', 'payload', 'reachable', 'results', 'retry-after', 'source', 'status', 'timestamp', 'webhook_json', 'x-channel-id', 'x-harness-adapter']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_types.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ []
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_redact.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ ['Authorization', 'X-Api-Key', '[REDACTED:MAX_DEPTH]', '[REDACTED]', 'accessToken', 'access_token', 'api-key', 'apiKey', 'api_key', 'authorization', 'bearer', 'cardNumber', 'card_number', 'choices', 'content', 'content_length', 'created', 'credential', 'credentials', 'creditCard', 'credit_card', 'finish_reason', 'frequency_penalty', 'function', 'function_names', 'functions', 'has_system', 'has_tool_calls', 'id', 'index', 'input', 'logit_bias', 'logprobs', 'max_tokens', 'message', 'message_count', 'message_roles', 'messages', 'metadata', 'model', 'n', 'name', 'object', 'parallel_tool_calls', 'password', 'presence_penalty', 'privateKey', 'private_key', 'refreshToken', 'refresh_token', 'response_format', 'role', 'secret', 'secretKey', 'secret_key', 'seed', 'service_tier', 'sessionToken', 'session_token', 'ssn', 'stop', 'stop_reason', 'stop_sequence', 'stop_sequences', 'stream', 'system', 'system_fingerprint', 'temperature', 'text', 'text_length', 'token', 'tool_call_count', 'tool_call_names', 'tool_calls', 'tool_choice', 'tool_names', 'tool_use', 'tools', 'top_k', 'top_p', 'type', 'unknown', 'usage', 'user', 'x-api-key']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\wrappers\anthropic.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [1000, 'Anthropic Observer', 'LLM_ERROR', 'LLM_REQUEST', 'LLM_RESPONSE', 'T', 'TOOL_CALL', '[REDACTED]', '_', '_akhu_observer', 'anthropic', 'content', 'correlationId', 'durationMs', 'error_message', 'error_type', 'id', 'input', 'model', 'name', 'provider', 'tool_name', 'tool_use', 'tool_use_id', 'type', 'unknown']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\__init__.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ ['0.1.0', 'AkhuClient', 'BatchIngestData', 'BatchIngestResponse', 'CHANNEL_ID_RE', 'ChannelHealth', 'ChannelInfo', 'ErrorCallback', 'FlushCallback', 'HealthStatus', 'IngestResponse', 'IngestResult', 'observe_anthropic', 'observe_openai']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_constants.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [0.05, 0.1, 0.2, 5.0, 10.0, 3600.0, 5000, 10000, 1048576, '/api/v1', 'AKHU_CAPTURE_CONTENT', 'AKHU_CHANNEL_ID', 'AKHU_CHANNEL_NAME', 'AKHU_URL', 'akhu-observer-openai', 'akhu-observer-python', 'python-anthropic', 'python-openai']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_http.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [5.0, 443, 'Content-Length', 'Content-Type', 'Retry-After', '_conn', '_destroyed', '_host', '_is_https', '_port', '_scheme', 'application/json', 'body', 'headers', 'https', 'localhost', 'raw', 'replace', 'retry-after', 'status', 'utf-8']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\wrappers\__init__.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ ['observe_anthropic', 'observe_openai']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_http.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [5.0, 443, 'Content-Length', 'Content-Type', 'Retry-After', 'application/json', 'body', 'headers', 'https', 'localhost', 'raw', 'replace', 'retry-after', 'status', 'utf-8']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_http.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [5.0, 443, 'Content-Length', 'Content-Type', 'Retry-After', '_conn', '_destroyed', '_host', '_is_https', '_port', '_scheme', 'application/json', 'body', 'headers', 'https', 'localhost', 'raw', 'replace', 'retry-after', 'status', 'utf-8']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\wrappers\__init__.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ []
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\_retry.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [429, 500, 600, 'T', 'broken pipe', 'connection refused', 'connection reset', 'host unreachable', 'network unreachable', 'retry_after_s', 'socket', 'timed out']
@@ -0,0 +1,4 @@
1
+ # file: C:\Users\newim\akhu-technologies\packages\observer-python\src\akhu_observer\wrappers\openai.py
2
+ # hypothesis_version: 6.151.14
3
+
4
+ [1000, 'LLM_ERROR', 'LLM_REQUEST', 'LLM_RESPONSE', 'OpenAI Observer', 'T', 'TOOL_CALL', '[REDACTED]', '_', '__dict__', 'arguments', 'choices', 'correlationId', 'dict', 'durationMs', 'error_message', 'error_type', 'function', 'id', 'message', 'model', 'model_dump', 'name', 'openai', 'provider', 'tool_call_id', 'tool_calls', 'tool_name', 'unknown']
@@ -0,0 +1 @@
1
+ a��>���N��=��. ?�Yc�co���E!Rۿ:K|<6��QKF�]�
@@ -0,0 +1 @@
1
+ a��>���N��=��. ?�Yc�co���E!Rۿ:K|<6��QKF�]�.secondary
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: akhu-observer
3
+ Version: 0.1.0
4
+ Summary: AKHU Observer SDK — Evidence infrastructure adapter for AI systems
5
+ License: SEE LICENSE IN ROOT
6
+ Keywords: ai,audit,compliance,eu-ai-act,evidence,observability
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.10
17
+ Provides-Extra: anthropic
18
+ Requires-Dist: anthropic>=0.20.0; extra == 'anthropic'
19
+ Provides-Extra: dev
20
+ Requires-Dist: hypothesis>=6.0; extra == 'dev'
21
+ Requires-Dist: pytest-timeout>=2.0; extra == 'dev'
22
+ Requires-Dist: pytest>=7.0; extra == 'dev'
23
+ Provides-Extra: openai
24
+ Requires-Dist: openai>=1.0.0; extra == 'openai'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # akhu-observer (Python)
28
+
29
+ 𓅂 **AKHU Observer SDK** — Evidence infrastructure adapter for AI systems.
30
+
31
+ Zero-dependency Python SDK for connecting AI applications to the AKHU evidence ledger.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ pip install akhu-observer
37
+ ```
38
+
39
+ With provider support:
40
+
41
+ ```bash
42
+ pip install "akhu-observer[openai]" # OpenAI wrapper
43
+ pip install "akhu-observer[anthropic]" # Anthropic wrapper
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ### Direct Client
49
+
50
+ ```python
51
+ from akhu_observer import AkhuClient
52
+
53
+ client = AkhuClient(url="http://akhu-api:3000", channel_id="my-system")
54
+ client.observe("DOCUMENT_PROCESSED", {"doc_id": "abc-123", "pages": 12})
55
+ ```
56
+
57
+ ### OpenAI Wrapper
58
+
59
+ ```python
60
+ from openai import OpenAI
61
+ from akhu_observer import observe_openai
62
+
63
+ client = observe_openai(OpenAI(), akhu_url="http://akhu-api:3000")
64
+ response = client.chat.completions.create(model="gpt-4o", messages=[...])
65
+ # Observation sent automatically — response unmodified
66
+ ```
67
+
68
+ ### Anthropic Wrapper
69
+
70
+ ```python
71
+ from anthropic import Anthropic
72
+ from akhu_observer import observe_anthropic
73
+
74
+ client = observe_anthropic(Anthropic(), akhu_url="http://akhu-api:3000")
75
+ response = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=1024, messages=[...])
76
+ ```
77
+
78
+ ### Environment Variables
79
+
80
+ ```bash
81
+ export AKHU_URL="http://akhu-api:3000"
82
+ export AKHU_CHANNEL_ID="my-channel"
83
+ ```
84
+
85
+ ```python
86
+ # No config needed — reads from environment
87
+ client = AkhuClient()
88
+ ```
89
+
90
+ ## Architecture
91
+
92
+ - **Zero runtime dependencies** — uses only Python stdlib (`http.client`, `threading`, `json`)
93
+ - **Fail-open** — observation failures never affect the observed system
94
+ - **Privacy by default** — content redacted unless explicitly opted in
95
+ - **Security always** — credentials stripped even with `capture_content=True`
96
+ - **Thread-safe** — safe to use from any thread, background flush via daemon threads
97
+
98
+ Full API reference: [OBSERVER-SDK-REFERENCE.md](../../docs/OBSERVER-SDK-REFERENCE.md)
99
+
100
+ ## Development
101
+
102
+ ```bash
103
+ cd packages/observer-python
104
+ pip install -e ".[dev]"
105
+ pytest
106
+ pytest tests/invariants/ # Property-based tests
107
+ pytest tests/adversarial/ # Injection/attack resistance
108
+ ```
@@ -0,0 +1,82 @@
1
+ # akhu-observer (Python)
2
+
3
+ 𓅂 **AKHU Observer SDK** — Evidence infrastructure adapter for AI systems.
4
+
5
+ Zero-dependency Python SDK for connecting AI applications to the AKHU evidence ledger.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install akhu-observer
11
+ ```
12
+
13
+ With provider support:
14
+
15
+ ```bash
16
+ pip install "akhu-observer[openai]" # OpenAI wrapper
17
+ pip install "akhu-observer[anthropic]" # Anthropic wrapper
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### Direct Client
23
+
24
+ ```python
25
+ from akhu_observer import AkhuClient
26
+
27
+ client = AkhuClient(url="http://akhu-api:3000", channel_id="my-system")
28
+ client.observe("DOCUMENT_PROCESSED", {"doc_id": "abc-123", "pages": 12})
29
+ ```
30
+
31
+ ### OpenAI Wrapper
32
+
33
+ ```python
34
+ from openai import OpenAI
35
+ from akhu_observer import observe_openai
36
+
37
+ client = observe_openai(OpenAI(), akhu_url="http://akhu-api:3000")
38
+ response = client.chat.completions.create(model="gpt-4o", messages=[...])
39
+ # Observation sent automatically — response unmodified
40
+ ```
41
+
42
+ ### Anthropic Wrapper
43
+
44
+ ```python
45
+ from anthropic import Anthropic
46
+ from akhu_observer import observe_anthropic
47
+
48
+ client = observe_anthropic(Anthropic(), akhu_url="http://akhu-api:3000")
49
+ response = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=1024, messages=[...])
50
+ ```
51
+
52
+ ### Environment Variables
53
+
54
+ ```bash
55
+ export AKHU_URL="http://akhu-api:3000"
56
+ export AKHU_CHANNEL_ID="my-channel"
57
+ ```
58
+
59
+ ```python
60
+ # No config needed — reads from environment
61
+ client = AkhuClient()
62
+ ```
63
+
64
+ ## Architecture
65
+
66
+ - **Zero runtime dependencies** — uses only Python stdlib (`http.client`, `threading`, `json`)
67
+ - **Fail-open** — observation failures never affect the observed system
68
+ - **Privacy by default** — content redacted unless explicitly opted in
69
+ - **Security always** — credentials stripped even with `capture_content=True`
70
+ - **Thread-safe** — safe to use from any thread, background flush via daemon threads
71
+
72
+ Full API reference: [OBSERVER-SDK-REFERENCE.md](../../docs/OBSERVER-SDK-REFERENCE.md)
73
+
74
+ ## Development
75
+
76
+ ```bash
77
+ cd packages/observer-python
78
+ pip install -e ".[dev]"
79
+ pytest
80
+ pytest tests/invariants/ # Property-based tests
81
+ pytest tests/adversarial/ # Injection/attack resistance
82
+ ```
@@ -0,0 +1,76 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "akhu-observer"
7
+ version = "0.1.0"
8
+ description = "AKHU Observer SDK — Evidence infrastructure adapter for AI systems"
9
+ readme = "README.md"
10
+ license = {text = "SEE LICENSE IN ROOT"}
11
+ requires-python = ">=3.10"
12
+ dependencies = []
13
+ keywords = ["ai", "observability", "evidence", "audit", "compliance", "eu-ai-act"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ "Typing :: Typed",
24
+ ]
25
+
26
+ [project.optional-dependencies]
27
+ openai = ["openai>=1.0.0"]
28
+ anthropic = ["anthropic>=0.20.0"]
29
+ dev = [
30
+ "pytest>=7.0",
31
+ "pytest-timeout>=2.0",
32
+ "hypothesis>=6.0",
33
+ ]
34
+
35
+ [tool.pytest.ini_options]
36
+ testpaths = ["tests"]
37
+ timeout = 10
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/akhu_observer"]
41
+ artifacts = ["src/akhu_observer/py.typed"]
42
+
43
+ [tool.ruff]
44
+ target-version = "py310"
45
+ line-length = 100
46
+
47
+ [tool.ruff.lint]
48
+ select = [
49
+ "E", # pycodestyle errors
50
+ "W", # pycodestyle warnings
51
+ "F", # pyflakes
52
+ "I", # isort
53
+ "N", # pep8-naming
54
+ "UP", # pyupgrade
55
+ "B", # flake8-bugbear
56
+ "S", # flake8-bandit (security)
57
+ "A", # flake8-builtins
58
+ "C4", # flake8-comprehensions
59
+ "SIM", # flake8-simplify
60
+ "TCH", # flake8-type-checking
61
+ "RUF", # ruff-specific
62
+ ]
63
+ ignore = [
64
+ "S311", # random for jitter is acceptable (not crypto)
65
+ "S101", # assert in tests
66
+ ]
67
+
68
+ [tool.ruff.lint.per-file-ignores]
69
+ "tests/**" = ["S101", "S106", "S105"]
70
+
71
+ [tool.mypy]
72
+ python_version = "3.10"
73
+ strict = true
74
+ warn_return_any = true
75
+ warn_unused_configs = true
76
+ disallow_untyped_defs = true
@@ -0,0 +1,46 @@
1
+ """
2
+ akhu-observer — Public API
3
+
4
+ This is the only entry point. Everything exported here IS the SDK.
5
+ Everything not exported here is internal implementation detail.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from .client import AkhuClient
11
+ from .wrappers.openai import observe_openai
12
+ from .wrappers.anthropic import observe_anthropic
13
+ from ._constants import CHANNEL_ID_RE
14
+ from ._types import (
15
+ ErrorCallback,
16
+ FlushCallback,
17
+ HealthStatus,
18
+ IngestResult,
19
+ IngestResponse,
20
+ BatchIngestData,
21
+ BatchIngestResponse,
22
+ ChannelHealth,
23
+ ChannelInfo,
24
+ )
25
+
26
+ __all__ = [
27
+ # Core
28
+ "AkhuClient",
29
+ # Wrappers
30
+ "observe_openai",
31
+ "observe_anthropic",
32
+ # Constants
33
+ "CHANNEL_ID_RE",
34
+ # Types
35
+ "ErrorCallback",
36
+ "FlushCallback",
37
+ "HealthStatus",
38
+ "IngestResult",
39
+ "IngestResponse",
40
+ "BatchIngestData",
41
+ "BatchIngestResponse",
42
+ "ChannelHealth",
43
+ "ChannelInfo",
44
+ ]
45
+
46
+ __version__ = "0.1.0"