hotdata-framework 0.4.1__tar.gz → 0.6.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 (38) hide show
  1. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/CHANGELOG.md +11 -0
  2. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/PKG-INFO +2 -2
  3. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/client.py +28 -0
  4. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/pyproject.toml +2 -2
  5. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_client.py +29 -0
  6. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/uv.lock +5 -5
  7. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.github/dependabot.yml +0 -0
  8. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.github/workflows/check-release.yml +0 -0
  9. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.github/workflows/ci.yml +0 -0
  10. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.github/workflows/dependabot-automerge.yml +0 -0
  11. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.github/workflows/publish.yml +0 -0
  12. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.github/workflows/release.yml +0 -0
  13. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/.gitignore +0 -0
  14. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/CONTRACT.md +0 -0
  15. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/README.md +0 -0
  16. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/RELEASING.md +0 -0
  17. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/examples/basic_usage.py +0 -0
  18. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/__init__.py +0 -0
  19. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/databases.py +0 -0
  20. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/env.py +0 -0
  21. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/errors.py +0 -0
  22. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/health.py +0 -0
  23. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/http.py +0 -0
  24. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/managed_client.py +0 -0
  25. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/py.typed +0 -0
  26. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/hotdata_framework/result.py +0 -0
  27. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/scripts/check-release.py +0 -0
  28. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/scripts/extract-changelog.py +0 -0
  29. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/scripts/publish-workflow.sh +0 -0
  30. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/scripts/release.sh +0 -0
  31. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/scripts/update_changelog.py +0 -0
  32. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_contract.py +0 -0
  33. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_databases.py +0 -0
  34. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_health.py +0 -0
  35. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_managed_client.py +0 -0
  36. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_result.py +0 -0
  37. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_update_changelog.py +0 -0
  38. {hotdata_framework-0.4.1 → hotdata_framework-0.6.0}/tests/test_version.py +0 -0
@@ -8,6 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
 
10
10
 
11
+ ## [0.6.0] - 2026-06-30
12
+
13
+ ### Added
14
+
15
+ - `HotdataClient.add_managed_table(database, table, *, schema)` declares a new table on an existing managed database (wrapping the SDK `add_database_table` endpoint). This allows additive schema evolution without recreating the database.
16
+
17
+ ## [0.5.0] - 2026-06-28
18
+
19
+ ### Changed
20
+
21
+ - Adopt the `hotdata` 0.5.0 SDK surface (dependency bumped from `>=0.4.1` to `>=0.5.0`). The release is backward compatible for everything the framework uses; the only API changes are additive (a new optional `format` field on `LoadManagedTableRequest` and an optional `format` parameter on `ResultsApi.get_result`), so no framework code changes were required.
11
22
 
12
23
  ## [0.4.1] - 2026-06-26
13
24
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hotdata-framework
3
- Version: 0.4.1
3
+ Version: 0.6.0
4
4
  Summary: Python framework for building Hotdata integrations: workspace/session runtime, query execution, and managed databases
5
5
  Project-URL: Homepage, https://www.hotdata.dev
6
6
  Project-URL: Documentation, https://www.hotdata.dev/docs
@@ -21,7 +21,7 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Classifier: Typing :: Typed
23
23
  Requires-Python: >=3.10
24
- Requires-Dist: hotdata>=0.4.1
24
+ Requires-Dist: hotdata>=0.5.0
25
25
  Requires-Dist: pandas>=2.0
26
26
  Requires-Dist: pyarrow>=14.0
27
27
  Description-Content-Type: text/markdown
@@ -14,6 +14,7 @@ from hotdata.api.query_runs_api import QueryRunsApi
14
14
  from hotdata.api.results_api import ResultsApi
15
15
  from hotdata.api.uploads_api import UploadsApi
16
16
  from hotdata.exceptions import ApiException
17
+ from hotdata.models.add_managed_table_request import AddManagedTableRequest
17
18
  from hotdata.models.async_query_response import AsyncQueryResponse
18
19
  from hotdata.models.create_database_request import CreateDatabaseRequest
19
20
  from hotdata.models.database_default_schema_decl import DatabaseDefaultSchemaDecl
@@ -300,6 +301,33 @@ class HotdataClient:
300
301
  full_name=f"{db.id}.{loaded.schema_name}.{loaded.table_name}",
301
302
  )
302
303
 
