vaultkit 0.3.0__tar.gz → 0.3.1__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 (41) hide show
  1. {vaultkit-0.3.0 → vaultkit-0.3.1}/PKG-INFO +1 -1
  2. {vaultkit-0.3.0 → vaultkit-0.3.1}/pyproject.toml +1 -1
  3. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/__init__.py +1 -1
  4. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/client.py +2 -0
  5. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/core/http.py +1 -0
  6. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/errors/exceptions.py +6 -1
  7. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/models/fetch_result.py +12 -1
  8. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/executor.py +11 -6
  9. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit.egg-info/PKG-INFO +1 -1
  10. {vaultkit-0.3.0 → vaultkit-0.3.1}/README.md +0 -0
  11. {vaultkit-0.3.0 → vaultkit-0.3.1}/setup.cfg +0 -0
  12. {vaultkit-0.3.0 → vaultkit-0.3.1}/tests/test_fetch.py +0 -0
  13. {vaultkit-0.3.0 → vaultkit-0.3.1}/tests/test_query.py +0 -0
  14. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/core/__init__.py +0 -0
  15. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/core/polling.py +0 -0
  16. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/errors/__init__.py +0 -0
  17. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/errors/base.py +0 -0
  18. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/mcp/__init__.py +0 -0
  19. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/mcp/__main__.py +0 -0
  20. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/mcp/identity.py +0 -0
  21. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/mcp/server.py +0 -0
  22. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/models/__init__.py +0 -0
  23. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/models/dataset_info.py +0 -0
  24. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/models/dataset_schema.py +0 -0
  25. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/models/query_result.py +0 -0
  26. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/__init__.py +0 -0
  27. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/adapters/__init__.py +0 -0
  28. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/adapters/anthropic.py +0 -0
  29. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/adapters/mcp.py +0 -0
  30. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/adapters/openai.py +0 -0
  31. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/builder.py +0 -0
  32. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/definitions.py +0 -0
  33. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/tools/schemas.py +0 -0
  34. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/utils/__init__.py +0 -0
  35. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/utils/retry.py +0 -0
  36. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit/utils/validation.py +0 -0
  37. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit.egg-info/SOURCES.txt +0 -0
  38. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit.egg-info/dependency_links.txt +0 -0
  39. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit.egg-info/entry_points.txt +0 -0
  40. {vaultkit-0.3.0 → vaultkit-0.3.1}/vaultkit.egg-info/requires.txt +0 -0
  41. {vaultkit-0.3.0 → vaultkit-0.3.1}/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.0
3
+ Version: 0.3.1
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "vaultkit"
7
- version = "0.3.0"
7
+ version = "0.3.1"
8
8
  description = "VaultKit Python SDK for policy-driven, runtime governed data access"
