whodb-sdk 0.127.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 (31) hide show
  1. whodb_sdk-0.127.0/PKG-INFO +83 -0
  2. whodb_sdk-0.127.0/README.md +63 -0
  3. whodb_sdk-0.127.0/pyproject.toml +30 -0
  4. whodb_sdk-0.127.0/setup.cfg +4 -0
  5. whodb_sdk-0.127.0/src/whodb/__init__.py +50 -0
  6. whodb_sdk-0.127.0/src/whodb/_async_ontology.py +173 -0
  7. whodb_sdk-0.127.0/src/whodb/_auth.py +122 -0
  8. whodb_sdk-0.127.0/src/whodb/_errors.py +57 -0
  9. whodb_sdk-0.127.0/src/whodb/_generated/__init__.py +2 -0
  10. whodb_sdk-0.127.0/src/whodb/_generated/hydration.py +34 -0
  11. whodb_sdk-0.127.0/src/whodb/_generated/manifest.py +81 -0
  12. whodb_sdk-0.127.0/src/whodb/_generated/operations.py +303 -0
  13. whodb_sdk-0.127.0/src/whodb/_generated/types.py +565 -0
  14. whodb_sdk-0.127.0/src/whodb/_hydrate.py +96 -0
  15. whodb_sdk-0.127.0/src/whodb/_manifest_check.py +59 -0
  16. whodb_sdk-0.127.0/src/whodb/_pagination.py +41 -0
  17. whodb_sdk-0.127.0/src/whodb/_transport.py +114 -0
  18. whodb_sdk-0.127.0/src/whodb/_transport_ipc.py +222 -0
  19. whodb_sdk-0.127.0/src/whodb/_version.py +4 -0
  20. whodb_sdk-0.127.0/src/whodb/client.py +289 -0
  21. whodb_sdk-0.127.0/src/whodb/dataset.py +52 -0
  22. whodb_sdk-0.127.0/src/whodb/ontology.py +349 -0
  23. whodb_sdk-0.127.0/src/whodb/source.py +75 -0
  24. whodb_sdk-0.127.0/src/whodb_sdk.egg-info/PKG-INFO +83 -0
  25. whodb_sdk-0.127.0/src/whodb_sdk.egg-info/SOURCES.txt +29 -0
  26. whodb_sdk-0.127.0/src/whodb_sdk.egg-info/dependency_links.txt +1 -0
  27. whodb_sdk-0.127.0/src/whodb_sdk.egg-info/requires.txt +1 -0
  28. whodb_sdk-0.127.0/src/whodb_sdk.egg-info/top_level.txt +1 -0
  29. whodb_sdk-0.127.0/tests/test_auth.py +88 -0
  30. whodb_sdk-0.127.0/tests/test_errors.py +54 -0
  31. whodb_sdk-0.127.0/tests/test_hydrate.py +47 -0
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: whodb-sdk
3
+ Version: 0.127.0
4
+ Summary: Official Python SDK for the WhoDB hosted platform — ontology, datasets, and sources as in-code function APIs
5
+ Author: Clidey, Inc.
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://whodb.com
8
+ Project-URL: Repository, https://github.com/clidey/whodb
9
+ Keywords: whodb,ontology,data,sdk
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: httpx>=0.27
20
+
21
+ # whodb-sdk
22
+
23
+ Official Python SDK for the [WhoDB](https://whodb.com) hosted platform — your
24
+ ontology, datasets, and sources as in-code function APIs.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install whodb-sdk
30
+ ```
31
+
32
+ Requires Python ≥ 3.10.
33
+
34
+ ## Quickstart
35
+
36
+ ```python
37
+ import os
38
+ from whodb import WhoDB
39
+
40
+ # Production: API key (create one in org settings → API keys).
41
+ whodb = WhoDB(api_key=os.environ["WHODB_API_KEY"])
42
+
43
+ # Local development: zero config — reuses your `whodb login` session.
44
+ # whodb = WhoDB()
45
+
46
+ users = whodb.ontology("User")
47
+
48
+ user = users.get("u_123")
49
+ active = users.list(where={"status": {"eq": "active"}}, page_size=100).all()
50
+ users.create({"email": "a@b.co"})
51
+ users.create_many(rows, idempotency_key="import-42")
52
+ users.update("u_123", {"plan": "pro"})
53
+ orders = users.follow_link("u_123", "orders").all()
54
+
55
+ # Iterate everything, page by page:
56
+ for page in users.list(page_size=500).pages():
57
+ print(len(page.rows))
58
+
59
+ # Async client:
60
+ from whodb import AsyncWhoDB
61
+ awhodb = AsyncWhoDB(api_key=os.environ["WHODB_API_KEY"])
62
+ user = await awhodb.ontology("User").get("u_123")
63
+ ```
64
+
65
+ ## Authentication
66
+
67
+ Credential precedence: constructor args (`api_key=` / `token=` /
68
+ `credentials=`) → `WHODB_API_KEY` env var → the `whodb` CLI's stored login.
69
+ Workspace (`org=` / `project=`) is optional with an API key; pass `project=`
70
+ when the key has access to more than one project.
71
+
72
+ Inside a WhoDB Function, `WhoDB()` auto-detects the runtime and needs no
73
+ configuration at all.
74
+
75
+ ## Typed clients
76
+
77
+ ```bash
78
+ whodb sdk generate --language python --out whodb_gen/
79
+ ```
80
+
81
+ ## License
82
+
83
+ Apache-2.0
@@ -0,0 +1,63 @@
1
+ # whodb-sdk
2
+
3
+ Official Python SDK for the [WhoDB](https://whodb.com) hosted platform — your
4
+ ontology, datasets, and sources as in-code function APIs.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ pip install whodb-sdk
10
+ ```
11
+
12
+ Requires Python ≥ 3.10.
13
+
14
+ ## Quickstart
15
+
16
+ ```python
17
+ import os
18
+ from whodb import WhoDB
19
+
20
+ # Production: API key (create one in org settings → API keys).
21
+ whodb = WhoDB(api_key=os.environ["WHODB_API_KEY"])
22
+
23
+ # Local development: zero config — reuses your `whodb login` session.
24
+ # whodb = WhoDB()
25
+
26
+ users = whodb.ontology("User")
27
+
28
+ user = users.get("u_123")
29
+ active = users.list(where={"status": {"eq": "active"}}, page_size=100).all()
30
+ users.create({"email": "a@b.co"})
31
+ users.create_many(rows, idempotency_key="import-42")
32
+ users.update("u_123", {"plan": "pro"})
33
+ orders = users.follow_link("u_123", "orders").all()
34
+
35
+ # Iterate everything, page by page:
36
+ for page in users.list(page_size=500).pages():
37
+ print(len(page.rows))
38
+
39
+ # Async client:
40
+ from whodb import AsyncWhoDB
41
+ awhodb = AsyncWhoDB(api_key=os.environ["WHODB_API_KEY"])
42
+ user = await awhodb.ontology("User").get("u_123")
43
+ ```
44
+
45
+ ## Authentication
46
+
47
+ Credential precedence: constructor args (`api_key=` / `token=` /
48
+ `credentials=`) → `WHODB_API_KEY` env var → the `whodb` CLI's stored login.
49
+ Workspace (`org=` / `project=`) is optional with an API key; pass `project=`
50
+ when the key has access to more than one project.
51
+
52
+ Inside a WhoDB Function, `WhoDB()` auto-detects the runtime and needs no
53
+ configuration at all.
54
+
55
+ ## Typed clients
56
+
57
+ ```bash
58
+ whodb sdk generate --language python --out whodb_gen/
59
+ ```
60
+
61
+ ## License
62
+
63
+ Apache-2.0
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "whodb-sdk"
7
+ version = "0.127.0"
8
+ description = "Official Python SDK for the WhoDB hosted platform — ontology, datasets, and sources as in-code function APIs"
9
+ readme = "README.md"
10
+ license = { text = "Apache-2.0" }
11
+ requires-python = ">=3.10"
12
+ dependencies = ["httpx>=0.27"]
13
+ authors = [{ name = "Clidey, Inc." }]
14
+ keywords = ["whodb", "ontology", "data", "sdk"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://whodb.com"
27
+ Repository = "https://github.com/clidey/whodb"
28
+
29
+ [tool.setuptools.packages.find]
30
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,50 @@
1
+ """Official Python SDK for the WhoDB hosted platform.
2
+
3
+ ```python
4
+ from whodb import WhoDB
5
+
6
+ whodb = WhoDB(api_key=os.environ["WHODB_API_KEY"])
7
+ user = whodb.ontology("User").get("u_123")
8
+ ```
9
+ """
10
+
11
+ from ._auth import CliCredentials, StaticCredentials
12
+ from ._errors import (
13
+ AuthError,
14
+ CliCredentialsError,
15
+ NotFoundError,
16
+ PlatformError,
17
+ TransportCapabilityError,
18
+ ValidationError,
19
+ WhoDBError,
20
+ WhoDBVersionError,
21
+ )
22
+ from ._pagination import ListCall, Page
23
+ from ._version import SDK_VERSION
24
+ from .client import DEFAULT_HOST, AsyncWhoDB, WhoDB
25
+ from .dataset import DatasetHandle
26
+ from .ontology import OntologyHandle
27
+ from .source import SourceHandle
28
+
29
+ __version__ = SDK_VERSION
30
+
31
+ __all__ = [
32
+ "WhoDB",
33
+ "AsyncWhoDB",
34
+ "DEFAULT_HOST",
35
+ "OntologyHandle",
36
+ "DatasetHandle",
37
+ "SourceHandle",
38
+ "ListCall",
39
+ "Page",
40
+ "WhoDBError",
41
+ "AuthError",
42
+ "NotFoundError",
43
+ "ValidationError",
44
+ "WhoDBVersionError",
45
+ "CliCredentialsError",
46
+ "TransportCapabilityError",
47
+ "PlatformError",
48
+ "StaticCredentials",
49
+ "CliCredentials",
50
+ ]
@@ -0,0 +1,173 @@
1
+ """Async twin of OntologyHandle. Same behavior, awaitable surface."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from typing import Any, AsyncIterator, Awaitable, Callable, Optional
7
+
8
+ from ._errors import NotFoundError, ValidationError
9
+ from ._generated import operations as ops
10
+ from ._hydrate import hydrate_rows, property_types_of
11
+ from ._manifest_check import warn_if_flagged
12
+ from .ontology import _DEFAULT_PAGE_SIZE, _to_record_inputs
13
+
14
+
15
+ class AsyncOntologyHandle:
16
+ """Awaitable handle for one ontology entity, addressed by apiName."""
17
+
18
+ def __init__(
19
+ self,
20
+ execute: Callable[[ops.Request], Awaitable[Any]],
21
+ project_id: Callable[[], Awaitable[str]],
22
+ api_name: str,
23
+ ):
24
+ self._execute = execute
25
+ self._project_id = project_id
26
+ self._api_name = api_name
27
+ self._entity_cache: Optional[dict] = None
28
+
29
+ async def entity_meta(self) -> dict:
30
+ """Resolve and cache the entity metadata backing this handle."""
31
+ if self._entity_cache is not None:
32
+ return self._entity_cache
33
+ warn_if_flagged("OntologyEntities")
34
+ entities = await self._execute(
35
+ ops.ontology_entities_request({"projectId": await self._project_id()})
36
+ )
37
+ entity = next((e for e in entities or [] if e.get("apiName") == self._api_name), None)
38
+ if entity is None:
39
+ raise NotFoundError(f'ontology entity "{self._api_name}" not found in this project')
40
+ self._entity_cache = entity
41
+ return entity
42
+
43
+ async def get(self, pk: Any) -> Optional[dict]:
44
+ """Fetch a single record by primary key, or None when absent."""
45
+ entity = await self.entity_meta()
46
+ primary_key = entity.get("primaryKey")
47
+ if not primary_key:
48
+ raise ValidationError(
49
+ f'entity "{self._api_name}" has no primary key — use list() with a where filter'
50
+ )
51
+ warn_if_flagged("OntologyQuery")
52
+ result = await self._execute(
53
+ ops.ontology_query_request(
54
+ {
55
+ "projectId": await self._project_id(),
56
+ "input": {
57
+ "entity": self._api_name,
58
+ "whereJson": json.dumps({primary_key: {"eq": str(pk)}}),
59
+ "pageSize": 1,
60
+ "offset": 0,
61
+ },
62
+ }
63
+ )
64
+ )
65
+ rows, _ = hydrate_rows(result, property_types_of(entity))
66
+ return rows[0] if rows else None
67
+
68
+ async def list(
69
+ self,
70
+ where: Optional[dict] = None,
71
+ sort: Optional[list[dict]] = None,
72
+ page_size: int = _DEFAULT_PAGE_SIZE,
73
+ page_offset: int = 0,
74
+ ) -> list[dict]:
75
+ """List one page of records with optional filter/sort."""
76
+ entity = await self.entity_meta()
77
+ warn_if_flagged("OntologyQuery")
78
+ result = await self._execute(
79
+ ops.ontology_query_request(
80
+ {
81
+ "projectId": await self._project_id(),
82
+ "input": {
83
+ "entity": self._api_name,
84
+ "whereJson": json.dumps(where) if where else None,
85
+ "sort": sort,
86
+ "pageSize": page_size,
87
+ "offset": page_offset,
88
+ },
89
+ }
90
+ )
91
+ )
92
+ rows, _ = hydrate_rows(result, property_types_of(entity))
93
+ return rows
94
+
95
+ async def pages(
96
+ self, where: Optional[dict] = None, page_size: int = _DEFAULT_PAGE_SIZE
97
+ ) -> AsyncIterator[list[dict]]:
98
+ """Iterate every page until a short page signals the end."""
99
+ offset = 0
100
+ while True:
101
+ rows = await self.list(where=where, page_size=page_size, page_offset=offset)
102
+ yield rows
103
+ if len(rows) < page_size:
104
+ return
105
+ offset += page_size
106
+
107
+ async def create(self, values: dict[str, Any]) -> None:
108
+ """Insert one record."""
109
+ entity = await self.entity_meta()
110
+ warn_if_flagged("OntologyAddRow")
111
+ await self._execute(
112
+ ops.ontology_add_row_request(
113
+ {
114
+ "projectId": await self._project_id(),
115
+ "entityId": entity["id"],
116
+ "values": _to_record_inputs(values),
117
+ }
118
+ )
119
+ )
120
+
121
+ async def create_many(self, rows: list[dict[str, Any]], idempotency_key: Optional[str] = None) -> dict:
122
+ """Insert many records with optional idempotency key."""
123
+ entity = await self.entity_meta()
124
+ warn_if_flagged("OntologyAddRows")
125
+ return await self._execute(
126
+ ops.ontology_add_rows_request(
127
+ {
128
+ "projectId": await self._project_id(),
129
+ "entityId": entity["id"],
130
+ "rows": [{"values": _to_record_inputs(row)} for row in rows],
131
+ "idempotencyKey": idempotency_key,
132
+ }
133
+ )
134
+ )
135
+
136
+ async def update(self, pk: Any, values: dict[str, Any]) -> None:
137
+ """Update one record identified by primary key."""
138
+ entity = await self.entity_meta()
139
+ primary_key = entity.get("primaryKey")
140
+ if not primary_key:
141
+ raise ValidationError(
142
+ f'entity "{self._api_name}" has no primary key — updates are not supported'
143
+ )
144
+ warn_if_flagged("OntologyUpdateRow")
145
+ await self._execute(
146
+ ops.ontology_update_row_request(
147
+ {
148
+ "projectId": await self._project_id(),
149
+ "entityId": entity["id"],
150
+ "values": _to_record_inputs({**values, primary_key: str(pk)}),
151
+ "updatedColumns": list(values.keys()),
152
+ }
153
+ )
154
+ )
155
+
156
+ async def delete(self, pk: Any) -> None:
157
+ """Delete one record identified by primary key."""
158
+ entity = await self.entity_meta()
159
+ primary_key = entity.get("primaryKey")
160
+ if not primary_key:
161
+ raise ValidationError(
162
+ f'entity "{self._api_name}" has no primary key — deletes are not supported'
163
+ )
164
+ warn_if_flagged("OntologyDeleteRow")
165
+ await self._execute(
166
+ ops.ontology_delete_row_request(
167
+ {
168
+ "projectId": await self._project_id(),
169
+ "entityId": entity["id"],
170
+ "values": _to_record_inputs({primary_key: str(pk)}),
171
+ }
172
+ )
173
+ )
@@ -0,0 +1,122 @@
1
+ """Credential providers, mirrored from the TypeScript SDK's auth.ts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import subprocess
7
+ from datetime import datetime, timedelta, timezone
8
+ from typing import Callable, Optional, Protocol
9
+
10
+ from ._errors import AuthError, CliCredentialsError
11
+
12
+ _CLI_REFRESH_SKEW = timedelta(seconds=60)
13
+
14
+
15
+ class CredentialProvider(Protocol):
16
+ """Yields a bearer credential; refresh() runs once after a 401."""
17
+
18
+ def token(self) -> str: ...
19
+
20
+ def refresh(self) -> None: ...
21
+
22
+ def defaults(self) -> dict:
23
+ """Workspace defaults carried by the credential source, if any."""
24
+ ...
25
+
26
+
27
+ class StaticCredentials:
28
+ """Static API-key or raw-token credentials (production/headless usage)."""
29
+
30
+ def __init__(self, value: str):
31
+ self._value = value
32
+
33
+ def token(self) -> str:
34
+ """Return the configured credential."""
35
+ return self._value
36
+
37
+ def refresh(self) -> None:
38
+ """Static credentials cannot refresh; no-op."""
39
+
40
+ def defaults(self) -> dict:
41
+ """Static credentials carry no workspace defaults."""
42
+ return {}
43
+
44
+
45
+ class CallbackCredentials:
46
+ """Caller-managed token callback."""
47
+
48
+ def __init__(self, callback: Callable[[], str]):
49
+ self._callback = callback
50
+
51
+ def token(self) -> str:
52
+ """Return a token from the caller's callback."""
53
+ return self._callback()
54
+
55
+ def refresh(self) -> None:
56
+ """The callback is consulted every call; nothing to invalidate."""
57
+
58
+ def defaults(self) -> dict:
59
+ """Callback credentials carry no workspace defaults."""
60
+ return {}
61
+
62
+
63
+ class CliCredentials:
64
+ """CLI credentials: exec `whodb auth print-token` and cache until expiry.
65
+
66
+ The gcloud-ADC pattern for local development — requires the whodb CLI on
67
+ PATH and a prior `whodb login`.
68
+ """
69
+
70
+ def __init__(self, command: str = "whodb"):
71
+ self._command = command
72
+ self._cached: Optional[dict] = None
73
+
74
+ def _exec(self) -> dict:
75
+ try:
76
+ completed = subprocess.run(
77
+ [self._command, "auth", "print-token", "--format", "json"],
78
+ capture_output=True,
79
+ timeout=15,
80
+ check=False,
81
+ )
82
+ except FileNotFoundError as exc:
83
+ raise CliCredentialsError(
84
+ "whodb CLI not found — install it or set WHODB_API_KEY"
85
+ ) from exc
86
+ if completed.returncode != 0:
87
+ detail = completed.stderr.decode(errors="replace").strip()
88
+ raise CliCredentialsError(f"whodb auth print-token failed: {detail}")
89
+ try:
90
+ return json.loads(completed.stdout)
91
+ except json.JSONDecodeError as exc:
92
+ raise CliCredentialsError("whodb auth print-token returned invalid JSON") from exc
93
+
94
+ def _is_fresh(self, entry: dict) -> bool:
95
+ expires_at = entry.get("expires_at")
96
+ if not expires_at:
97
+ return False # no expiry info — re-exec every call
98
+ expiry = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
99
+ return expiry - datetime.now(timezone.utc) > _CLI_REFRESH_SKEW
100
+
101
+ def token(self) -> str:
102
+ """Return a fresh access token, re-execing the CLI near expiry."""
103
+ if self._cached is None or not self._is_fresh(self._cached):
104
+ self._cached = self._exec()
105
+ token = self._cached.get("access_token")
106
+ if not token:
107
+ raise AuthError("whodb CLI returned an empty access token")
108
+ return token
109
+
110
+ def refresh(self) -> None:
111
+ """Drop the cached token so the next call re-execs the CLI."""
112
+ self._cached = None
113
+
114
+ def defaults(self) -> dict:
115
+ """Return the CLI's saved host/org/project defaults."""
116
+ if self._cached is None:
117
+ self._cached = self._exec()
118
+ return {
119
+ "host": self._cached.get("host"),
120
+ "org_id": self._cached.get("org_id"),
121
+ "project_id": self._cached.get("project_id"),
122
+ }
@@ -0,0 +1,57 @@
1
+ """Error taxonomy for the whodb SDK, mirrored across all SDK languages."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ class WhoDBError(Exception):
7
+ """Base class for all errors raised by the whodb SDK."""
8
+
9
+
10
+ class AuthError(WhoDBError):
11
+ """Authentication failed: missing, invalid, expired, or revoked credentials."""
12
+
13
+
14
+ class NotFoundError(WhoDBError):
15
+ """The requested resource does not exist or the caller cannot see it."""
16
+
17
+
18
+ class ValidationError(WhoDBError):
19
+ """The request was rejected as invalid before execution."""
20
+
21
+
22
+ class WhoDBVersionError(WhoDBError):
23
+ """This SDK release targets an older platform API; upgrade the package."""
24
+
25
+
26
+ class CliCredentialsError(WhoDBError):
27
+ """The whodb CLI credential helper is unavailable or not logged in."""
28
+
29
+
30
+ class TransportCapabilityError(WhoDBError):
31
+ """An operation is not available over the current transport (e.g. IPC)."""
32
+
33
+
34
+ class PlatformError(WhoDBError):
35
+ """Any other platform-reported error, carrying the GraphQL error code."""
36
+
37
+ def __init__(self, message: str, code: str):
38
+ super().__init__(message)
39
+ self.code = code
40
+
41
+
42
+ def map_graphql_errors(errors: list[dict]) -> WhoDBError:
43
+ """Map a GraphQL errors array to the SDK error taxonomy.
44
+
45
+ The first error decides the type; its code is preserved on PlatformError
46
+ for callers that need to branch on specifics.
47
+ """
48
+ first = errors[0] if errors else {"message": "unknown platform error"}
49
+ code = (first.get("extensions") or {}).get("code", "")
50
+ message = first.get("message", "unknown platform error")
51
+ if code in ("UNAUTHENTICATED", "FORBIDDEN"):
52
+ return AuthError(message)
53
+ if code == "NOT_FOUND":
54
+ return NotFoundError(message)
55
+ if code in ("BAD_USER_INPUT", "GRAPHQL_VALIDATION_FAILED"):
56
+ return ValidationError(message)
57
+ return PlatformError(message, code)
@@ -0,0 +1,2 @@
1
+ # GENERATED by sdk/tools/generate-core.mjs — DO NOT EDIT (manifest 4b84678f5fe7)
2
+ """Generated wire core for the whodb SDK. Do not import directly."""
@@ -0,0 +1,34 @@
1
+ # GENERATED by sdk/tools/generate-core.mjs — DO NOT EDIT (manifest 4b84678f5fe7)
2
+ """Column-type → coercion kind rules shared across all SDK languages."""
3
+
4
+ HYDRATION_RULES = {
5
+ "int": "int",
6
+ "integer": "int",
7
+ "bigint": "int",
8
+ "smallint": "int",
9
+ "int2": "int",
10
+ "int4": "int",
11
+ "int8": "int",
12
+ "serial": "int",
13
+ "bigserial": "int",
14
+ "float": "float",
15
+ "float4": "float",
16
+ "float8": "float",
17
+ "double": "float",
18
+ "double precision": "float",
19
+ "real": "float",
20
+ "numeric": "float",
21
+ "decimal": "float",
22
+ "bool": "bool",
23
+ "boolean": "bool",
24
+ "timestamp": "timestamp",
25
+ "timestamptz": "timestamp",
26
+ "timestamp with time zone": "timestamp",
27
+ "timestamp without time zone": "timestamp",
28
+ "datetime": "timestamp",
29
+ "date": "date",
30
+ "json": "json",
31
+ "jsonb": "json"
32
+ }
33
+
34
+ HYDRATION_DEFAULT = "string"