vaultkit 0.2.0__tar.gz → 0.3.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.
- {vaultkit-0.2.0 → vaultkit-0.3.0}/PKG-INFO +32 -1
- {vaultkit-0.2.0 → vaultkit-0.3.0}/README.md +31 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/pyproject.toml +1 -1
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/__init__.py +1 -1
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/client.py +41 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/definitions.py +67 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/executor.py +4 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/utils/validation.py +74 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit.egg-info/PKG-INFO +32 -1
- {vaultkit-0.2.0 → vaultkit-0.3.0}/setup.cfg +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/tests/test_fetch.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/tests/test_query.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/core/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/core/http.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/core/polling.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/errors/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/errors/base.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/errors/exceptions.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/mcp/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/mcp/__main__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/mcp/identity.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/mcp/server.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/models/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/models/dataset_info.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/models/dataset_schema.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/models/fetch_result.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/models/query_result.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/adapters/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/adapters/anthropic.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/adapters/mcp.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/adapters/openai.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/builder.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/tools/schemas.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/utils/__init__.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit/utils/retry.py +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit.egg-info/SOURCES.txt +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit.egg-info/dependency_links.txt +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit.egg-info/entry_points.txt +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit.egg-info/requires.txt +0 -0
- {vaultkit-0.2.0 → vaultkit-0.3.0}/vaultkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vaultkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: VaultKit Python SDK for policy-driven, runtime governed data access
|
|
5
5
|
Author-email: VaultKit <founders@vaultkit.io>
|
|
6
6
|
License: MIT
|
|
@@ -74,6 +74,37 @@ print(result.rows)
|
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
77
|
+
## Analytical Queries
|
|
78
|
+
|
|
79
|
+
Aggregate, group, filter on aggregates and sort within a single dataset:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
result = client.execute(
|
|
83
|
+
dataset="orders",
|
|
84
|
+
fields=["region"],
|
|
85
|
+
aggregates=[{"func": "sum", "field": "amount", "alias": "total"}],
|
|
86
|
+
having=[{"field": "SUM(amount)", "operator": "gt", "value": 1000}],
|
|
87
|
+
order_by={"column": "total", "direction": "desc"},
|
|
88
|
+
limit=10,
|
|
89
|
+
purpose="Quarterly revenue by region",
|
|
90
|
+
)
|
|
91
|
+
# [{"region": "US", "total": 18250}, {"region": "CA", "total": 4100}, ...]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- `aggregates`: `func` is one of `count`, `sum`, `avg`, `min`, `max`; use `field="*"` with `count`.
|
|
95
|
+
- `group_by`: optional. Defaults to `fields`; if given, it must include every entry in `fields`.
|
|
96
|
+
- `having`: needs an aggregate expression such as `SUM(amount)`, not an alias.
|
|
97
|
+
- `order_by`: a field, an aggregate alias or an aggregate expression, `asc` (default) or `desc`.
|
|
98
|
+
- `fields` can be omitted for a single total, e.g. `aggregates=[{"func": "count", "field": "*"}]`.
|
|
99
|
+
|
|
100
|
+
Policies apply to every field these clauses use. `min`/`max`/`sum`/`avg` over a masked
|
|
101
|
+
field are denied; `count` is allowed. Joins are not supported.
|
|
102
|
+
|
|
103
|
+
> Requires a VaultKit control plane with intent analytics support. Older control
|
|
104
|
+
> planes ignore these parameters and return ungrouped rows.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
77
108
|
## AI Agent Usage
|
|
78
109
|
|
|
79
110
|
VaultKit provides built-in tools for LLM agents.
|
|
@@ -48,6 +48,37 @@ print(result.rows)
|
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
|
+
## Analytical Queries
|
|
52
|
+
|
|
53
|
+
Aggregate, group, filter on aggregates and sort within a single dataset:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
result = client.execute(
|
|
57
|
+
dataset="orders",
|
|
58
|
+
fields=["region"],
|
|
59
|
+
aggregates=[{"func": "sum", "field": "amount", "alias": "total"}],
|
|
60
|
+
having=[{"field": "SUM(amount)", "operator": "gt", "value": 1000}],
|
|
61
|
+
order_by={"column": "total", "direction": "desc"},
|
|
62
|
+
limit=10,
|
|
63
|
+
purpose="Quarterly revenue by region",
|
|
64
|
+
)
|
|
65
|
+
# [{"region": "US", "total": 18250}, {"region": "CA", "total": 4100}, ...]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- `aggregates`: `func` is one of `count`, `sum`, `avg`, `min`, `max`; use `field="*"` with `count`.
|
|
69
|
+
- `group_by`: optional. Defaults to `fields`; if given, it must include every entry in `fields`.
|
|
70
|
+
- `having`: needs an aggregate expression such as `SUM(amount)`, not an alias.
|
|
71
|
+
- `order_by`: a field, an aggregate alias or an aggregate expression, `asc` (default) or `desc`.
|
|
72
|
+
- `fields` can be omitted for a single total, e.g. `aggregates=[{"func": "count", "field": "*"}]`.
|
|
73
|
+
|
|
74
|
+
Policies apply to every field these clauses use. `min`/`max`/`sum`/`avg` over a masked
|
|
75
|
+
field are denied; `count` is allowed. Joins are not supported.
|
|
76
|
+
|
|
77
|
+
> Requires a VaultKit control plane with intent analytics support. Older control
|
|
78
|
+
> planes ignore these parameters and return ungrouped rows.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
51
82
|
## AI Agent Usage
|
|
52
83
|
|
|
53
84
|
VaultKit provides built-in tools for LLM agents.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vaultkit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "VaultKit Python SDK for policy-driven, runtime governed data access"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "VaultKit", email = "founders@vaultkit.io" }
|
|
@@ -19,7 +19,11 @@ from vaultkit.models.query_result import QueryResult
|
|
|
19
19
|
from vaultkit.utils.retry import RetryConfig, with_retries
|
|
20
20
|
from vaultkit.utils.validation import (
|
|
21
21
|
require_str,
|
|
22
|
+
validate_aggregates,
|
|
22
23
|
validate_filters,
|
|
24
|
+
validate_group_by,
|
|
25
|
+
validate_having,
|
|
26
|
+
validate_order_by,
|
|
23
27
|
validate_limit,
|
|
24
28
|
)
|
|
25
29
|
|
|
@@ -98,6 +102,10 @@ class VaultKitClient:
|
|
|
98
102
|
fields: Optional[List[str]] = None,
|
|
99
103
|
filters: Optional[List[Dict[str, Any]]] = None,
|
|
100
104
|
limit: Optional[int] = None,
|
|
105
|
+
aggregates: Optional[List[Dict[str, Any]]] = None,
|
|
106
|
+
group_by: Optional[List[str]] = None,
|
|
107
|
+
having: Optional[List[Dict[str, Any]]] = None,
|
|
108
|
+
order_by: Optional[Dict[str, Any]] = None,
|
|
101
109
|
purpose: Optional[str] = None,
|
|
102
110
|
requester_region: Optional[str] = None,
|
|
103
111
|
requester_clearance: Optional[str] = None,
|
|
@@ -106,6 +114,18 @@ class VaultKitClient:
|
|
|
106
114
|
"""
|
|
107
115
|
Submit an intent request and return data — full grant lifecycle internal.
|
|
108
116
|
|
|
117
|
+
Analytical queries (single dataset, no joins):
|
|
118
|
+
aggregates [{"func": "sum", "field": "amount", "alias": "total"}]
|
|
119
|
+
func is one of count, sum, avg, min, max; "*" only with count.
|
|
120
|
+
group_by ["region"] — every field in `fields` must be listed when given.
|
|
121
|
+
having [{"field": "SUM(amount)", "operator": "gt", "value": 1000}]
|
|
122
|
+
field must be an aggregate expression, not an alias.
|
|
123
|
+
order_by {"column": "total", "direction": "desc"}
|
|
124
|
+
|
|
125
|
+
`fields` may be omitted when `aggregates` is given (e.g. a single COUNT(*)).
|
|
126
|
+
Requires a control plane that supports intent analytics; older ones
|
|
127
|
+
ignore these parameters.
|
|
128
|
+
|
|
109
129
|
Raises:
|
|
110
130
|
DeniedError Policy rejected. Do not retry.
|
|
111
131
|
ApprovalRequiredError Needs human approval (request_id attached).
|
|
@@ -126,6 +146,10 @@ class VaultKitClient:
|
|
|
126
146
|
fields=fields,
|
|
127
147
|
filters=filters,
|
|
128
148
|
limit=limit,
|
|
149
|
+
aggregates=aggregates,
|
|
150
|
+
group_by=group_by,
|
|
151
|
+
having=having,
|
|
152
|
+
order_by=order_by,
|
|
129
153
|
purpose=purpose,
|
|
130
154
|
requester_region=requester_region,
|
|
131
155
|
requester_clearance=requester_clearance,
|
|
@@ -214,6 +238,10 @@ class VaultKitClient:
|
|
|
214
238
|
fields: Optional[List[str]] = None,
|
|
215
239
|
filters: Optional[List[Dict[str, Any]]] = None,
|
|
216
240
|
limit: Optional[int] = None,
|
|
241
|
+
aggregates: Optional[List[Dict[str, Any]]] = None,
|
|
242
|
+
group_by: Optional[List[str]] = None,
|
|
243
|
+
having: Optional[List[Dict[str, Any]]] = None,
|
|
244
|
+
order_by: Optional[Dict[str, Any]] = None,
|
|
217
245
|
purpose: Optional[str] = None,
|
|
218
246
|
requester_region: Optional[str] = None,
|
|
219
247
|
requester_clearance: Optional[str] = None,
|
|
@@ -223,6 +251,10 @@ class VaultKitClient:
|
|
|
223
251
|
dataset = require_str("dataset", dataset)
|
|
224
252
|
limit = validate_limit(limit)
|
|
225
253
|
filters = validate_filters(filters)
|
|
254
|
+
aggregates = validate_aggregates(aggregates)
|
|
255
|
+
group_by = validate_group_by(group_by)
|
|
256
|
+
having = validate_having(having)
|
|
257
|
+
order_by = validate_order_by(order_by)
|
|
226
258
|
|
|
227
259
|
req: Dict[str, Any] = {"dataset": dataset}
|
|
228
260
|
body: Dict[str, Any] = {"request": req}
|
|
@@ -235,6 +267,14 @@ class VaultKitClient:
|
|
|
235
267
|
req["purpose"] = str(purpose)
|
|
236
268
|
if filters is not None:
|
|
237
269
|
req["filters"] = filters
|
|
270
|
+
if aggregates is not None:
|
|
271
|
+
req["aggregates"] = aggregates
|
|
272
|
+
if group_by is not None:
|
|
273
|
+
req["group_by"] = group_by
|
|
274
|
+
if having is not None:
|
|
275
|
+
req["having"] = having
|
|
276
|
+
if order_by is not None:
|
|
277
|
+
req["order_by"] = order_by
|
|
238
278
|
if requester_region is not None:
|
|
239
279
|
body["requester_region"] = requester_region
|
|
240
280
|
if requester_clearance is not None:
|
|
@@ -248,6 +288,7 @@ class VaultKitClient:
|
|
|
248
288
|
"poll": poll,
|
|
249
289
|
"has_fields": fields is not None,
|
|
250
290
|
"has_filters": filters is not None,
|
|
291
|
+
"has_aggregates": aggregates is not None,
|
|
251
292
|
"limit": limit,
|
|
252
293
|
},
|
|
253
294
|
)
|
|
@@ -115,6 +115,8 @@ def query_tool_def(
|
|
|
115
115
|
"description": (
|
|
116
116
|
"Query a governed dataset through VaultKit. Policies are enforced automatically: "
|
|
117
117
|
"sensitive fields may be masked and some datasets require approval before data is returned. "
|
|
118
|
+
"Supports aggregation (count/sum/avg/min/max), grouping, having and sorting on a single dataset; "
|
|
119
|
+
"joins are not supported. "
|
|
118
120
|
"Returns data or a pending status if approval is required."
|
|
119
121
|
),
|
|
120
122
|
"input_schema": {
|
|
@@ -143,6 +145,71 @@ def query_tool_def(
|
|
|
143
145
|
"maximum": 10000,
|
|
144
146
|
"description": "Maximum number of rows to return.",
|
|
145
147
|
},
|
|
148
|
+
"aggregates": {
|
|
149
|
+
"type": "array",
|
|
150
|
+
"minItems": 1,
|
|
151
|
+
"items": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {
|
|
154
|
+
"func": {"type": "string", "enum": ["count", "sum", "avg", "min", "max"]},
|
|
155
|
+
"field": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"description": "A field of the selected dataset, or '*' with count.",
|
|
158
|
+
},
|
|
159
|
+
"alias": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
|
|
162
|
+
"description": "Name of the result column. Use it in order_by.",
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
"required": ["func", "field"],
|
|
166
|
+
},
|
|
167
|
+
"description": (
|
|
168
|
+
"Aggregate functions over the selected dataset. When aggregating, every entry in "
|
|
169
|
+
"'fields' is a grouping column. 'fields' may be omitted for a single total.\n\n"
|
|
170
|
+
"Example: [{func: 'sum', field: 'amount', alias: 'total'}]\n"
|
|
171
|
+
"min/max/sum/avg over masked fields are denied by policy; count is allowed."
|
|
172
|
+
),
|
|
173
|
+
},
|
|
174
|
+
"group_by": {
|
|
175
|
+
"type": "array",
|
|
176
|
+
"items": {"type": "string"},
|
|
177
|
+
"description": (
|
|
178
|
+
"Fields to group by. Optional: defaults to 'fields'. If given, it must include "
|
|
179
|
+
"every entry in 'fields'."
|
|
180
|
+
),
|
|
181
|
+
},
|
|
182
|
+
"having": {
|
|
183
|
+
"type": "array",
|
|
184
|
+
"items": {
|
|
185
|
+
"type": "object",
|
|
186
|
+
"properties": {
|
|
187
|
+
"field": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"description": "An aggregate expression such as 'SUM(amount)'. Aliases are not allowed here.",
|
|
190
|
+
},
|
|
191
|
+
"operator": {"type": "string", "enum": ["gt", "lt", "eq", "gte", "lte"]},
|
|
192
|
+
"value": {"type": "number"},
|
|
193
|
+
},
|
|
194
|
+
"required": ["field", "operator", "value"],
|
|
195
|
+
},
|
|
196
|
+
"description": (
|
|
197
|
+
"Filters applied after aggregation. Requires 'aggregates'.\n\n"
|
|
198
|
+
"Example: [{field: 'SUM(amount)', operator: 'gt', value: 1000}]"
|
|
199
|
+
),
|
|
200
|
+
},
|
|
201
|
+
"order_by": {
|
|
202
|
+
"type": "object",
|
|
203
|
+
"properties": {
|
|
204
|
+
"column": {
|
|
205
|
+
"type": "string",
|
|
206
|
+
"description": "A field, an aggregate alias, or an aggregate expression.",
|
|
207
|
+
},
|
|
208
|
+
"direction": {"type": "string", "enum": ["asc", "desc"], "default": "asc"},
|
|
209
|
+
},
|
|
210
|
+
"required": ["column"],
|
|
211
|
+
"description": "Sort order of the results.",
|
|
212
|
+
},
|
|
146
213
|
"purpose": {
|
|
147
214
|
"type": "string",
|
|
148
215
|
"description": (
|
|
@@ -105,6 +105,10 @@ class ToolExecutor:
|
|
|
105
105
|
fields=args.get("fields"),
|
|
106
106
|
filters=args.get("filters"),
|
|
107
107
|
limit=args.get("limit"),
|
|
108
|
+
aggregates=args.get("aggregates"),
|
|
109
|
+
group_by=args.get("group_by"),
|
|
110
|
+
having=args.get("having"),
|
|
111
|
+
order_by=args.get("order_by"),
|
|
108
112
|
purpose=purpose,
|
|
109
113
|
requester_region=args.get("requester_region") or self._default_requester_region,
|
|
110
114
|
)
|
|
@@ -85,3 +85,77 @@ def validate_filters(value: Optional[Any]) -> Optional[list]:
|
|
|
85
85
|
)
|
|
86
86
|
|
|
87
87
|
return value
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# Analytical clauses. Only the shape is checked here; the control plane
|
|
91
|
+
# validates functions, fields and operators and returns a clear error.
|
|
92
|
+
|
|
93
|
+
def _require_list_of_dicts(name: str, value: Optional[Any]) -> Optional[list]:
|
|
94
|
+
if value is None:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
if not isinstance(value, list):
|
|
98
|
+
raise ValidationError(
|
|
99
|
+
f"{name} must be a list",
|
|
100
|
+
context=ErrorContext(raw=value),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
for item in value:
|
|
104
|
+
if not isinstance(item, dict):
|
|
105
|
+
raise ValidationError(
|
|
106
|
+
f"each {name} entry must be an object",
|
|
107
|
+
context=ErrorContext(raw=item),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
return value
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def validate_aggregates(value: Optional[Any]) -> Optional[list]:
|
|
114
|
+
value = _require_list_of_dicts("aggregates", value)
|
|
115
|
+
if value is None:
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
if not value:
|
|
119
|
+
raise ValidationError(
|
|
120
|
+
"aggregates cannot be empty",
|
|
121
|
+
context=ErrorContext(raw=value),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
for agg in value:
|
|
125
|
+
if not agg.get("func") or not agg.get("field"):
|
|
126
|
+
raise ValidationError(
|
|
127
|
+
"each aggregate needs 'func' and 'field'",
|
|
128
|
+
context=ErrorContext(raw=agg),
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return value
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def validate_group_by(value: Optional[Any]) -> Optional[list]:
|
|
135
|
+
if value is None:
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
if not isinstance(value, list) or not all(isinstance(v, str) and v.strip() for v in value):
|
|
139
|
+
raise ValidationError(
|
|
140
|
+
"group_by must be a list of field names",
|
|
141
|
+
context=ErrorContext(raw=value),
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return value
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def validate_having(value: Optional[Any]) -> Optional[list]:
|
|
148
|
+
return _require_list_of_dicts("having", value)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def validate_order_by(value: Optional[Any]) -> Optional[Dict[str, Any]]:
|
|
152
|
+
if value is None:
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
if not isinstance(value, dict) or not value.get("column"):
|
|
156
|
+
raise ValidationError(
|
|
157
|
+
"order_by must be an object with a 'column'",
|
|
158
|
+
context=ErrorContext(raw=value),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
return value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vaultkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: VaultKit Python SDK for policy-driven, runtime governed data access
|
|
5
5
|
Author-email: VaultKit <founders@vaultkit.io>
|
|
6
6
|
License: MIT
|
|
@@ -74,6 +74,37 @@ print(result.rows)
|
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
77
|
+
## Analytical Queries
|
|
78
|
+
|
|
79
|
+
Aggregate, group, filter on aggregates and sort within a single dataset:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
result = client.execute(
|
|
83
|
+
dataset="orders",
|
|
84
|
+
fields=["region"],
|
|
85
|
+
aggregates=[{"func": "sum", "field": "amount", "alias": "total"}],
|
|
86
|
+
having=[{"field": "SUM(amount)", "operator": "gt", "value": 1000}],
|
|
87
|
+
order_by={"column": "total", "direction": "desc"},
|
|
88
|
+
limit=10,
|
|
89
|
+
purpose="Quarterly revenue by region",
|
|
90
|
+
)
|
|
91
|
+
# [{"region": "US", "total": 18250}, {"region": "CA", "total": 4100}, ...]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- `aggregates`: `func` is one of `count`, `sum`, `avg`, `min`, `max`; use `field="*"` with `count`.
|
|
95
|
+
- `group_by`: optional. Defaults to `fields`; if given, it must include every entry in `fields`.
|
|
96
|
+
- `having`: needs an aggregate expression such as `SUM(amount)`, not an alias.
|
|
97
|
+
- `order_by`: a field, an aggregate alias or an aggregate expression, `asc` (default) or `desc`.
|
|
98
|
+
- `fields` can be omitted for a single total, e.g. `aggregates=[{"func": "count", "field": "*"}]`.
|
|
99
|
+
|
|
100
|
+
Policies apply to every field these clauses use. `min`/`max`/`sum`/`avg` over a masked
|
|
101
|
+
field are denied; `count` is allowed. Joins are not supported.
|
|
102
|
+
|
|
103
|
+
> Requires a VaultKit control plane with intent analytics support. Older control
|
|
104
|
+
> planes ignore these parameters and return ungrouped rows.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
77
108
|
## AI Agent Usage
|
|
78
109
|
|
|
79
110
|
VaultKit provides built-in tools for LLM agents.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|