bylaw-python 0.4.0__py3-none-any.whl
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.
- bylaw_python/__init__.py +114 -0
- bylaw_python/adapters/__init__.py +1 -0
- bylaw_python/adapters/_core.py +58 -0
- bylaw_python/adapters/crewai.py +99 -0
- bylaw_python/adapters/langchain.py +167 -0
- bylaw_python/adapters/llamaindex.py +90 -0
- bylaw_python/cli.py +366 -0
- bylaw_python/client.py +1595 -0
- bylaw_python/config.py +95 -0
- bylaw_python/counterparty.py +145 -0
- bylaw_python/enforce.py +561 -0
- bylaw_python/exceptions.py +104 -0
- bylaw_python/manifest.py +152 -0
- bylaw_python/models.py +330 -0
- bylaw_python/pending.py +128 -0
- bylaw_python/webhook.py +44 -0
- bylaw_python-0.4.0.dist-info/METADATA +227 -0
- bylaw_python-0.4.0.dist-info/RECORD +20 -0
- bylaw_python-0.4.0.dist-info/WHEEL +4 -0
- bylaw_python-0.4.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bylaw-python
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Agent-agnostic compliance shim for SOX 404 policy enforcement via the ALCV Vault
|
|
5
|
+
Project-URL: Homepage, https://github.com/bylaw-dev/python-sdk
|
|
6
|
+
Project-URL: Documentation, https://docs.bylaw.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/bylaw-dev/python-sdk
|
|
8
|
+
Author-email: Bylaw <team@bylaw.dev>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: agents,ai,compliance,security,sox404,vault
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: cachetools>=5.3.0
|
|
24
|
+
Requires-Dist: click>=8.1.0
|
|
25
|
+
Requires-Dist: httpx>=0.25.0
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: pyjwt[crypto]>=2.8.0
|
|
29
|
+
Provides-Extra: crewai
|
|
30
|
+
Requires-Dist: crewai>=0.1.0; extra == 'crewai'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: build>=1.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: respx>=0.21.0; extra == 'dev'
|
|
37
|
+
Provides-Extra: langchain
|
|
38
|
+
Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
|
|
39
|
+
Provides-Extra: llamaindex
|
|
40
|
+
Requires-Dist: llama-index-core>=0.10.0; extra == 'llamaindex'
|
|
41
|
+
Provides-Extra: yaml
|
|
42
|
+
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# Ledgix ALCV — Python SDK
|
|
46
|
+
|
|
47
|
+
[](https://pypi.org/project/bylaw-python/)
|
|
48
|
+
[](https://python.org)
|
|
49
|
+
[](LICENSE)
|
|
50
|
+
|
|
51
|
+
Agent-agnostic compliance shim for SOX 404 policy enforcement. Intercepts AI agent tool calls, validates them against your policies via the ALCV Vault, and ensures only approved actions receive a cryptographically signed A-JWT (Agentic JSON Web Token).
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install bylaw-python
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
# ledgix.yaml
|
|
61
|
+
# enforce:
|
|
62
|
+
# - tool: "stripe_*"
|
|
63
|
+
# policy_id: "financial-high-risk"
|
|
64
|
+
# - tool: "*"
|
|
65
|
+
# policy_id: "default"
|
|
66
|
+
|
|
67
|
+
import tools
|
|
68
|
+
import bylaw_python as ledgix
|
|
69
|
+
|
|
70
|
+
ledgix.configure(agent_id="payments-agent")
|
|
71
|
+
ledgix.auto_instrument(tools)
|
|
72
|
+
|
|
73
|
+
result = tools.stripe_refund(45, "Late package")
|
|
74
|
+
print(result)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`auto_instrument()` reads `ledgix.yaml`, `ledgix.yml`, or `ledgix.json` from the current working directory by default, wraps matching functions in place, and leaves unmatched functions alone.
|
|
78
|
+
|
|
79
|
+
## Configuration
|
|
80
|
+
|
|
81
|
+
Set environment variables (prefix: `LEDGIX_`):
|
|
82
|
+
|
|
83
|
+
| Variable | Default | Description |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `LEDGIX_VAULT_URL` | `http://localhost:8000` | Vault server URL |
|
|
86
|
+
| `LEDGIX_VAULT_API_KEY` | `""` | API key for Vault auth |
|
|
87
|
+
| `LEDGIX_VAULT_TIMEOUT` | `30.0` | Request timeout (seconds) |
|
|
88
|
+
| `LEDGIX_VERIFY_JWT` | `true` | Verify A-JWT signatures |
|
|
89
|
+
| `LEDGIX_JWT_ISSUER` | `alcv-vault` | Expected A-JWT issuer |
|
|
90
|
+
| `LEDGIX_JWT_AUDIENCE` | `ledgix-sdk` | Expected A-JWT audience |
|
|
91
|
+
| `LEDGIX_AGENT_ID` | `default-agent` | Agent identifier |
|
|
92
|
+
|
|
93
|
+
Or pass a `VaultConfig` directly:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from bylaw_python import LedgixClient, VaultConfig
|
|
97
|
+
|
|
98
|
+
config = VaultConfig(vault_url="https://vault.mycompany.com", vault_api_key="sk-...")
|
|
99
|
+
client = LedgixClient(config=config)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Manifest-driven auto-instrumentation
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
import tools
|
|
106
|
+
import bylaw_python as ledgix
|
|
107
|
+
|
|
108
|
+
ledgix.configure(agent_id="payments-agent")
|
|
109
|
+
|
|
110
|
+
# Auto-discover ledgix.yaml / ledgix.yml / ledgix.json from the CWD
|
|
111
|
+
wrapped = ledgix.auto_instrument(tools)
|
|
112
|
+
|
|
113
|
+
# Or pass an inline manifest
|
|
114
|
+
ledgix.auto_instrument(
|
|
115
|
+
tools,
|
|
116
|
+
manifest={"enforce": [{"tool": "stripe_*", "policy_id": "financial-high-risk"}]},
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
YAML manifests require `pyyaml`:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
pip install bylaw-python[yaml]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Escape hatch
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
@ledgix.tool
|
|
130
|
+
def special_refund(amount: float):
|
|
131
|
+
return ledgix.current_token()
|
|
132
|
+
|
|
133
|
+
@ledgix.tool(policy_id="override-policy")
|
|
134
|
+
def stripe_charge(amount: float):
|
|
135
|
+
return ledgix.current_token()
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Framework Adapters
|
|
139
|
+
|
|
140
|
+
### LangChain
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pip install bylaw-python[langchain]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from bylaw_python.adapters.langchain import LedgixCallbackHandler, LedgixTool
|
|
148
|
+
|
|
149
|
+
# Option 1: Callback handler (intercepts ALL tool calls)
|
|
150
|
+
handler = LedgixCallbackHandler(client)
|
|
151
|
+
agent = create_agent(callbacks=[handler])
|
|
152
|
+
|
|
153
|
+
# Option 2: Wrap individual tools
|
|
154
|
+
guarded_tool = LedgixTool.wrap(client, my_tool, policy_id="refund-policy")
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### LlamaIndex
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install bylaw-python[llamaindex]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from bylaw_python.adapters.llamaindex import wrap_tool
|
|
165
|
+
|
|
166
|
+
guarded_tool = wrap_tool(client, my_function_tool, policy_id="refund-policy")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### CrewAI
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
pip install bylaw-python[crewai]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from bylaw_python.adapters.crewai import LedgixCrewAITool
|
|
177
|
+
|
|
178
|
+
guarded_tool = LedgixCrewAITool.wrap(client, my_tool, policy_id="refund-policy")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Context Manager
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from bylaw_python import VaultContext
|
|
185
|
+
|
|
186
|
+
with VaultContext(client, "stripe_refund", {"amount": 45}) as ctx:
|
|
187
|
+
print(ctx.clearance.token) # Use the A-JWT
|
|
188
|
+
|
|
189
|
+
# Async
|
|
190
|
+
async with VaultContext(client, "stripe_refund", {"amount": 45}) as ctx:
|
|
191
|
+
print(ctx.clearance.token)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Error Handling
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from bylaw_python import ClearanceDeniedError, VaultConnectionError, TokenVerificationError
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
result = process_refund(amount=5000, reason="...")
|
|
201
|
+
except ClearanceDeniedError as e:
|
|
202
|
+
print(f"Blocked: {e.reason} (request: {e.request_id})")
|
|
203
|
+
except VaultConnectionError:
|
|
204
|
+
print("Cannot reach Vault — fail-closed")
|
|
205
|
+
except TokenVerificationError:
|
|
206
|
+
print("A-JWT signature invalid")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Development
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
git clone https://github.com/ledgix-dev/python-sdk.git
|
|
213
|
+
cd python-sdk
|
|
214
|
+
python -m venv .venv && source .venv/bin/activate
|
|
215
|
+
pip install -e ".[dev]"
|
|
216
|
+
pytest tests/ -v --cov
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Demo
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
python demo.py
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
bylaw_python/__init__.py,sha256=9kaXSZVekS5yOmHphhZgv6KteAvH_oK37G3bQsYzALE,2669
|
|
2
|
+
bylaw_python/cli.py,sha256=QfXMCjtLljc7K6V2KfZsgyxw0_q4-k_DCfbEjMbhp6I,11601
|
|
3
|
+
bylaw_python/client.py,sha256=_6XBbWrEYeEOYEsp2H_JyTcUgM9UU612G5zDLZeGS3s,70427
|
|
4
|
+
bylaw_python/config.py,sha256=Mw9h5hIPyMhxx55a3E0PaICNhJNrEtu3gdYBkjhS06k,3630
|
|
5
|
+
bylaw_python/counterparty.py,sha256=nEBLkQexndU1LPwbbblroVhWMEVFdh24kF-xdIDJtXs,4774
|
|
6
|
+
bylaw_python/enforce.py,sha256=TcPiyK35ouB5-iCpVGOeitHGjvsdWI5NCr7o0cXhswM,20827
|
|
7
|
+
bylaw_python/exceptions.py,sha256=gXXOxlaQFAnbTjRNJqPDJt1L7yHY1E7kgDQjbqSNEW0,3957
|
|
8
|
+
bylaw_python/manifest.py,sha256=WXuM9pYOyq-PHFqqgmVuDd4yDHYyJu5ObwyFnAU8-kA,4834
|
|
9
|
+
bylaw_python/models.py,sha256=Lbb5JpvWDzfxa-8iEuSslJpqu3apKPkYcITgHmF1Nqk,12940
|
|
10
|
+
bylaw_python/pending.py,sha256=pLvyHQO6jb9sJK7SeeRO2wvKRC6K-EkzERC_krJKN70,4697
|
|
11
|
+
bylaw_python/webhook.py,sha256=MD8dZZTPJ9xvk1e6isu26E7gt4goLxukLzTOAFAzWNc,1523
|
|
12
|
+
bylaw_python/adapters/__init__.py,sha256=qI-boxRb6Qgy7SkC3cTt1rXEH7geZzzV7ynNje-W6iQ,37
|
|
13
|
+
bylaw_python/adapters/_core.py,sha256=0LJmcbjzKaCJhFcYA7FTsj5oiAR6-LFIrU57XOBKNu8,2025
|
|
14
|
+
bylaw_python/adapters/crewai.py,sha256=I1VKAHg8Fuo2Ip7HHD1EyZDqPCq4wHbwjVK_Cp2K_sA,2981
|
|
15
|
+
bylaw_python/adapters/langchain.py,sha256=l-LO1cEUg82lKdLvDjaLOGyWsjS_9_e-_Di5EwLvzDA,5418
|
|
16
|
+
bylaw_python/adapters/llamaindex.py,sha256=z1uz-hGPEnNO34K_TLEnJP8y4HNLCiKkTwP01EAWH2g,2924
|
|
17
|
+
bylaw_python-0.4.0.dist-info/METADATA,sha256=Ovxx76HNp1g5PWkGV_g37Vx3Q8b9-1NQe5aL99R79L8,6227
|
|
18
|
+
bylaw_python-0.4.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
19
|
+
bylaw_python-0.4.0.dist-info/entry_points.txt,sha256=89hNo5_9O_5XXVkHOG2urhQEp_KiSnq87vk4MMa8vD0,48
|
|
20
|
+
bylaw_python-0.4.0.dist-info/RECORD,,
|