contextbase-shared-plugins 0.0.0a1__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.
- contextbase_shared_plugins-0.0.0a1.dist-info/METADATA +27 -0
- contextbase_shared_plugins-0.0.0a1.dist-info/RECORD +41 -0
- contextbase_shared_plugins-0.0.0a1.dist-info/WHEEL +4 -0
- shared_plugins/__init__.py +8 -0
- shared_plugins/automation.py +11 -0
- shared_plugins/base_platform.py +105 -0
- shared_plugins/bindings.py +260 -0
- shared_plugins/dlt.py +89 -0
- shared_plugins/env.py +104 -0
- shared_plugins/exceptions.py +10 -0
- shared_plugins/google_client/__init__.py +1 -0
- shared_plugins/google_client/auth.py +108 -0
- shared_plugins/google_client/batch_retry.py +308 -0
- shared_plugins/google_client/http_errors.py +27 -0
- shared_plugins/machine_token.py +419 -0
- shared_plugins/microsoft_dataverse/__init__.py +27 -0
- shared_plugins/microsoft_dataverse/annotations.py +61 -0
- shared_plugins/microsoft_dataverse/auth.py +26 -0
- shared_plugins/microsoft_dataverse/binding_config.py +35 -0
- shared_plugins/microsoft_dataverse/client.py +468 -0
- shared_plugins/microsoft_dataverse/ctx.py +21 -0
- shared_plugins/microsoft_dataverse/identifiers.py +62 -0
- shared_plugins/microsoft_dataverse/ingress.py +53 -0
- shared_plugins/microsoft_dataverse/metadata.py +106 -0
- shared_plugins/microsoft_dataverse/runtime_schema.py +332 -0
- shared_plugins/microsoft_dataverse/source.py +299 -0
- shared_plugins/microsoft_dataverse/tables.py +34 -0
- shared_plugins/microsoft_dataverse/translators.py +133 -0
- shared_plugins/microsoft_dataverse/types.py +355 -0
- shared_plugins/microsoft_graph.py +250 -0
- shared_plugins/models.py +91 -0
- shared_plugins/naming.py +83 -0
- shared_plugins/pg_column_comments.py +59 -0
- shared_plugins/provider_token.py +238 -0
- shared_plugins/pyairbyte.py +485 -0
- shared_plugins/resources.py +179 -0
- shared_plugins/scratch.py +127 -0
- shared_plugins/sentry.py +117 -0
- shared_plugins/sqlalchemy_types.py +225 -0
- shared_plugins/sqlite.py +123 -0
- shared_plugins/values.py +117 -0
shared_plugins/values.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def as_mapping(value: object) -> Mapping[str, Any] | None:
|
|
10
|
+
if not isinstance(value, Mapping):
|
|
11
|
+
return None
|
|
12
|
+
return value
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def as_string(value: object) -> str | None:
|
|
16
|
+
if isinstance(value, str):
|
|
17
|
+
return value
|
|
18
|
+
return None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def non_empty_string(value: object) -> str | None:
|
|
22
|
+
text = as_string(value)
|
|
23
|
+
if text is None:
|
|
24
|
+
return None
|
|
25
|
+
stripped = text.strip()
|
|
26
|
+
return stripped or None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def coerce_non_empty_string_mapping(value: object) -> dict[str, str]:
|
|
30
|
+
if value is None:
|
|
31
|
+
return {}
|
|
32
|
+
if not isinstance(value, Mapping):
|
|
33
|
+
raise ValueError(
|
|
34
|
+
"Expected a mapping of non-empty string keys to non-empty string values."
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
mapping: dict[str, str] = {}
|
|
38
|
+
for key, raw_value in value.items():
|
|
39
|
+
if not isinstance(key, str) or key == "" or key != key.strip():
|
|
40
|
+
raise ValueError(
|
|
41
|
+
"Expected a mapping of non-empty string keys to non-empty string values."
|
|
42
|
+
)
|
|
43
|
+
if (
|
|
44
|
+
not isinstance(raw_value, str)
|
|
45
|
+
or raw_value == ""
|
|
46
|
+
or raw_value != raw_value.strip()
|
|
47
|
+
):
|
|
48
|
+
raise ValueError(
|
|
49
|
+
"Expected a mapping of non-empty string keys to non-empty string values."
|
|
50
|
+
)
|
|
51
|
+
mapping[key] = raw_value
|
|
52
|
+
return mapping
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def load_json_value(value: object) -> Any:
|
|
56
|
+
if isinstance(value, (dict, list)):
|
|
57
|
+
return value
|
|
58
|
+
if isinstance(value, str):
|
|
59
|
+
return json.loads(value)
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def require_non_empty_text(
|
|
64
|
+
value: object,
|
|
65
|
+
*,
|
|
66
|
+
label: str,
|
|
67
|
+
context: str = "payload",
|
|
68
|
+
) -> str:
|
|
69
|
+
if isinstance(value, str):
|
|
70
|
+
text = value.strip() or None
|
|
71
|
+
elif value is None:
|
|
72
|
+
text = None
|
|
73
|
+
else:
|
|
74
|
+
text = str(value).strip() or None
|
|
75
|
+
if text is None:
|
|
76
|
+
raise RuntimeError(f"{context} is missing required field '{label}'.")
|
|
77
|
+
return text
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def require_non_negative_int(
|
|
81
|
+
value: object,
|
|
82
|
+
*,
|
|
83
|
+
message: str = "must be a non-negative integer",
|
|
84
|
+
) -> int:
|
|
85
|
+
if value is None or isinstance(value, bool):
|
|
86
|
+
raise ValueError(message)
|
|
87
|
+
if isinstance(value, int):
|
|
88
|
+
if value >= 0:
|
|
89
|
+
return value
|
|
90
|
+
raise ValueError(message)
|
|
91
|
+
if isinstance(value, str):
|
|
92
|
+
stripped = value.strip()
|
|
93
|
+
if stripped == "":
|
|
94
|
+
raise ValueError(message)
|
|
95
|
+
try:
|
|
96
|
+
parsed = int(stripped)
|
|
97
|
+
except ValueError as exc:
|
|
98
|
+
raise ValueError(message) from exc
|
|
99
|
+
if parsed >= 0:
|
|
100
|
+
return parsed
|
|
101
|
+
raise ValueError(message)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def parse_utc_datetime_from_str(value: str) -> datetime | None:
|
|
105
|
+
if not isinstance(value, str):
|
|
106
|
+
raise TypeError(f"Expected str, got {type(value).__name__}")
|
|
107
|
+
|
|
108
|
+
text = value.strip()
|
|
109
|
+
if not text:
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
normalized = f"{text[:-1]}+00:00" if text.endswith("Z") else text
|
|
113
|
+
parsed = datetime.fromisoformat(normalized)
|
|
114
|
+
|
|
115
|
+
if parsed.tzinfo is None or parsed.utcoffset() is None:
|
|
116
|
+
return parsed.replace(tzinfo=timezone.utc)
|
|
117
|
+
return parsed.astimezone(timezone.utc)
|