9
9
  authors = [
10
10
  { name = "VaultKit", email = "founders@vaultkit.io" }
@@ -53,7 +53,7 @@ from .models import (
53
53
  # Optional (nice DX improvement)
54
54
  from .tools import ToolBuilder, ToolExecutor
55
55
 
56
- __version__ = "0.3.0"
56
+ __version__ = "0.3.1"
57
57
 
58
58
  __all__ = [
59
59
  "VaultKitClient",
@@ -190,6 +190,7 @@ class VaultKitClient:
190
190
  raise DeniedError(
191
191
  result.reason or "Request denied by policy",
192
192
  policy_id=result.policy_id,
193
+ reason=result.reason,
193
194
  )
194
195
 
195
196
  # Case 1: data already returned (reuse path)
@@ -315,6 +316,7 @@ class VaultKitClient:
315
316
  raise DeniedError(
316
317
  result.reason or "Request denied",
317
318
  policy_id=result.policy_id,
319
+ reason=result.reason,
318
320
  )
319
321
  if result.is_pending and not poll:
320
322
  raise QueuedError(
@@ -166,6 +166,7 @@ class HttpClient:
166
166
  raw.get("error")
167
167
  or raw.get("message")
168
168
  or raw.get("detail")
169
+ or raw.get("reason")
169
170
  or msg
170
171
  )
171
172
  except Exception:
@@ -62,10 +62,12 @@ class DeniedError(VaultKitError):
62
62
  message: str,
63
63
  *,
64
64
  policy_id: Optional[str] = None,
65
+ reason: Optional[str] = None,
65
66
  context: Optional[ErrorContext] = None,
66
67
  ) -> None:
67
68
  super().__init__(message, context=context)
68
69
  self.policy_id = policy_id
70
+ self.reason = reason or message
69
71
 
70
72
 
71
73
  class QueuedError(VaultKitError):
@@ -185,10 +187,13 @@ def map_http_error(status_code: int, message: str, *, context: ErrorContext) ->
185
187
  return AuthError(message, context=context)
186
188
 
187
189
  if status_code == 403:
188
- if error_type == "policy_denied":
190
+ # The intent API answers a denial with {"status": "denied", "policy_id", "reason"};
191
+ # older backends sent {"type": "policy_denied"}.
192
+ if error_type == "policy_denied" or raw.get("status") == "denied":
189
193
  return DeniedError(
190
194
  message,
191
195
  policy_id=raw.get("policy_id"),
196
+ reason=raw.get("reason"),
192
197
  context=context,
193
198
  )
194
199
  return ForbiddenError(message, context=context)
@@ -42,12 +42,23 @@ class FetchResult:
42
42
  @property
43
43
  def masked_fields(self) -> List[str]:
44
44
  """
45
- Masked field names from meta, if your API returns them there.
45
+ Masked field names from meta.
46
+
47
+ funl sends meta.masked_fields as a map of field -> mask method
48
+ ({"email": "partial"}); a plain list of names is also accepted.
46
49
  Returns [] safely if meta is absent or has no masked_fields key.
47
50
  """
48
51
  value = (self.meta or {}).get("masked_fields")
52
+ if isinstance(value, dict):
53
+ return list(value.keys())
49
54
  return value if isinstance(value, list) else []
50
55
 
56
+ @property
57
+ def masking_methods(self) -> Dict[str, str]:
58
+ """Mask method per masked field, e.g. {"email": "partial"}. Empty if the API sent a list."""
59
+ value = (self.meta or {}).get("masked_fields")
60
+ return dict(value) if isinstance(value, dict) else {}
61
+
51
62
  @property
52
63
  def is_empty(self) -> bool:
53
64
  return not self.rows
@@ -86,7 +86,6 @@ class ToolExecutor:
86
86
  "name": d.dataset,
87
87
  "datasource": d.datasource,
88
88
  "visibility": visibility_map.get(getattr(d, "visibility", None), getattr(d, "visibility", None)),
89
- "field_count": len(getattr(d, "fields", []) or []),
90
89
  }
91
90
  for d in datasets
92
91
  ],
@@ -121,6 +120,7 @@ class ToolExecutor:
121
120
  }
122
121
 
123
122
  if result.masked_fields:
123
+ response["masked_fields"] = result.masked_fields
124
124
  response["note"] = f"Fields {result.masked_fields} were masked per data policy."
125
125
 
126
126
  return response
@@ -158,12 +158,17 @@ class ToolExecutor:
158
158
 
159
159
  if isinstance(exc, DeniedError):
160
160
  policy_id = getattr(exc, "policy_id", None)
161
+ reason = getattr(exc, "reason", None) or exc.message
161
162
  extra = f" (policy_id={policy_id})" if policy_id else ""
162
- return self._error(
163
- f"Access denied by VaultKit policy{extra}. Reason: {msg}. "
164
- "Do not retry — this denial is deterministic.",
165
- code="denied",
166
- )
163
+ return {
164
+ "status": "denied",
165
+ "reason": reason,
166
+ "policy_id": policy_id,
167
+ "error": (
168
+ f"Access denied by VaultKit policy{extra}. Reason: {reason}. "
169
+ "Do not retry — this denial is deterministic."
170
+ ),
171
+ }
167
172
 
168
173
  if isinstance(exc, ApprovalRequiredError):
169
174
  return {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vaultkit
3
- Version: 0.3.0
3
+ Version: 0.3.1
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
File without changes
File without changes
File without changes
File without changes