hotdata-runtime 0.1.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.
- hotdata_runtime-0.1.0/.github/workflows/publish.yml +70 -0
- hotdata_runtime-0.1.0/.gitignore +50 -0
- hotdata_runtime-0.1.0/CONTRACT.md +92 -0
- hotdata_runtime-0.1.0/PKG-INFO +48 -0
- hotdata_runtime-0.1.0/README.md +38 -0
- hotdata_runtime-0.1.0/examples/basic_usage.py +25 -0
- hotdata_runtime-0.1.0/hotdata_runtime/__init__.py +47 -0
- hotdata_runtime-0.1.0/hotdata_runtime/client.py +341 -0
- hotdata_runtime-0.1.0/hotdata_runtime/env.py +81 -0
- hotdata_runtime-0.1.0/hotdata_runtime/health.py +27 -0
- hotdata_runtime-0.1.0/hotdata_runtime/http.py +19 -0
- hotdata_runtime-0.1.0/hotdata_runtime/result.py +75 -0
- hotdata_runtime-0.1.0/pyproject.toml +30 -0
- hotdata_runtime-0.1.0/tests/test_client.py +231 -0
- hotdata_runtime-0.1.0/tests/test_contract.py +50 -0
- hotdata_runtime-0.1.0/tests/test_health.py +64 -0
- hotdata_runtime-0.1.0/tests/test_result.py +37 -0
- hotdata_runtime-0.1.0/tests/test_version.py +13 -0
- hotdata_runtime-0.1.0/uv.lock +677 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v[0-9]*'
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: pypi-publish-${{ github.ref_name }}
|
|
10
|
+
cancel-in-progress: false
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
name: Build distribution
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.12'
|
|
25
|
+
|
|
26
|
+
- name: Install build tooling
|
|
27
|
+
run: python -m pip install --upgrade build twine
|
|
28
|
+
|
|
29
|
+
- name: Verify tag matches pyproject version
|
|
30
|
+
run: |
|
|
31
|
+
# Release tags must start with `v` followed by a PEP 440 version (e.g. v1.2.3, v1.2.3a1).
|
|
32
|
+
if [[ ! "$GITHUB_REF_NAME" =~ ^v[0-9] ]]; then
|
|
33
|
+
echo "Release tag '$GITHUB_REF_NAME' must start with 'v' followed by a digit (e.g. v1.0.0)" >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
37
|
+
pkg_version=$(python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
|
|
38
|
+
if [ "$tag" != "$pkg_version" ]; then
|
|
39
|
+
echo "Release tag ($tag) does not match pyproject.toml version ($pkg_version)" >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
- name: Build sdist and wheel
|
|
44
|
+
run: python -m build
|
|
45
|
+
|
|
46
|
+
- name: Check distribution metadata
|
|
47
|
+
run: python -m twine check --strict dist/*
|
|
48
|
+
|
|
49
|
+
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
|
|
50
|
+
with:
|
|
51
|
+
name: dist
|
|
52
|
+
path: dist/
|
|
53
|
+
|
|
54
|
+
publish:
|
|
55
|
+
name: Publish to PyPI
|
|
56
|
+
needs: build
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
environment:
|
|
59
|
+
name: pypi
|
|
60
|
+
url: https://pypi.org/p/hotdata-runtime
|
|
61
|
+
permissions:
|
|
62
|
+
id-token: write
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
|
|
65
|
+
with:
|
|
66
|
+
name: dist
|
|
67
|
+
path: dist/
|
|
68
|
+
|
|
69
|
+
- name: Publish via Trusted Publishing
|
|
70
|
+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution / packaging
|
|
8
|
+
.Python
|
|
9
|
+
build/
|
|
10
|
+
develop-eggs/
|
|
11
|
+
dist/
|
|
12
|
+
downloads/
|
|
13
|
+
eggs/
|
|
14
|
+
.eggs/
|
|
15
|
+
lib/
|
|
16
|
+
lib64/
|
|
17
|
+
parts/
|
|
18
|
+
sdist/
|
|
19
|
+
var/
|
|
20
|
+
wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
|
|
25
|
+
# Virtual environments
|
|
26
|
+
.env
|
|
27
|
+
.venv
|
|
28
|
+
env/
|
|
29
|
+
venv/
|
|
30
|
+
ENV/
|
|
31
|
+
|
|
32
|
+
# Testing / coverage
|
|
33
|
+
.tox/
|
|
34
|
+
.nox/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
.cache
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
htmlcov/
|
|
40
|
+
|
|
41
|
+
# Type checkers
|
|
42
|
+
.mypy_cache/
|
|
43
|
+
.pyright/
|
|
44
|
+
.ruff_cache/
|
|
45
|
+
|
|
46
|
+
# IDEs
|
|
47
|
+
.idea/
|
|
48
|
+
.vscode/
|
|
49
|
+
*.swp
|
|
50
|
+
.DS_Store
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# hotdata-runtime Contract
|
|
2
|
+
|
|
3
|
+
`hotdata-runtime` is the framework-agnostic runtime contract for Hotdata integrations.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
This package provides shared primitives for:
|
|
8
|
+
|
|
9
|
+
- Environment and workspace resolution
|
|
10
|
+
- Query execution and polling
|
|
11
|
+
- Normalized tabular result handling
|
|
12
|
+
- Basic workspace health checks
|
|
13
|
+
|
|
14
|
+
## Public Runtime Contract
|
|
15
|
+
|
|
16
|
+
The supported import surface is:
|
|
17
|
+
|
|
18
|
+
- `HotdataClient`
|
|
19
|
+
- `QueryResult`
|
|
20
|
+
- `from_env`
|
|
21
|
+
- `workspace_health_lines`
|
|
22
|
+
- `default_api_key`
|
|
23
|
+
- `default_host`
|
|
24
|
+
- `default_session_id`
|
|
25
|
+
- `explicit_workspace_id`
|
|
26
|
+
- `list_workspaces`
|
|
27
|
+
- `normalize_host`
|
|
28
|
+
- `pick_workspace`
|
|
29
|
+
- `resolve_workspace_selection`
|
|
30
|
+
- `ResultSummary`
|
|
31
|
+
- `RunHistoryItem`
|
|
32
|
+
- `WorkspaceSelection`
|
|
33
|
+
|
|
34
|
+
Adapters should import from `hotdata_runtime` and treat this surface as the stable API.
|
|
35
|
+
|
|
36
|
+
## Semantic Guarantees
|
|
37
|
+
|
|
38
|
+
### `HotdataClient`
|
|
39
|
+
|
|
40
|
+
- Represents runtime context: API key, host, workspace, optional session.
|
|
41
|
+
- `from_env()` resolves runtime context from env vars and selected workspace.
|
|
42
|
+
- `execute_sql(sql)` returns `QueryResult` or raises `RuntimeError`/`TimeoutError`.
|
|
43
|
+
- `get_result(result_id)` returns a ready `QueryResult` and waits for readiness when needed.
|
|
44
|
+
- `connections()` returns the connections API wrapper for adapter UI/status features.
|
|
45
|
+
- `query_runs()` returns the query-runs API wrapper for adapter history views.
|
|
46
|
+
- `results()` returns the results API wrapper for adapter result pickers.
|
|
47
|
+
- `list_recent_results(...)` returns normalized `ResultSummary` entries.
|
|
48
|
+
- `list_run_history(limit=...)` returns normalized `RunHistoryItem` entries.
|
|
49
|
+
- `list_qualified_table_names(...)` returns sorted fully qualified table names.
|
|
50
|
+
- `columns_for_qualified(qualified, connection_id=...)` resolves table columns, and
|
|
51
|
+
adapters should pass `connection_id` when known.
|
|
52
|
+
|
|
53
|
+
### `QueryResult`
|
|
54
|
+
|
|
55
|
+
- Canonical tabular result model with `columns`, `rows`, and `row_count`.
|
|
56
|
+
- Carries server identifiers and execution metadata when available.
|
|
57
|
+
- `to_pandas()` converts to a DataFrame with stable column ordering.
|
|
58
|
+
- `to_records(max_rows=...)` returns row dicts keyed by column names.
|
|
59
|
+
- `metadata_dict()` returns normalized result metadata for adapter rendering.
|
|
60
|
+
|
|
61
|
+
### Env Resolution
|
|
62
|
+
|
|
63
|
+
- `default_api_key()` reads `HOTDATA_API_KEY`.
|
|
64
|
+
- `default_host()` reads `HOTDATA_API_URL` (default: `https://api.hotdata.dev`) and normalizes it.
|
|
65
|
+
- `default_session_id()` reads `HOTDATA_SANDBOX`.
|
|
66
|
+
- `explicit_workspace_id()` reads `HOTDATA_WORKSPACE` (workspace public id).
|
|
67
|
+
- `pick_workspace()` prefers explicit env workspace, then active workspace, then first workspace.
|
|
68
|
+
- `resolve_workspace_selection()` is the canonical workspace selection algorithm. It returns `WorkspaceSelection` with selected workspace id, selection source, and discovered workspaces when auto-selected.
|
|
69
|
+
|
|
70
|
+
## Adapter Responsibilities
|
|
71
|
+
|
|
72
|
+
Framework packages (Jupyter, Marimo, LangChain, LangGraph, LlamaIndex, Streamlit) own:
|
|
73
|
+
|
|
74
|
+
- Framework-native lifecycle and state management
|
|
75
|
+
- Rendering/UI concerns
|
|
76
|
+
- Tool/agent wrappers and callback integration
|
|
77
|
+
|
|
78
|
+
They should not duplicate runtime env/workspace/query semantics.
|
|
79
|
+
|
|
80
|
+
## Runtime Non-Goals
|
|
81
|
+
|
|
82
|
+
`hotdata-runtime` does not define framework UI primitives and does not require framework dependencies.
|
|
83
|
+
|
|
84
|
+
## Versioning Policy
|
|
85
|
+
|
|
86
|
+
- Backward-incompatible contract changes require a major version bump.
|
|
87
|
+
- Additive contract changes are minor versions.
|
|
88
|
+
- Bug fixes that preserve contract semantics are patch versions.
|
|
89
|
+
|
|
90
|
+
## Enforcement
|
|
91
|
+
|
|
92
|
+
Contract stability is enforced by tests that verify the public export surface and key behavioral invariants.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hotdata-runtime
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Workspace/session runtime primitives for Hotdata integrations
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: hotdata>=0.1.0
|
|
8
|
+
Requires-Dist: pandas>=2.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# hotdata-runtime
|
|
12
|
+
|
|
13
|
+
Shared runtime primitives for Hotdata integrations: workspace/session semantics, execution context, query state, run history, and replayable result handles. Framework packages (Marimo, Jupyter, Streamlit, LangGraph) depend on this package.
|
|
14
|
+
|
|
15
|
+
Runtime boundary and guarantees are defined in `CONTRACT.md`.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **Environment-driven client setup** — create clients from `HOTDATA_API_KEY`, optional `HOTDATA_API_URL`, `HOTDATA_WORKSPACE`, and `HOTDATA_SANDBOX`.
|
|
20
|
+
- **Workspace resolution** — choose an explicit workspace from env, otherwise discover workspaces and select the active workspace or first available workspace.
|
|
21
|
+
- **Sandbox/session propagation** — pass sandbox session context through the SDK via `X-Session-Id`.
|
|
22
|
+
- **HTTP resilience** — configure SDK retries for transient connection failures and retry SQL execution on stale pooled sockets.
|
|
23
|
+
- **SQL execution helper** — run SQL through `POST /v1/query`, poll async query runs when needed, and return a `QueryResult`.
|
|
24
|
+
- **Result utilities** — convert query results to records, pandas DataFrames, or metadata dictionaries for adapter display layers.
|
|
25
|
+
- **History helpers** — list recent results and query run history with normalized dataclasses.
|
|
26
|
+
- **Health helpers** — build compact API/workspace health summaries for UI integrations.
|
|
27
|
+
|
|
28
|
+
Install:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv pip install hotdata-runtime
|
|
32
|
+
# or: pip install hotdata-runtime
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
python examples/basic_usage.py
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Development (uses **uv**; creates `.venv/` in this repo):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uv sync --locked
|
|
45
|
+
uv run pytest
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`uv.lock` is checked in so CI can run `uv sync --locked`. The default **dev** group (pytest) is enabled via `[tool.uv] default-groups`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# hotdata-runtime
|
|
2
|
+
|
|
3
|
+
Shared runtime primitives for Hotdata integrations: workspace/session semantics, execution context, query state, run history, and replayable result handles. Framework packages (Marimo, Jupyter, Streamlit, LangGraph) depend on this package.
|
|
4
|
+
|
|
5
|
+
Runtime boundary and guarantees are defined in `CONTRACT.md`.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Environment-driven client setup** — create clients from `HOTDATA_API_KEY`, optional `HOTDATA_API_URL`, `HOTDATA_WORKSPACE`, and `HOTDATA_SANDBOX`.
|
|
10
|
+
- **Workspace resolution** — choose an explicit workspace from env, otherwise discover workspaces and select the active workspace or first available workspace.
|
|
11
|
+
- **Sandbox/session propagation** — pass sandbox session context through the SDK via `X-Session-Id`.
|
|
12
|
+
- **HTTP resilience** — configure SDK retries for transient connection failures and retry SQL execution on stale pooled sockets.
|
|
13
|
+
- **SQL execution helper** — run SQL through `POST /v1/query`, poll async query runs when needed, and return a `QueryResult`.
|
|
14
|
+
- **Result utilities** — convert query results to records, pandas DataFrames, or metadata dictionaries for adapter display layers.
|
|
15
|
+
- **History helpers** — list recent results and query run history with normalized dataclasses.
|
|
16
|
+
- **Health helpers** — build compact API/workspace health summaries for UI integrations.
|
|
17
|
+
|
|
18
|
+
Install:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv pip install hotdata-runtime
|
|
22
|
+
# or: pip install hotdata-runtime
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python examples/basic_usage.py
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Development (uses **uv**; creates `.venv/` in this repo):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv sync --locked
|
|
35
|
+
uv run pytest
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`uv.lock` is checked in so CI can run `uv sync --locked`. The default **dev** group (pytest) is enabled via `[tool.uv] default-groups`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Basic hotdata-runtime usage."""
|
|
2
|
+
|
|
3
|
+
from hotdata_runtime import from_env
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main() -> None:
|
|
7
|
+
client = from_env()
|
|
8
|
+
result = client.execute_sql("SELECT 1 AS ok")
|
|
9
|
+
|
|
10
|
+
print("result metadata:", result.metadata_dict())
|
|
11
|
+
print("records:", result.to_records(max_rows=5))
|
|
12
|
+
|
|
13
|
+
print("recent results:")
|
|
14
|
+
for item in client.list_recent_results(limit=5, offset=0):
|
|
15
|
+
print(item.to_dict())
|
|
16
|
+
|
|
17
|
+
print("run history:")
|
|
18
|
+
for item in client.list_run_history(limit=5):
|
|
19
|
+
print(item.to_dict())
|
|
20
|
+
|
|
21
|
+
client.close()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Hotdata runtime primitives for notebook and app integrations."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
from hotdata_runtime.client import (
|
|
6
|
+
HotdataClient,
|
|
7
|
+
ResultSummary,
|
|
8
|
+
RunHistoryItem,
|
|
9
|
+
from_env,
|
|
10
|
+
)
|
|
11
|
+
from hotdata_runtime.env import (
|
|
12
|
+
default_api_key,
|
|
13
|
+
default_host,
|
|
14
|
+
default_session_id,
|
|
15
|
+
explicit_workspace_id,
|
|
16
|
+
list_workspaces,
|
|
17
|
+
normalize_host,
|
|
18
|
+
pick_workspace,
|
|
19
|
+
resolve_workspace_selection,
|
|
20
|
+
WorkspaceSelection,
|
|
21
|
+
)
|
|
22
|
+
from hotdata_runtime.health import workspace_health_lines
|
|
23
|
+
from hotdata_runtime.result import QueryResult
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
__version__ = version("hotdata-runtime")
|
|
27
|
+
except PackageNotFoundError:
|
|
28
|
+
__version__ = "0.0.0+unknown"
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"__version__",
|
|
32
|
+
"HotdataClient",
|
|
33
|
+
"QueryResult",
|
|
34
|
+
"workspace_health_lines",
|
|
35
|
+
"default_api_key",
|
|
36
|
+
"default_host",
|
|
37
|
+
"default_session_id",
|
|
38
|
+
"explicit_workspace_id",
|
|
39
|
+
"from_env",
|
|
40
|
+
"list_workspaces",
|
|
41
|
+
"normalize_host",
|
|
42
|
+
"pick_workspace",
|
|
43
|
+
"resolve_workspace_selection",
|
|
44
|
+
"ResultSummary",
|
|
45
|
+
"RunHistoryItem",
|
|
46
|
+
"WorkspaceSelection",
|
|
47
|
+
]
|