304
+ def add_managed_table(
305
+ self,
306
+ database: str,
307
+ table: str,
308
+ *,
309
+ schema: str = DEFAULT_SCHEMA,
310
+ ) -> ManagedTable:
311
+ """Declare a new table on an existing managed database.
312
+
313
+ The table is added empty (declared-but-unloaded); populate it with
314
+ :meth:`load_managed_table`. Use this to evolve a managed database's
315
+ schema after creation without recreating it.
316
+ """
317
+ db = self.resolve_managed_database(database)
318
+ request = AddManagedTableRequest(name=table)
319
+ try:
320
+ self._databases_api().add_database_table(db.id, schema, request)
321
+ except ApiException as e:
322
+ raise RuntimeError(api_error_message(e)) from e
323
+ return ManagedTable(
324
+ full_name=f"{db.id}.{schema}.{table}",
325
+ schema=schema,
326
+ table=table,
327
+ synced=False,
328
+ last_sync=None,
329
+ )
330
+
303
331
  def delete_managed_table(
304
332
  self,
305
333
  database: str,
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "hotdata-framework"
7
- version = "0.4.1"
7
+ version = "0.6.0"
8
8
  description = "Python framework for building Hotdata integrations: workspace/session runtime, query execution, and managed databases"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -26,7 +26,7 @@ classifiers = [
26
26
  "Typing :: Typed",
27
27
  ]
28
28
  dependencies = [
29
- "hotdata>=0.4.1",
29
+ "hotdata>=0.5.0",
30
30
  "pandas>=2.0",
31
31
  "pyarrow>=14.0",
32
32
  ]
@@ -178,6 +178,35 @@ def test_columns_for_qualified_prefers_explicit_connection_id():
178
178
  assert fake_api.kwargs["connection_id"] == "conn_explicit"
179
179
 
180
180
 
181
+ def test_add_managed_table_declares_table_on_existing_database():
182
+ client = HotdataClient("k", "ws", host="https://api.hotdata.dev")
183
+ fake_db = SimpleNamespace(id="db_1", default_connection_id="conn")
184
+
185
+ class FakeDatabasesApi:
186
+ def __init__(self):
187
+ self.calls: list[tuple[str, str, str]] = []
188
+
189
+ def add_database_table(self, database_id, var_schema, request):
190
+ self.calls.append((database_id, var_schema, request.name))
191
+ return SimpleNamespace(
192
+ connection_id="conn", var_schema=var_schema, table=request.name
193
+ )
194
+
195
+ fake_api = FakeDatabasesApi()
196
+ with (
197
+ patch.object(client, "resolve_managed_database", return_value=fake_db),
198
+ patch.object(client, "_databases_api", return_value=fake_api),
199
+ ):
200
+ result = client.add_managed_table("mydb", "orders", schema="public")
201
+
202
+ assert fake_api.calls == [("db_1", "public", "orders")]
203
+ assert result.full_name == "db_1.public.orders"
204
+ assert result.schema == "public"
205
+ assert result.table == "orders"
206
+ assert result.synced is False
207
+ assert result.last_sync is None
208
+
209
+
181
210
  def test_list_recent_results_returns_normalized_summaries():
182
211
  client = HotdataClient("k", "ws", host="https://api.hotdata.dev")
183
212
  listing = SimpleNamespace(
@@ -86,7 +86,7 @@ wheels = [
86
86
 
87
87
  [[package]]
88
88
  name = "hotdata"
89
- version = "0.4.1"
89
+ version = "0.5.0"
90
90
  source = { registry = "https://pypi.org/simple" }
91
91
  dependencies = [
92
92
  { name = "pydantic" },
@@ -94,14 +94,14 @@ dependencies = [
94
94
  { name = "typing-extensions" },
95
95
  { name = "urllib3" },
96
96
  ]
97
- sdist = { url = "https://files.pythonhosted.org/packages/10/f8/397b2fa161e74abb115283fc169b2abe7455022cc53e1119f0fee80969d2/hotdata-0.4.1.tar.gz", hash = "sha256:e123d267872178f4dd6c8337ac47cf6616984685aca3aaa5ae2c590cecb1f29d", size = 147822, upload-time = "2026-06-19T15:12:36.131Z" }
97
+ sdist = { url = "https://files.pythonhosted.org/packages/f2/d8/79f4906f4a39aacd7a94c7991af63064cecb95015d4fbe4d50757b21c940/hotdata-0.5.0.tar.gz", hash = "sha256:3d0240e6a3e7333e4290d8b3e75afebba43e518b868e1c3e3818fd719a6ab994", size = 170462, upload-time = "2026-06-28T16:28:49.591Z" }
98
98
  wheels = [
99
- { url = "https://files.pythonhosted.org/packages/47/59/5ff00a1adce5a8b312692a7145660027340d3b4b352b4c3427045a59191f/hotdata-0.4.1-py3-none-any.whl", hash = "sha256:0a71c3d74bae06a79a05eb3f42893baf33f8229ef6f0dc735b59899048a2b7b1", size = 289951, upload-time = "2026-06-19T15:12:34.752Z" },
99
+ { url = "https://files.pythonhosted.org/packages/aa/0e/026a2e03647e3d3c26027b690ea24ef036fbeb314b85517db3d606aab4da/hotdata-0.5.0-py3-none-any.whl", hash = "sha256:e7c4f5f8af6a7b370810fb599e5a166fc4bb569f6f41c506698c4bebfb500fcc", size = 286907, upload-time = "2026-06-28T16:28:48.298Z" },
100
100
  ]
101
101
 
102
102
  [[package]]
103
103
  name = "hotdata-framework"
104
- version = "0.4.1"
104
+ version = "0.6.0"
105
105
  source = { editable = "." }
106
106
  dependencies = [
107
107
  { name = "hotdata" },
@@ -120,7 +120,7 @@ dev = [
120
120
 
121
121
  [package.metadata]
122
122
  requires-dist = [
123
- { name = "hotdata", specifier = ">=0.4.1" },
123
+ { name = "hotdata", specifier = ">=0.5.0" },
124
124
  { name = "pandas", specifier = ">=2.0" },
125
125
  { name = "pyarrow", specifier = ">=14.0" },
126
126
  ]