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.
@@ -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
+ ]